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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [partitions/] [efi.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/************************************************************
2
 * EFI GUID Partition Table handling
3
 * Per Intel EFI Specification v1.02
4
 * http://developer.intel.com/technology/efi/efi.htm
5
 * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com>
6
 *   Copyright 2000,2001,2002,2004 Dell Inc.
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, write to the Free Software
20
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 *
22
 *
23
 * TODO:
24
 *
25
 * Changelog:
26
 * Mon Nov 09 2004 Matt Domsch <Matt_Domsch@dell.com>
27
 * - test for valid PMBR and valid PGPT before ever reading
28
 *   AGPT, allow override with 'gpt' kernel command line option.
29
 * - check for first/last_usable_lba outside of size of disk
30
 *
31
 * Tue  Mar 26 2002 Matt Domsch <Matt_Domsch@dell.com>
32
 * - Ported to 2.5.7-pre1 and 2.5.7-dj2
33
 * - Applied patch to avoid fault in alternate header handling
34
 * - cleaned up find_valid_gpt
35
 * - On-disk structure and copy in memory is *always* LE now -
36
 *   swab fields as needed
37
 * - remove print_gpt_header()
38
 * - only use first max_p partition entries, to keep the kernel minor number
39
 *   and partition numbers tied.
40
 *
41
 * Mon  Feb 04 2002 Matt Domsch <Matt_Domsch@dell.com>
42
 * - Removed __PRIPTR_PREFIX - not being used
43
 *
44
 * Mon  Jan 14 2002 Matt Domsch <Matt_Domsch@dell.com>
45
 * - Ported to 2.5.2-pre11 + library crc32 patch Linus applied
46
 *
47
 * Thu Dec 6 2001 Matt Domsch <Matt_Domsch@dell.com>
48
 * - Added compare_gpts().
49
 * - moved le_efi_guid_to_cpus() back into this file.  GPT is the only
50
 *   thing that keeps EFI GUIDs on disk.
51
 * - Changed gpt structure names and members to be simpler and more Linux-like.
52
 *
53
 * Wed Oct 17 2001 Matt Domsch <Matt_Domsch@dell.com>
54
 * - Removed CONFIG_DEVFS_VOLUMES_UUID code entirely per Martin Wilck
55
 *
56
 * Wed Oct 10 2001 Matt Domsch <Matt_Domsch@dell.com>
57
 * - Changed function comments to DocBook style per Andreas Dilger suggestion.
58
 *
59
 * Mon Oct 08 2001 Matt Domsch <Matt_Domsch@dell.com>
60
 * - Change read_lba() to use the page cache per Al Viro's work.
61
 * - print u64s properly on all architectures
62
 * - fixed debug_printk(), now Dprintk()
63
 *
64
 * Mon Oct 01 2001 Matt Domsch <Matt_Domsch@dell.com>
65
 * - Style cleanups
66
 * - made most functions static
67
 * - Endianness addition
68
 * - remove test for second alternate header, as it's not per spec,
69
 *   and is unnecessary.  There's now a method to read/write the last
70
 *   sector of an odd-sized disk from user space.  No tools have ever
71
 *   been released which used this code, so it's effectively dead.
72
 * - Per Asit Mallick of Intel, added a test for a valid PMBR.
73
 * - Added kernel command line option 'gpt' to override valid PMBR test.
74
 *
75
 * Wed Jun  6 2001 Martin Wilck <Martin.Wilck@Fujitsu-Siemens.com>
76
 * - added devfs volume UUID support (/dev/volumes/uuids) for
77
 *   mounting file systems by the partition GUID.
78
 *
79
 * Tue Dec  5 2000 Matt Domsch <Matt_Domsch@dell.com>
80
 * - Moved crc32() to linux/lib, added efi_crc32().
81
 *
82
 * Thu Nov 30 2000 Matt Domsch <Matt_Domsch@dell.com>
83
 * - Replaced Intel's CRC32 function with an equivalent
84
 *   non-license-restricted version.
85
 *
86
 * Wed Oct 25 2000 Matt Domsch <Matt_Domsch@dell.com>
87
 * - Fixed the last_lba() call to return the proper last block
88
 *
89
 * Thu Oct 12 2000 Matt Domsch <Matt_Domsch@dell.com>
90
 * - Thanks to Andries Brouwer for his debugging assistance.
91
 * - Code works, detects all the partitions.
92
 *
93
 ************************************************************/
94
#include <linux/crc32.h>
95
#include "check.h"
96
#include "efi.h"
97
 
98
#undef EFI_DEBUG
99
#ifdef EFI_DEBUG
100
#define Dprintk(x...) printk(KERN_DEBUG x)
101
#else
102
#define Dprintk(x...)
103
#endif
104
 
105
/* This allows a kernel command line option 'gpt' to override
106
 * the test for invalid PMBR.  Not __initdata because reloading
107
 * the partition tables happens after init too.
108
 */
109
static int force_gpt;
110
static int __init
111
force_gpt_fn(char *str)
112
{
113
        force_gpt = 1;
114
        return 1;
115
}
116
__setup("gpt", force_gpt_fn);
117
 
118
 
119
/**
120
 * efi_crc32() - EFI version of crc32 function
121
 * @buf: buffer to calculate crc32 of
122
 * @len - length of buf
123
 *
124
 * Description: Returns EFI-style CRC32 value for @buf
125
 *
126
 * This function uses the little endian Ethernet polynomial
127
 * but seeds the function with ~0, and xor's with ~0 at the end.
128
 * Note, the EFI Specification, v1.02, has a reference to
129
 * Dr. Dobbs Journal, May 1994 (actually it's in May 1992).
130
 */
131
static inline u32
132
efi_crc32(const void *buf, unsigned long len)
133
{
134
        return (crc32(~0L, buf, len) ^ ~0L);
135
}
136
 
137
/**
138
 * last_lba(): return number of last logical block of device
139
 * @bdev: block device
140
 *
141
 * Description: Returns last LBA value on success, 0 on error.
142
 * This is stored (by sd and ide-geometry) in
143
 *  the part[0] entry for this disk, and is the number of
144
 *  physical sectors available on the disk.
145
 */
146
static u64
147
last_lba(struct block_device *bdev)
148
{
149
        if (!bdev || !bdev->bd_inode)
150
                return 0;
151
        return (bdev->bd_inode->i_size >> 9) - 1ULL;
152
}
153
 
154
static inline int
155
pmbr_part_valid(struct partition *part)
156
{
157
        if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
158
            le32_to_cpu(part->start_sect) == 1UL)
159
                return 1;
160
        return 0;
161
}
162
 
