OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [hfs/] [part_tbl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/fs/hfs/part_tbl.c
3
 *
4
 * Copyright (C) 1996-1997  Paul H. Hargrove
5
 * This file may be distributed under the terms of the GNU General Public License.
6
 *
7
 * Original code to handle the new style Mac partition table based on
8
 * a patch contributed by Holger Schemel (aeglos@valinor.owl.de).
9
 *
10
 * "XXX" in a comment is a note to myself to consider changing something.
11
 *
12
 * In function preconditions the term "valid" applied to a pointer to
13
 * a structure means that the pointer is non-NULL and the structure it
14
 * points to has all fields initialized to consistent values.
15
 *
16
 * The code in this file initializes some structures which contain
17
 * pointers by calling memset(&foo, 0, sizeof(foo)).
18
 * This produces the desired behavior only due to the non-ANSI
19
 * assumption that the machine representation of NULL is all zeros.
20
 */
21
 
22
#include "hfs.h"
23
 
24
/*================ File-local data types ================*/
25
 
26
/*
27
 * The Macintosh Driver Descriptor Block
28
 *
29
 * On partitioned Macintosh media this is block 0.
30
 * We really only need the "magic number" to check for partitioned media.
31
 */
32
struct hfs_drvr_desc {
33
        hfs_word_t      ddSig;          /* The signature word */
34
        /* a bunch more stuff we don't need */
35
};
36
 
37
/*
38
 * The new style Mac partition map
39
 *
40
 * For each partition on the media there is a physical block (512-byte
41
 * block) containing one of these structures.  These blocks are
42
 * contiguous starting at block 1.
43
 */
44
struct new_pmap {
45
        hfs_word_t      pmSig;          /* Signature bytes to verify
46
                                           that this is a partition
47
                                           map block */
48
        hfs_word_t      reSigPad;       /* padding */
49
        hfs_lword_t     pmMapBlkCnt;    /* (At least in block 1) this
50
                                           is the number of partition
51
                                           map blocks */
52
        hfs_lword_t     pmPyPartStart;  /* The physical block number
53
                                           of the first block in this
54
                                           partition */
55
        hfs_lword_t     pmPartBlkCnt;   /* The number of physical
56
                                           blocks in this partition */
57
        hfs_byte_t      pmPartName[32]; /* (null terminated?) string
58
                                           giving the name of this
59
                                           partition */
60
        hfs_byte_t      pmPartType[32]; /* (null terminated?) string
61
                                           giving the type of this
62
                                           partition */
63
        /* a bunch more stuff we don't need */
64
};
65
 
66
/*
67
 * The old style Mac partition map
68
 *
69
 * The partition map consists for a 2-byte signature followed by an
70
 * array of these structures.  The map is terminated with an all-zero
71
 * one of these.
72
 */
73
struct old_pmap {
74
        hfs_word_t              pdSig;  /* Signature bytes */
75
        struct  old_pmap_entry {
76
                hfs_lword_t     pdStart;
77
                hfs_lword_t     pdSize;
78
                hfs_lword_t     pdFSID;
79
        }       pdEntry[42];
80
} __attribute__((packed));
81
 
82
/*================ File-local functions ================*/
83
 
84
/*
85
 * parse_new_part_table()
86
 *
87
 * Parse a new style partition map looking for the
88
 * start and length of the 'part'th HFS partition.
89
 */
90
static int parse_new_part_table(hfs_sysmdb sys_mdb, hfs_buffer buf,
91
                                int part, hfs_s32 *size, hfs_s32 *start)
92
{
93
        struct new_pmap *pm = (struct new_pmap *)hfs_buffer_data(buf);
94
        hfs_u32 pmap_entries = hfs_get_hl(pm->pmMapBlkCnt);
95
        int hfs_part = 0;
96
        int entry;
97
 
98
        for (entry = 0; (entry < pmap_entries) && !(*start); ++entry) {
99
                if (entry) {
100
                        /* read the next partition map entry */
101
                        buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK + entry, 1);
102
                        if (!hfs_buffer_ok(buf)) {
103
                                hfs_warn("hfs_fs: unable to "
104
                                         "read partition map.\n");
105
                                goto bail;
106
                        }
107
                        pm = (struct new_pmap *)hfs_buffer_data(buf);
108
                        if (hfs_get_ns(pm->pmSig) !=
109
                                                htons(HFS_NEW_PMAP_MAGIC)) {
110
                                hfs_warn("hfs_fs: invalid "
111
                                         "entry in partition map\n");
112
                                hfs_buffer_put(buf);
113
                                goto bail;
114
                        }
115
                }
116
 
117
                /* look for an HFS partition */
118
                if (!memcmp(pm->pmPartType,"Apple_HFS",9) &&
119
                    ((hfs_part++) == part)) {
120
                        /* Found it! */
121
                        *start = hfs_get_hl(pm->pmPyPartStart);
122
                        *size = hfs_get_hl(pm->pmPartBlkCnt);
123
                }
124
 
125
                hfs_buffer_put(buf);
126
        }
127
 
128
        return 0;
129
 
130
bail:
131
        return 1;
132
}
133
 
