1/************************************************************
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 */
109static int force_gpt;
110static int __init
111force_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 */
131static inline u32
132efi_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 */
146static u64
147last_lba(struct block_device *bdev)
148{
149	if (!bdev || !bdev->bd_inode)
150		return 0;
151
152	/* Foxconn modified start pling 09/10/2012 */
153	/* GPT-4096 sector size fix */
154	//common disk use 512 sector size
155	//but the large volume disk may use 4096 sector size
156	int n = bdev_hardsect_size(bdev);
157	if(4096==n)
158	{
159		return (bdev->bd_inode->i_size >> 12) - 1ULL;
160	}
161	else
162		return (bdev->bd_inode->i_size >> 9) - 1ULL;
163	/* Foxconn modified end pling 09/10/2012 */
164}
165
166static inline int
167/* Foxconn modified start pling 09/10/2012 */
168/* GPT-4096 sector size fix */
169/* pmbr_part_valid(struct partition *part) */
170pmbr_part_valid(struct partition *part, u64 lastlba)
171/* Foxconn modified end pling 09/10/2012 */
172{
173        if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
174            le32_to_cpu(part->start_sect) == 1UL)
175                return 1;
176        return 0;
177}
178
179/**
180 * is_pmbr_valid(): test Protective MBR for validity
181 * @mbr: pointer to a legacy mbr structure
182 * @lastlba: last_lba for the whole device
183 *
184 * Description: Returns 1 if PMBR is valid, 0 otherwise.
185 * Validity depends on two things:
186 *  1) MSDOS signature is in the last two bytes of the MBR
187 *  2) One partition of type 0xEE is found
188 */
189static int
190/* Foxconn modified start pling 09/10/2012 */
191/* GPT-4096 sector size fix */
192/* is_pmbr_valid(legacy_mbr *mbr) */
193is_pmbr_valid(legacy_mbr *mbr, u64 lastlba)
194/* Foxconn modified end pling 09/10/2012 */
195{
196	int i;
197	if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
198                return 0;
199	for (i = 0; i < 4; i++)
200		/* Foxconn modified start pling 09/10/2012 */
201		/* GPT-4096 sector size fix */
202		/* if (pmbr_part_valid(&mbr->partition_record[i])) */
203		if (pmbr_part_valid(&mbr->partition_record[i], lastlba))
204		/* Foxconn modified end pling 09/10/2012 */
205                        return 1;
206	return 0;
207}
208
209/**
210 * read_lba(): Read bytes from disk, starting at given LBA
211 * @bdev
212 * @lba
213 * @buffer
214 * @size_t
215 *
216 * Description:  Reads @count bytes from @bdev into @buffer.
217 * Returns number of bytes read on success, 0 on error.
218 */
219static size_t
220read_lba(struct block_device *bdev, u64 lba, u8 * buffer, size_t count)
221{
222	size_t totalreadcount = 0;
223
224	/* Foxconn added start pling 09/10/2012 */
225	/* GPT-4096 sector size fix */
226	sector_t n = lba * (bdev_hardsect_size(bdev) / 512);
227	/* Foxconn added end pling 09/10/2012 */
228
229	if (!bdev || !buffer || lba > last_lba(bdev))
230                return 0;
231
232	while (count) {
233		int copied = 512;
234		Sector sect;
235		/* Foxconn modified start pling 09/10/2012 */
236		/* GPT-4096 sector size fix */
237		/* unsigned char *data = read_dev_sector(bdev, lba++, &sect); */
238		unsigned char *data = read_dev_sector(bdev, n++, &sect);
239		/* Foxconn modified end pling 09/10/2012 */
240		if (!data)
241			break;
242		if (copied > count)
243			copied = count;
244		memcpy(buffer, data, copied);
245		put_dev_sector(sect);
246		buffer += copied;
247		totalreadcount +=copied;
248		count -= copied;
249	}
250	return totalreadcount;
251}
252
253/**
254 * alloc_read_gpt_entries(): reads partition entries from disk
255 * @bdev
256 * @gpt - GPT header
257 *
258 * Description: Returns ptes on success,  NULL on error.
259 * Allocates space for PTEs based on information found in @gpt.
260 * Notes: remember to free pte when you're done!
261 */
262static gpt_entry *
263alloc_read_gpt_entries(struct block_device *bdev, gpt_header *gpt)
264{
265	size_t count;
266	gpt_entry *pte;
267	if (!bdev || !gpt)
268		return NULL;
269
270	count = le32_to_cpu(gpt->num_partition_entries) *
271                le32_to_cpu(gpt->sizeof_partition_entry);
272	if (!count)
273		return NULL;
274	pte = kzalloc(count, GFP_KERNEL);
275	if (!pte)
276		return NULL;
277
278	if (read_lba(bdev, le64_to_cpu(gpt->partition_entry_lba),
279                     (u8 *) pte,
280		     count) < count) {
281		kfree(pte);
282                pte=NULL;
283		return NULL;
284	}
285	return pte;
286}
287
288/**
289 * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
290 * @bdev
291 * @lba is the Logical Block Address of the partition table
292 *
293 * Description: returns GPT header on success, NULL on error.   Allocates
294 * and fills a GPT header starting at @ from @bdev.
295 * Note: remember to free gpt when finished with it.
296 */
297static gpt_header *
298alloc_read_gpt_header(struct block_device *bdev, u64 lba)
299{
300	gpt_header *gpt;
301
302	/* Foxconn added start pling 09/10/2012 */
303	/* GPT-4096 sector size fix */
304	unsigned ssz = bdev_hardsect_size(bdev);
305	/* Foxconn added end pling 09/10/2012 */
306
307	if (!bdev)
308		return NULL;
309
310	/* Foxconn modified start pling 09/10/2012 */
311	/* GPT-4096 sector size fix */
312	/* gpt = kzalloc(sizeof (gpt_header), GFP_KERNEL); */
313	gpt = kzalloc(ssz, GFP_KERNEL);
314	/* Foxconn modified end pling 09/10/2012 */
315
316	if (!gpt)
317		return NULL;
318
319	if (read_lba(bdev, lba, (u8 *) gpt,
320			/* Foxconn modified start pling 09/10/2012 */
321			/* GPT-4096 sector size fix */
322			/* sizeof (gpt_header)) < sizeof (gpt_header)) { */
323		     ssz) < ssz) {
324			/* Foxconn modified end pling 09/10/2012 */
325		kfree(gpt);
326                gpt=NULL;
327		return NULL;
328	}
329
330	return gpt;
331}
332
333/**
334 * is_gpt_valid() - tests one GPT header and PTEs for validity
335 * @bdev
336 * @lba is the logical block address of the GPT header to test
337 * @gpt is a GPT header ptr, filled on return.
338 * @ptes is a PTEs ptr, filled on return.
339 *
340 * Description: returns 1 if valid,  0 on error.
341 * If valid, returns pointers to newly allocated GPT header and PTEs.
342 */
343static int
344is_gpt_valid(struct block_device *bdev, u64 lba,
345	     gpt_header **gpt, gpt_entry **ptes)
346{
347	u32 crc, origcrc;
348	u64 lastlba;
349
350	if (!bdev || !gpt || !ptes)
351		return 0;
352	if (!(*gpt = alloc_read_gpt_header(bdev, lba)))
353		return 0;
354
355	/* Check the GUID Partition Table signature */
356	if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
357		Dprintk("GUID Partition Table Header signature is wrong:"
358			"%lld != %lld\n",
359			(unsigned long long)le64_to_cpu((*gpt)->signature),
360			(unsigned long long)GPT_HEADER_SIGNATURE);
361		goto fail;
362	}
363
364	/* Check the GUID Partition Table CRC */
365	origcrc = le32_to_cpu((*gpt)->header_crc32);
366	(*gpt)->header_crc32 = 0;
367	crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));
368
369	if (crc != origcrc) {
370		Dprintk
371		    ("GUID Partition Table Header CRC is wrong: %x != %x\n",
372		     crc, origcrc);
373		goto fail;
374	}
375	(*gpt)->header_crc32 = cpu_to_le32(origcrc);
376
377	/* Check that the my_lba entry points to the LBA that contains
378	 * the GUID Partition Table */
379	if (le64_to_cpu((*gpt)->my_lba) != lba) {
380		Dprintk("GPT my_lba incorrect: %lld != %lld\n",
381			(unsigned long long)le64_to_cpu((*gpt)->my_lba),
382			(unsigned long long)lba);
383		goto fail;
384	}
385
386	/* Check the first_usable_lba and last_usable_lba are
387	 * within the disk.
388	 */
389	lastlba = last_lba(bdev);
390	if (le64_to_cpu((*gpt)->first_usable_lba) > lastlba) {
391		Dprintk("GPT: first_usable_lba incorrect: %lld > %lld\n",
392			(unsigned long long)le64_to_cpu((*gpt)->first_usable_lba),
393			(unsigned long long)lastlba);
394		goto fail;
395	}
396	if (le64_to_cpu((*gpt)->last_usable_lba) > lastlba) {
397		Dprintk("GPT: last_usable_lba incorrect: %lld > %lld\n",
398			(unsigned long long)le64_to_cpu((*gpt)->last_usable_lba),
399			(unsigned long long)lastlba);
400		goto fail;
401	}
402
403	if (!(*ptes = alloc_read_gpt_entries(bdev, *gpt)))
404		goto fail;
405
406	/* Check the GUID Partition Entry Array CRC */
407	crc = efi_crc32((const unsigned char *) (*ptes),
408			le32_to_cpu((*gpt)->num_partition_entries) *
409			le32_to_cpu((*gpt)->sizeof_partition_entry));
410
411	if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
412		Dprintk("GUID Partitition Entry Array CRC check failed.\n");
413		goto fail_ptes;
414	}
415
416	/* We're done, all's well */
417	return 1;
418
419 fail_ptes:
420	kfree(*ptes);
421	*ptes = NULL;
422 fail:
423	kfree(*gpt);
424	*gpt = NULL;
425	return 0;
426}
427
428/**
429 * is_pte_valid() - tests one PTE for validity
430 * @pte is the pte to check
431 * @lastlba is last lba of the disk
432 *
433 * Description: returns 1 if valid,  0 on error.
434 */
435static inline int
436is_pte_valid(const gpt_entry *pte, const u64 lastlba)
437{
438	if ((!efi_guidcmp(pte->partition_type_guid, NULL_GUID)) ||
439	    le64_to_cpu(pte->starting_lba) > lastlba         ||
440	    le64_to_cpu(pte->ending_lba)   > lastlba)
441		return 0;
442	return 1;
443}
444
445/**
446 * compare_gpts() - Search disk for valid GPT headers and PTEs
447 * @pgpt is the primary GPT header
448 * @agpt is the alternate GPT header
449 * @lastlba is the last LBA number
450 * Description: Returns nothing.  Sanity checks pgpt and agpt fields
451 * and prints warnings on discrepancies.
452 *
453 */
454static void
455compare_gpts(gpt_header *pgpt, gpt_header *agpt, u64 lastlba)
456{
457	int error_found = 0;
458	if (!pgpt || !agpt)
459		return;
460	if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) {
461		printk(KERN_WARNING
462		       "GPT:Primary header LBA != Alt. header alternate_lba\n");
463		printk(KERN_WARNING "GPT:%lld != %lld\n",
464		       (unsigned long long)le64_to_cpu(pgpt->my_lba),
465                       (unsigned long long)le64_to_cpu(agpt->alternate_lba));
466		error_found++;
467	}
468	if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) {
469		printk(KERN_WARNING
470		       "GPT:Primary header alternate_lba != Alt. header my_lba\n");
471		printk(KERN_WARNING "GPT:%lld != %lld\n",
472		       (unsigned long long)le64_to_cpu(pgpt->alternate_lba),
473                       (unsigned long long)le64_to_cpu(agpt->my_lba));
474		error_found++;
475	}
476	if (le64_to_cpu(pgpt->first_usable_lba) !=
477            le64_to_cpu(agpt->first_usable_lba)) {
478		printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n");
479		printk(KERN_WARNING "GPT:%lld != %lld\n",
480		       (unsigned long long)le64_to_cpu(pgpt->first_usable_lba),
481                       (unsigned long long)le64_to_cpu(agpt->first_usable_lba));
482		error_found++;
483	}
484	if (le64_to_cpu(pgpt->last_usable_lba) !=
485            le64_to_cpu(agpt->last_usable_lba)) {
486		printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n");
487		printk(KERN_WARNING "GPT:%lld != %lld\n",
488		       (unsigned long long)le64_to_cpu(pgpt->last_usable_lba),
489                       (unsigned long long)le64_to_cpu(agpt->last_usable_lba));
490		error_found++;
491	}
492	if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
493		printk(KERN_WARNING "GPT:disk_guids don't match.\n");
494		error_found++;
495	}
496	if (le32_to_cpu(pgpt->num_partition_entries) !=
497            le32_to_cpu(agpt->num_partition_entries)) {
498		printk(KERN_WARNING "GPT:num_partition_entries don't match: "
499		       "0x%x != 0x%x\n",
500		       le32_to_cpu(pgpt->num_partition_entries),
501		       le32_to_cpu(agpt->num_partition_entries));
502		error_found++;
503	}
504	if (le32_to_cpu(pgpt->sizeof_partition_entry) !=
505            le32_to_cpu(agpt->sizeof_partition_entry)) {
506		printk(KERN_WARNING
507		       "GPT:sizeof_partition_entry values don't match: "
508		       "0x%x != 0x%x\n",
509                       le32_to_cpu(pgpt->sizeof_partition_entry),
510		       le32_to_cpu(agpt->sizeof_partition_entry));
511		error_found++;
512	}
513	if (le32_to_cpu(pgpt->partition_entry_array_crc32) !=
514            le32_to_cpu(agpt->partition_entry_array_crc32)) {
515		printk(KERN_WARNING
516		       "GPT:partition_entry_array_crc32 values don't match: "
517		       "0x%x != 0x%x\n",
518                       le32_to_cpu(pgpt->partition_entry_array_crc32),
519		       le32_to_cpu(agpt->partition_entry_array_crc32));
520		error_found++;
521	}
522	if (le64_to_cpu(pgpt->alternate_lba) != lastlba) {
523		printk(KERN_WARNING
524		       "GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
525		printk(KERN_WARNING "GPT:%lld != %lld\n",
526			(unsigned long long)le64_to_cpu(pgpt->alternate_lba),
527			(unsigned long long)lastlba);
528		error_found++;
529	}
530
531	if (le64_to_cpu(agpt->my_lba) != lastlba) {
532		printk(KERN_WARNING
533		       "GPT:Alternate GPT header not at the end of the disk.\n");
534		printk(KERN_WARNING "GPT:%lld != %lld\n",
535			(unsigned long long)le64_to_cpu(agpt->my_lba),
536			(unsigned long long)lastlba);
537		error_found++;
538	}
539
540	if (error_found)
541		printk(KERN_WARNING
542		       "GPT: Use GNU Parted to correct GPT errors.\n");
543	return;
544}
545
546/**
547 * find_valid_gpt() - Search disk for valid GPT headers and PTEs
548 * @bdev
549 * @gpt is a GPT header ptr, filled on return.
550 * @ptes is a PTEs ptr, filled on return.
551 * Description: Returns 1 if valid, 0 on error.
552 * If valid, returns pointers to newly allocated GPT header and PTEs.
553 * Validity depends on PMBR being valid (or being overridden by the
554 * 'gpt' kernel command line option) and finding either the Primary
555 * GPT header and PTEs valid, or the Alternate GPT header and PTEs
556 * valid.  If the Primary GPT header is not valid, the Alternate GPT header
557 * is not checked unless the 'gpt' kernel command line option is passed.
558 * This protects against devices which misreport their size, and forces
559 * the user to decide to use the Alternate GPT.
560 */
561static int
562find_valid_gpt(struct block_device *bdev, gpt_header **gpt, gpt_entry **ptes)
563{
564	int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
565	gpt_header *pgpt = NULL, *agpt = NULL;
566	gpt_entry *pptes = NULL, *aptes = NULL;
567	/* Foxconn modified start pling 09/10/2012 */
568	/* GPT-4096 sector size fix */
569	legacy_mbr *legacymbr = NULL;
570	/* Foxconn modified end pling 09/10/2012 */
571	u64 lastlba;
572	if (!bdev || !gpt || !ptes)
573		return 0;
574
575	lastlba = last_lba(bdev);
576        if (!force_gpt) {
577                /* This will be added to the EFI Spec. per Intel after v1.02. */
578                legacymbr = kzalloc(sizeof (*legacymbr), GFP_KERNEL);
579                if (legacymbr) {
580                        read_lba(bdev, 0, (u8 *) legacymbr,
581                                 sizeof (*legacymbr));
582                        /* Foxconn modified start pling 09/10/2012 */
583                        /* GPT-4096 sector size fix */
584                        /* good_pmbr = is_pmbr_valid(legacymbr); */
585                        good_pmbr = is_pmbr_valid(legacymbr, lastlba);
586                        /* Foxconn modified end pling 09/10/2012 */
587                        kfree(legacymbr);
588
589                        /* Foxconn added start pling 09/10/2012 */
590                        /* GPT-4096 sector size fix */
591                        legacymbr=NULL;
592                        /* Foxconn added end pling 09/10/2012 */
593                }
594                if (!good_pmbr)
595                        goto fail;
596        }
597
598	good_pgpt = is_gpt_valid(bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
599				 &pgpt, &pptes);
600        if (good_pgpt)
601		good_agpt = is_gpt_valid(bdev,
602					 le64_to_cpu(pgpt->alternate_lba),
603					 &agpt, &aptes);
604        if (!good_agpt && force_gpt)
605                good_agpt = is_gpt_valid(bdev, lastlba,
606                                         &agpt, &aptes);
607
608        /* The obviously unsuccessful case */
609        if (!good_pgpt && !good_agpt)
610                goto fail;
611
612        compare_gpts(pgpt, agpt, lastlba);
613
614        /* The good cases */
615        if (good_pgpt) {
616                *gpt  = pgpt;
617                *ptes = pptes;
618                kfree(agpt);
619                kfree(aptes);
620                if (!good_agpt) {
621                        printk(KERN_WARNING
622			       "Alternate GPT is invalid, "
623                               "using primary GPT.\n");
624                }
625                return 1;
626        }
627        else if (good_agpt) {
628                *gpt  = agpt;
629                *ptes = aptes;
630                kfree(pgpt);
631                kfree(pptes);
632                printk(KERN_WARNING
633                       "Primary GPT is invalid, using alternate GPT.\n");
634                return 1;
635        }
636
637 fail:
638        kfree(pgpt);
639        kfree(agpt);
640        kfree(pptes);
641        kfree(aptes);
642        *gpt = NULL;
643        *ptes = NULL;
644        return 0;
645}
646
647/**
648 * efi_partition(struct parsed_partitions *state, struct block_device *bdev)
649 * @state
650 * @bdev
651 *
652 * Description: called from check.c, if the disk contains GPT
653 * partitions, sets up partition entries in the kernel.
654 *
655 * If the first block on the disk is a legacy MBR,
656 * it will get handled by msdos_partition().
657 * If it's a Protective MBR, we'll handle it here.
658 *
659 * We do not create a Linux partition for GPT, but
660 * only for the actual data partitions.
661 * Returns:
662 * -1 if unable to read the partition table
663 *  0 if this isn't our partition table
664 *  1 if successful
665 *
666 */
667int
668efi_partition(struct parsed_partitions *state, struct block_device *bdev)
669{
670	gpt_header *gpt = NULL;
671	gpt_entry *ptes = NULL;
672	u32 i;
673
674	/* Foxconn added start pling 09/10/2012 */
675	/* GPT-4096 sector size fix */
676	unsigned ssz = bdev_hardsect_size(bdev) / 512;
677	/* Foxconn added end pling 09/10/2012 */
678
679	if (!find_valid_gpt(bdev, &gpt, &ptes) || !gpt || !ptes) {
680		kfree(gpt);
681		kfree(ptes);
682		return 0;
683	}
684
685	Dprintk("GUID Partition Table is valid!  Yea!\n");
686
687	for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < state->limit-1; i++) {
688		if (!is_pte_valid(&ptes[i], last_lba(bdev)))
689			continue;
690
691		/* Foxconn modified start pling 09/10/2012 */
692		/* GPT-4096 sector size fix */
693#if 0
694		put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba),
695				 (le64_to_cpu(ptes[i].ending_lba) -
696                                  le64_to_cpu(ptes[i].starting_lba) +
697				  1ULL));
698#endif
699		put_partition(state, i+1, le64_to_cpu(ptes[i].starting_lba) * ssz,
700				 (le64_to_cpu(ptes[i].ending_lba) -
701                                  le64_to_cpu(ptes[i].starting_lba) +
702				  1ULL) * ssz);
703		/* Foxconn modified end pling 09/10/2012 */
704
705		/* If this is a RAID volume, tell md */
706		if (!efi_guidcmp(ptes[i].partition_type_guid,
707				 PARTITION_LINUX_RAID_GUID))
708			state->parts[i+1].flags = 1;
709	}
710	kfree(ptes);
711	kfree(gpt);
712	printk("\n");
713	return 1;
714}
715