163
/**
164
 * is_pmbr_valid(): test Protective MBR for validity
165
 * @mbr: pointer to a legacy mbr structure
166
 *
167
 * Description: Returns 1 if PMBR is valid, 0 otherwise.
168
 * Validity depends on two things:
169
 *  1) MSDOS signature is in the last two bytes of the MBR
170
 *  2) One partition of type 0xEE is found
171
 */
172
static int
173
is_pmbr_valid(legacy_mbr *mbr)
174
{
175
        int i;
176
        if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
177
                return 0;
178
        for (i = 0; i < 4; i++)
179
                if (pmbr_part_valid(&mbr->partition_record[i]))
180
                        return 1;
181
        return 0;
182
}
183
 
184
/**
185
 * read_lba(): Read bytes from disk, starting at given LBA
186
 * @bdev
187
 * @lba
188
 * @buffer
189
 * @size_t
190
 *
191
 * Description:  Reads @count bytes from @bdev into @buffer.
192
 * Returns number of bytes read on success, 0 on error.
193
 */
194
static size_t
195
read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
196
{
197
        size_t totalreadcount = 0;
198
 
199
        if (!bdev || !buffer || lba > last_lba(bdev))
200
                return 0;
201
 
202
        while (count) {
203
                int copied = 512;
204
                Sector sect;
205
                unsigned char *data = read_dev_sector(bdev, lba++, &sect);
206
                if (!data)
207
                        break;
208
                if (copied > count)
209
                        copied = count;
210
                memcpy(buffer, data, copied);
211
                put_dev_sector(sect);
212
                buffer += copied;
213
                totalreadcount +=copied;
214
                count -= copied;
215
        }
216
        return totalreadcount;
217
}
218
 