134
/*
135
 * parse_old_part_table()
136
 *
137
 * Parse a old style partition map looking for the
138
 * start and length of the 'part'th HFS partition.
139
 */
140
static int parse_old_part_table(hfs_sysmdb sys_mdb, hfs_buffer buf,
141
                                int part, hfs_s32 *size, hfs_s32 *start)
142
{
143
        struct old_pmap *pm = (struct old_pmap *)hfs_buffer_data(buf);
144
        struct old_pmap_entry *p = &pm->pdEntry[0];
145
        int hfs_part = 0;
146
 
147
        while ((p->pdStart || p->pdSize || p->pdFSID) && !(*start)) {
148
                /* look for an HFS partition */
149
                if ((hfs_get_nl(p->pdFSID) == htonl(0x54465331)/*"TFS1"*/) &&
150
                    ((hfs_part++) == part)) {
151
                        /* Found it! */
152
                        *start = hfs_get_hl(p->pdStart);
153
                        *size = hfs_get_hl(p->pdSize);
154
                }
155
                ++p;
156
        }
157
        hfs_buffer_put(buf);
158
 
159
        return 0;
160
}
161
 
162
/*================ Global functions ================*/
163
 
164
/*
165
 * hfs_part_find()
166
 *
167
 * Parse the partition map looking for the
168
 * start and length of the 'part'th HFS partition.
169
 */
170
int hfs_part_find(hfs_sysmdb sys_mdb, int part, int silent,
171
                  hfs_s32 *size, hfs_s32 *start)
172
{
173
        hfs_buffer buf;
174
        hfs_u16 sig;
175
        int dd_found = 0;
176
        int retval = 1;
177
 
178
        /* Read block 0 to see if this media is partitioned */
179
        buf = hfs_buffer_get(sys_mdb, HFS_DD_BLK, 1);
180
        if (!hfs_buffer_ok(buf)) {
181
                hfs_warn("hfs_fs: Unable to read block 0.\n");
182
                goto done;
183
        }
184
        sig = hfs_get_ns(((struct hfs_drvr_desc *)hfs_buffer_data(buf))->ddSig);
185
        hfs_buffer_put(buf);
186
 
187
        if (sig == htons(HFS_DRVR_DESC_MAGIC)) {
188
                /* We are definitely on partitioned media. */
189
                dd_found = 1;
190
        }
191
 
192
        buf = hfs_buffer_get(sys_mdb, HFS_PMAP_BLK, 1);
193
        if (!hfs_buffer_ok(buf)) {
194
                hfs_warn("hfs_fs: Unable to read block 1.\n");
195
                goto done;
196
        }
197
 
198
        *size = *start = 0;
199
 
200
        switch (hfs_get_ns(hfs_buffer_data(buf))) {
201
        case __constant_htons(HFS_OLD_PMAP_MAGIC):
202
                retval = parse_old_part_table(sys_mdb, buf, part, size, start);
203
                break;
204
 
205
        case __constant_htons(HFS_NEW_PMAP_MAGIC):
206
                retval = parse_new_part_table(sys_mdb, buf, part, size, start);
207
                break;
208
 
209
        default:
210
                if (dd_found) {
211
                        /* The media claimed to have a partition map */
212
                        if (!silent) {
213
                                hfs_warn("hfs_fs: This disk has an "
214
                                         "unrecognized partition map type.\n");
215
                        }
216
                } else {
217
                        /* Conclude that the media is not partitioned */
218
                        retval = 0;
219
                }
220
                goto done;
221
        }
222
 
223
        if (!retval) {
224
                if (*start == 0) {
225
                        if (part) {
226
                                hfs_warn("hfs_fs: unable to locate "
227
                                         "HFS partition number %d.\n", part);
228
                        } else {
229
                                hfs_warn("hfs_fs: unable to locate any "
230
                                         "HFS partitions.\n");
231
                        }
232
                        retval = 1;
233
                } else if (*size < 0) {
234
                        hfs_warn("hfs_fs: Partition size > 1 Terabyte.\n");
235
                        retval = 1;
236
                } else if (*start < 0) {
237
                        hfs_warn("hfs_fs: Partition begins beyond 1 "
238
                                 "Terabyte.\n");
239
                        retval = 1;
240
                }
241
        }
242
done:
243
        return retval;
244
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.