219
/**
220
 * alloc_read_gpt_entries(): reads partition entries from disk
221
 * @bdev
222
 * @gpt - GPT header
223
 *
224
 * Description: Returns ptes on success,  NULL on error.
225
 * Allocates space for PTEs based on information found in @gpt.
226
 * Notes: remember to free pte when you're done!
227
 */
228
static gpt_entry *
229
alloc_read_gpt_entries(struct block_device *bdev, gpt_header *gpt)
230
{
231
        size_t count;
232
        gpt_entry *pte;
233
        if (!bdev || !gpt)
234
                return NULL;
235
 
236
        count = le32_to_cpu(gpt->num_partition_entries) *
237
                le32_to_cpu(gpt->sizeof_partition_entry);
238
        if (!count)
239
                return NULL;
240
        pte = kzalloc(count, GFP_KERNEL);
241
        if (!pte)
242
                return NULL;
243
 
244
        if (read_lba(bdev, le64_to_cpu(gpt->partition_entry_lba),
245
                     (u8 *) pte,
246
                     count) < count) {
247
                kfree(pte);
248
                pte=NULL;
249
                return NULL;
250
        }
251
        return pte;
252
}
253
 
254
/**
255
 * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
256
 * @bdev
257
 * @lba is the Logical Block Address of the partition table
258
 *
259
 * Description: returns GPT header on success, NULL on error.   Allocates
260
 * and fills a GPT header starting at @ from @bdev.
261
 * Note: remember to free gpt when finished with it.
262
 */
263
static gpt_header *
264
alloc_read_gpt_header(struct block_device *bdev, u64 lba)
265
{
266
        gpt_header *gpt;
267
        if (!bdev)
268
                return NULL;
269
 
270
        gpt = kzalloc(sizeof (gpt_header), GFP_KERNEL);
271
        if (!gpt)
272
                return NULL;
273
 
274
        if (read_lba(bdev, lba, (u8 *) gpt,
275
                     sizeof (gpt_header)) < sizeof (gpt_header)) {
276
                kfree(gpt);
277
                gpt=NULL;
278
                return NULL;
279
        }
280
 
281
        return gpt;
282
}
283
 
284
/**
285
 * is_gpt_valid() - tests one GPT header and PTEs for validity
286
 * @bdev
287
 * @lba is the logical block address of the GPT header to test
288
 * @gpt is a GPT header ptr, filled on return.
289
 * @ptes is a PTEs ptr, filled on return.
290
 *
291
 * Description: returns 1 if valid,  0 on error.
292
 * If valid, returns pointers to newly allocated GPT header and PTEs.
293
 */
294
static int
295
is_gpt_valid(struct block_device *bdev, u64 lba,
296
             gpt_header **gpt, gpt_entry **ptes)
297
{
298
        u32 crc, origcrc;
299
        u64 lastlba;
300
 
301
        if (!bdev || !gpt || !ptes)
302
                return 0;
303
        if (!(*gpt = alloc_read_gpt_header(bdev, lba)))
304
                return 0;
305
 
306
        /* Check the GUID Partition Table signature */
307
        if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
308
                Dprintk("GUID Partition Table Header signature is wrong:"
309
                        "%lld != %lld\n",
310
                        (unsigned long long)le64_to_cpu((*gpt)->signature),
311
                        (unsigned long long)GPT_HEADER_SIGNATURE);
312
                goto fail;
313
        }
314
 
315
        /* Check the GUID Partition Table CRC */
316
        origcrc = le32_to_cpu((*gpt)->header_crc32);
317
        (*gpt)->header_crc32 = 0;
318
        crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));
319
 
320
        if (crc != origcrc) {
321
                Dprintk
322
                    ("GUID Partition Table Header CRC is wrong: %x != %x\n",
323
                     crc, origcrc);
324
                goto fail;
325
        }
326
        (*gpt)->header_crc32 = cpu_to_le32(origcrc);
327
 
328
        /* Check that the my_lba entry points to the LBA that contains
329
         * the GUID Partition Table */
330
        if (le64_to_cpu((*gpt)->my_lba) != lba) {
331
                Dprintk("GPT my_lba incorrect: %lld != %lld\n",
332
                        (unsigned long long)le64_to_cpu((*gpt)->my_lba),
333
                        (unsigned long long)lba);
334
                goto fail;
335
        }
336
 
337
        /* Check the first_usable_lba and last_usable_lba are
338
         * within the disk.
339
         */
340
        lastlba = last_lba(bdev);
341
        if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
342
                Dprintk("GPT: first_usable_lba incorrect: %lld > %lld\n",
343
                        (unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
344
                        (unsigned long long)lastlba);
345
                goto fail;
346
        }
347
        if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
348
                Dprintk("GPT: last_usable_lba incorrect: %lld > %lld\n",
349
                        (unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
350
                        (unsigned long long)lastlba);
351
                goto fail;
352
        }
353
 
354
        if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt)))
355
                goto fail;
356
 
357
        /* Check the GUID Partition Entry Array CRC */
358
        crc = efi_crc32((const unsigned char *) (*ptes),
359
                        le32_to_cpu((*gpt)->num_partition_entries) *
360
                        le32_to_cpu((*gpt)->sizeof_partition_entry));
361
 
362
        if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
363
                Dprintk("GUID Partitition Entry Array CRC check failed.\n");
364
                goto fail_ptes;
365
        }
366
 
367
        /* We're done, all's well */
368
        return 1;
369
 
370
 fail_ptes:
371
        kfree(*ptes);
372
        *ptes = NULL;
373
 fail:
374
        kfree(*gpt);
375
        *gpt = NULL;
376
        return 0;
377
}
378
 
379
/**
380
 * is_pte_valid() - tests one PTE for validity
381
 * @pte is the pte to check
382
 * @lastlba is last lba of the disk
383
 *
384
 * Description: returns 1 if valid,  0 on error.
385
 */
386
static inline int
387
is_pte_valid(const gpt_entry *pte, const u64 lastlba)
388
{
389
        if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
390
            le64_to_cpu(pte->starting_lba) > lastlba         ||
391
            le64_to_cpu(pte->ending_lba)   > lastlba)
392
                return 0;
393
        return 1;
394
}
395
 
396
/**
397
 * compare_gpts() - Search disk for valid GPT headers and PTEs
398
 * @pgpt is the primary GPT header
399
 * @agpt is the alternate GPT header
400
 * @lastlba is the last LBA number
401
 * Description: Returns nothing.  Sanity checks pgpt and agpt fields
402
 * and prints warnings on discrepancies.
403
 *
404
 */
405
static void
406
compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
407
{
408
        int error_found = 0;
409
        if (!pgpt || !agpt)
410
                return;
411
        if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) {
412
                printk(KERN_WARNING
413
                       "GPT:Primary header LBA != Alt. header alternate_lba\n");
414
                printk(KERN_WARNING "GPT:%lld != %lld\n",
415
                       (unsigned long long)le64_to_cpu(pgpt->my_lba),
416
                       (unsigned long long)le64_to_cpu(agpt->alternate_lba));
417
                error_found++;
418
        }
419
        if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) {
420
                printk(KERN_WARNING
421
                       "GPT:Primary header alternate_lba != Alt. header my_lba\n");
422
                printk(KERN_WARNING "GPT:%lld != %lld\n",
423
                       (unsigned long long)le64_to_cpu(pgpt->alternate_lba),
424
                       (unsigned long long)le64_to_cpu(agpt->my_lba));
425
                error_found++;
426
        }
427
        if (le64_to_cpu(pgpt->first_usable_lba) !=
428
            le64_to_cpu(agpt->first_usable_lba)) {
429
                printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n");
430
                printk(KERN_WARNING "GPT:%lld != %lld\n",
431
                       (unsigned long long)le64_to_cpu(pgpt->first_usable_lba),
432
                       (unsigned long long)le64_to_cpu(agpt->first_usable_lba));
433
                error_found++;
434
        }
435
        if (le64_to_cpu(pgpt->last_usable_lba) !=
436
            le64_to_cpu(agpt->last_usable_lba)) {
437
                printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n");
438
                printk(KERN_WARNING "GPT:%lld != %lld\n",
439
                       (unsigned long long)le64_to_cpu(pgpt->last_usable_lba),
440
                       (unsigned long long)le64_to_cpu(agpt->last_usable_lba));
441
                error_found++;
442
        }
443
        if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
444
                printk(KERN_WARNING "GPT:disk_guids don't match.\n");
445
                error_found++;
446
        }
447
        if (le32_to_cpu(pgpt->num_partition_entries) !=
448
            le32_to_cpu(agpt->num_partition_entries)) {
449
                printk(KERN_WARNING "GPT:num_partition_entries don't match: "
450
                       "0x%x != 0x%x\n",
451
                       le32_to_cpu(pgpt->num_partition_entries),
452
                       le32_to_cpu(agpt->num_partition_entries));
453
                error_found++;
454
        }
455
        if (le32_to_cpu(pgpt->sizeof_partition_entry) !=
456
            le32_to_cpu(agpt->sizeof_partition_entry)) {
457
                printk(KERN_WARNING
458
                       "GPT:sizeof_partition_entry values don't match: "
459
                       "0x%x != 0x%x\n",
460
                       le32_to_cpu(pgpt->sizeof_partition_entry),
461
                       le32_to_cpu(agpt->sizeof_partition_entry));
462
                error_found++;
463
        }
464
        if (le32_to_cpu(pgpt->partition_entry_array_crc32) !=
465
            le32_to_cpu(agpt->partition_entry_array_crc32)) {
466
                printk(KERN_WARNING
467
                       "GPT:partition_entry_array_crc32 values don't match: "
468
                       "0x%x != 0x%x\n",
469
                       le32_to_cpu(pgpt->partition_entry_array_crc32),
470
                       le32_to_cpu(agpt->partition_entry_array_crc32));
471
                error_found++;
472
        }
473
        if (le64_to_cpu(pgpt->alternate_lba) != lastlba) {
474
                printk(KERN_WARNING
475
                       "GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
476
                printk(KERN_WARNING "GPT:%lld != %lld\n",
477
                        (unsigned long long)le64_to_cpu(pgpt->alternate_lba),
478
                        (unsigned long long)lastlba);
479
                error_found++;
480
        }
481
 
482
        if (le64_to_cpu(agpt->my_lba) != lastlba) {
483
                printk(KERN_WARNING
484
                       "GPT:Alternate GPT header not at the end of the disk.\n");
485
                printk(KERN_WARNING "GPT:%lld != %lld\n",
486
                        (unsigned long long)le64_to_cpu(agpt->my_lba),
487
                        (unsigned long long)lastlba);
488
                error_found++;
489
        }
490
 
491
        if (error_found)
492
                printk(KERN_WARNING
493
                       "GPT: Use GNU Parted to correct GPT errors.\n");
494
        return;
495
}
496
 
497
/**
498
 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
499
 * @bdev
500
 * @gpt is a GPT header ptr, filled on return.
501
 * @ptes is a PTEs ptr, filled on return.
502
 * Description: Returns 1 if valid, 0 on error.
503
 * If valid, returns pointers to newly allocated GPT header and PTEs.
504
 * Validity depends on PMBR being valid (or being overridden by the
505
 * 'gpt' kernel command line option) and finding either the Primary
506
 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
507
 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
508
 * is not checked unless the 'gpt' kernel command line option is passed.
509
 * This protects against devices which misreport their size, and forces
510
 * the user to decide to use the Alternate GPT.
511
 */
512
static int
513
find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
514
{
515
        int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
516
        gpt_header *pgpt = NULL, *agpt = NULL;
517
        gpt_entry *pptes = NULL, *aptes = NULL;
518
        legacy_mbr *legacymbr;
519
        u64 lastlba;
520
        if (!bdev || !gpt || !ptes)
521
                return 0;
522
 
523
        lastlba = last_lba(bdev);
524
        if (!force_gpt) {
525
                /* This will be added to the EFI Spec. per Intel after v1.02. */
526
                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
527
                if (legacymbr) {
528
                        read_lba(bdev, 0, (u8 *) legacymbr,
529
                                 sizeof (*legacymbr));
530
                        good_pmbr = is_pmbr_valid(legacymbr);
531
                        kfree(legacymbr);
532
                }
533
                if (!good_pmbr)
534
                        goto fail;
535
        }
536
 
537
        good_pgpt = is_gpt_valid(bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
538
                                 &pgpt, &pptes);
539
        if (good_pgpt)
540
                good_agpt = is_gpt_valid(bdev,
541
                                         le64_to_cpu(pgpt->alternate_lba),
542
                                         &agpt, &aptes);
543
        if (!good_agpt && force_gpt)
544
                good_agpt = is_gpt_valid(bdev, lastlba,
545
                                         &agpt, &aptes);
546
 
547
        /* The obviously unsuccessful case */
548
        if (!good_pgpt && !good_agpt)
549
                goto fail;
550
 
551
        compare_gpts(pgpt, agpt, lastlba);
552
 
553
        /* The good cases */
554
        if (good_pgpt) {
555
                *gpt  = pgpt;
556
                *ptes = pptes;
557
                kfree(agpt);
558
                kfree(aptes);
559
                if (!good_agpt) {
560
                        printk(KERN_WARNING
561
                               "Alternate GPT is invalid, "
562
                               "using primary GPT.\n");
563
                }
564
                return 1;
565
        }
566
        else if (good_agpt) {
567
                *gpt  = agpt;
568
                *ptes = aptes;
569
                kfree(pgpt);
570
                kfree(pptes);
571
                printk(KERN_WARNING
572
                       "Primary GPT is invalid, using alternate GPT.\n");
573
                return 1;
574
        }
575
 
576
 fail:
577
        kfree(pgpt);
578
        kfree(agpt);
579
        kfree(pptes);
580
        kfree(aptes);
581
        *gpt = NULL;
582
        *ptes = NULL;
583
        return 0;
584
}
585
 
586
/**
587
 * efi_partition(struct parsed_partitions *state, struct block_device *bdev)
588
 * @state
589
 * @bdev
590
 *
591
 * Description: called from check.c, if the disk contains GPT
592
 * partitions, sets up partition entries in the kernel.
593
 *
594
 * If the first block on the disk is a legacy MBR,
595
 * it will get handled by msdos_partition().
596
 * If it's a Protective MBR, we'll handle it here.
597
 *
598
 * We do not create a Linux partition for GPT, but
599
 * only for the actual data partitions.
600
 * Returns:
601
 * -1 if unable to read the partition table
602
 *  0 if this isn't our partition table
603
 *  1 if successful
604
 *
605
 */
606
int
607
efi_partition(struct parsed_partitions *state, struct block_device *bdev)
608
{
609
        gpt_header *gpt = NULL;
610
        gpt_entry *ptes = NULL;
611
        u32 i;
612
 
613
        if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
614
                kfree(gpt);
615
                kfree(ptes);
616
                return 0;
617
        }
618
 
619
        Dprintk("GUID Partition Table is valid!  Yea!\n");
620
 
621
        for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
622
                if (!is_pte_valid(&ptes[i], last_lba(bdev)))
623
                        continue;
624
 
625
                put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba),
626
                                 (le64_to_cpu(ptes[i].ending_lba) -
627
                                  le64_to_cpu(ptes[i].starting_lba) +
628
                                  1ULL));
629
 
630
                /* If this is a RAID volume, tell md */
631
                if (!efi_guidcmp(ptes[i].partition_type_guid,
632
                                 PARTITION_LINUX_RAID_GUID))
633
                        state->parts[i+1].flags = 1;
634
        }
635
        kfree(ptes);
636
        kfree(gpt);
637
        printk("\n");
638
        return 1;
639
}

powered by: WebSVN 2.1.0

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