*
* Changelog:
*
+ * 25 Mar 2002 - Matt Domsch <Matt_Domsch@dell.com>
+ * move uuid_unparse() to include/asm-ia64/efi.h:efi_guid_unparse()
+ *
* 12 Feb 2002 - Matt Domsch <Matt_Domsch@dell.com>
* use list_for_each_safe when deleting vars.
* remove ifdef CONFIG_SMP around include <linux/smp.h>
MODULE_DESCRIPTION("/proc interface to EFI Variables");
MODULE_LICENSE("GPL");
-#define EFIVARS_VERSION "0.04 2002-Feb-12"
+#define EFIVARS_VERSION "0.05 2002-Mar-26"
static int
efivar_read(char *page, char **start, off_t off,
return len;
}
-
-static void
-uuid_unparse(efi_guid_t *guid, char *out)
-{
- sprintf(out, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- guid->data1, guid->data2, guid->data3,
- guid->data4[0], guid->data4[1], guid->data4[2], guid->data4[3],
- guid->data4[4], guid->data4[5], guid->data4[6], guid->data4[7]);
-}
-
-
-
-
-
/*
* efivar_create_proc_entry()
* Requires:
private variables from another's. */
*(short_name + strlen(short_name)) = '-';
- uuid_unparse(vendor_guid, short_name + strlen(short_name));
+ efi_guid_unparse(vendor_guid, short_name + strlen(short_name));
/* Create the entry in proc */
* Purpose: Generic MCA handling layer
*
* Updated for latest kernel
+ * Copyright (C) 2002 Dell Computer Corporation
+ * Copyright (C) Matt Domsch (Matt_Domsch@dell.com)
+ *
* Copyright (C) 2002 Intel
* Copyright (C) Jenna Hall (jenna.s.hall@intel.com)
*
* Copyright (C) 1999 Silicon Graphics, Inc.
* Copyright (C) Vijay Chander(vijay@engr.sgi.com)
*
+ * 02/03/25 M. Domsch GUID cleanups
+ *
* 02/01/04 J. Hall Aligned MCA stack to 16 bytes, added platform vs. CPU
* error flag, set SAL default return values, changed
* error record structure to linked list, added init call
verify_guid (efi_guid_t *test, efi_guid_t *target)
{
int rc;
+ char out[40];
- if ((rc = memcmp((void *)test, (void *)target, sizeof(efi_guid_t)))) {
- IA64_MCA_DEBUG("ia64_mca_print: invalid guid = "
- "{ %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
- "%#02x, %#02x, %#02x, %#02x, } } \n ",
- test->data1, test->data2, test->data3, test->data4[0],
- test->data4[1], test->data4[2], test->data4[3],
- test->data4[4], test->data4[5], test->data4[6],
- test->data4[7]);
+ if ((rc = efi_guidcmp(*test, *target))) {
+ IA64_MCA_DEBUG(KERN_DEBUG
+ "verify_guid: invalid GUID = %s\n",
+ efi_guid_unparse(test, out));
}
-
return rc;
}
void
ia64_log_prt_guid (efi_guid_t *p_guid, prfunc_t prfunc)
{
- printk("GUID = { %08x, %04x, %04x, { %#02x, %#02x, %#02x, %#02x, "
- "%#02x, %#02x, %#02x, %#02x, } } \n ", p_guid->data1,
- p_guid->data2, p_guid->data3, p_guid->data4[0], p_guid->data4[1],
- p_guid->data4[2], p_guid->data4[3], p_guid->data4[4],
- p_guid->data4[5], p_guid->data4[6], p_guid->data4[7]);
+ char out[40];
+ printk(KERN_DEBUG "GUID = %s\n", efi_guid_unparse(p_guid, out));
}
static void
ia64_log_prt_section_header(slsh, prfunc);
#endif // MCA_PRT_XTRA_DATA for test only @FVL
- if (verify_guid((void *)&slsh->guid, (void *)&(SAL_PROC_DEV_ERR_SECT_GUID))) {
+ if (verify_guid(&slsh->guid, &(SAL_PROC_DEV_ERR_SECT_GUID))) {
IA64_MCA_DEBUG("ia64_mca_log_print: unsupported record section\n");
continue;
}
* TODO:
*
* Changelog:
+ * Tue Mar 26 2002 Matt Domsch <Matt_Domsch@dell.com>
+ * - Ported to 2.5.7-pre1 and 2.5.7-dj2
+ * - Applied patch to avoid fault in alternate header handling
+ * - cleaned up find_valid_gpt
+ * - On-disk structure and copy in memory is *always* LE now -
+ * swab fields as needed
+ * - remove print_gpt_header()
+ * - only use first max_p partition entries, to keep the kernel minor number
+ * and partition numbers tied.
+ *
+ * Mon Feb 04 2002 Matt Domsch <Matt_Domsch@dell.com>
+ * - Removed __PRIPTR_PREFIX - not being used
+ *
* Mon Jan 14 2002 Matt Domsch <Matt_Domsch@dell.com>
* - Ported to 2.5.2-pre11 + library crc32 patch Linus applied
*
/* Borrowed from /usr/include/inttypes.h */
# if BITS_PER_LONG == 64
# define __PRI64_PREFIX "l"
-# define __PRIPTR_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
-# define __PRIPTR_PREFIX
# endif
# define PRIx64 __PRI64_PREFIX "x"
* the test for invalid PMBR. Not __initdata because reloading
* the partition tables happens after init too.
*/
-static int forcegpt;
+static int force_gpt;
static int __init
-force_gpt(char *str)
+force_gpt_fn(char *str)
{
- forcegpt = 1;
+ force_gpt = 1;
return 1;
}
+__setup("gpt", force_gpt_fn);
-__setup("gpt", force_gpt);
-
-/**
- * le_efi_guid_to_cpus()
- * @guid
- *
- * Description: modifies @guid in situ
- *
- * This function converts a little endian efi_guid_t to the
- * native cpu representation. The EFI Spec. declares that all
- * on-disk structures are stored in little endian format.
- */
-static void
-le_efi_guid_to_cpus(efi_guid_t *guid)
-{
- le32_to_cpus(guid->data1);
- le16_to_cpus(guid->data2);
- le16_to_cpus(guid->data3);
- /* no need to change the rest. It's already an array of chars */
- return;
-}
/**
* efi_crc32() - EFI version of crc32 function
return (crc32(~0L, buf, len) ^ ~0L);
}
-/**
- * le_part_attributes_to_cpus(): converts LE attributes to CPU type in situ
- * @attributes - ptr to partition attributes
- *
- * Description: modifies attributes in situ, returns nothing.
- * Converts a little endian partition attributes struct to the
- * native cpu representation. Good for reading attributes off of a disk.
- */
-static void
-le_part_attributes_to_cpus(gpt_entry_attributes * a)
-{
- u64 *b = (u64 *) a;
- *b = le64_to_cpu(*b);
-}
-
/**
* is_pmbr_valid(): test Protective MBR for validity
* @mbr: pointer to a legacy mbr structure
return 0;
signature = (le16_to_cpu(mbr->signature) == MSDOS_MBR_SIGNATURE);
for (i = 0; signature && i < 4; i++) {
- if (mbr->partition_record[i].sys_ind == EFI_PMBR_OSTYPE_EFI_GPT) {
+ if (mbr->partition_record[i].sys_ind ==
+ EFI_PMBR_OSTYPE_EFI_GPT) {
found = 1;
break;
}
return totalreadcount;
}
-/**
- * print_gpt_header(): unparses gpt header to console
- * @gpt: gpt header
- */
-static void
-print_gpt_header(gpt_header *gpt)
-{
- Dprintk("GUID Partition Table Header\n");
- if (!gpt)
- return;
- Dprintk("signature : %" PRIx64 "\n", gpt->signature);
- Dprintk("revision : %x\n", gpt->revision);
- Dprintk("header_size : %x\n", gpt->header_size);
- Dprintk("header_crc32 : %x\n", gpt->header_crc32);
- Dprintk("my_lba : %" PRIx64 "\n", gpt->my_lba);
- Dprintk("alternate_lba : %" PRIx64 "\n",
- gpt->alternate_lba);
- Dprintk("first_usable_lba : %" PRIx64 "\n",
- gpt->first_usable_lba);
- Dprintk("last_usable_lba : %" PRIx64 "\n",
- gpt->last_usable_lba);
- Dprintk("partition_entry_lba : %" PRIx64 "\n",
- gpt->partition_entry_lba);
- Dprintk("num_partition_entries : %x\n",
- gpt->num_partition_entries);
- Dprintk("sizeof_partition_entry : %x\n",
- gpt->sizeof_partition_entry);
- Dprintk("partition_entry_array_crc32 : %x\n",
- gpt->partition_entry_array_crc32);
- return;
-}
/**
* alloc_read_gpt_entries(): reads partition entries from disk
alloc_read_gpt_entries(struct gendisk *hd,
struct block_device *bdev, gpt_header *gpt)
{
- u32 i, j;
size_t count;
gpt_entry *pte;
if (!hd || !bdev || !gpt)
return NULL;
- count = gpt->num_partition_entries * gpt->sizeof_partition_entry;
+ count = le32_to_cpu(gpt->num_partition_entries) *
+ le32_to_cpu(gpt->sizeof_partition_entry);
if (!count)
return NULL;
pte = kmalloc(count, GFP_KERNEL);
return NULL;
memset(pte, 0, count);
- if (read_lba(hd, bdev, gpt->partition_entry_lba, (u8 *) pte,
+ if (read_lba(hd, bdev, le64_to_cpu(gpt->partition_entry_lba),
+ (u8 *) pte,
count) < count) {
kfree(pte);
+ pte=NULL;
return NULL;
}
- /* Fixup endianness */
- for (i = 0; i < gpt->num_partition_entries; i++) {
- le_efi_guid_to_cpus(&pte[i].partition_type_guid);
- le_efi_guid_to_cpus(&pte[i].unique_partition_guid);
- le64_to_cpus(pte[i].starting_lba);
- le64_to_cpus(pte[i].ending_lba);
- le_part_attributes_to_cpus(&pte[i].attributes);
- for (j = 0; j < (72 / sizeof (efi_char16_t)); j++) {
- le16_to_cpus((u16) (pte[i].partition_name[j]));
- }
- }
-
return pte;
}
if (read_lba(hd, bdev, lba, (u8 *) gpt,
sizeof (gpt_header)) < sizeof (gpt_header)) {
kfree(gpt);
+ gpt=NULL;
return NULL;
}
- /* Fixup endianness */
- le64_to_cpus(gpt->signature);
- le32_to_cpus(gpt->revision);
- le32_to_cpus(gpt->header_size);
- le32_to_cpus(gpt->header_crc32);
- le32_to_cpus(gpt->reserved1);
- le64_to_cpus(gpt->my_lba);
- le64_to_cpus(gpt->alternate_lba);
- le64_to_cpus(gpt->first_usable_lba);
- le64_to_cpus(gpt->last_usable_lba);
- le_efi_guid_to_cpus(&gpt->disk_guid);
- le64_to_cpus(gpt->partition_entry_lba);
- le32_to_cpus(gpt->num_partition_entries);
- le32_to_cpus(gpt->sizeof_partition_entry);
- le32_to_cpus(gpt->partition_entry_array_crc32);
-
- print_gpt_header(gpt);
-
return gpt;
}
return 0;
/* Check the GUID Partition Table signature */
- if ((*gpt)->signature != GPT_HEADER_SIGNATURE) {
+ if (le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE) {
Dprintk("GUID Partition Table Header signature is wrong: %"
- PRIx64 " != %" PRIx64 "\n", (*gpt)->signature,
+ PRIx64 " != %" PRIx64 "\n", le64_to_cpu((*gpt)->signature),
GPT_HEADER_SIGNATURE);
kfree(*gpt);
*gpt = NULL;
}
/* Check the GUID Partition Table CRC */
- origcrc = (*gpt)->header_crc32;
+ origcrc = le32_to_cpu((*gpt)->header_crc32);
(*gpt)->header_crc32 = 0;
- crc = efi_crc32((const unsigned char *) (*gpt), (*gpt)->header_size);
+ crc = efi_crc32((const unsigned char *) (*gpt), le32_to_cpu((*gpt)->header_size));
if (crc != origcrc) {
Dprintk
("GUID Partition Table Header CRC is wrong: %x != %x\n",
- (*gpt)->header_crc32, origcrc);
+ crc, origcrc);
kfree(*gpt);
*gpt = NULL;
return 0;
}
- (*gpt)->header_crc32 = origcrc;
+ (*gpt)->header_crc32 = cpu_to_le32(origcrc);
/* Check that the my_lba entry points to the LBA that contains
* the GUID Partition Table */
- if ((*gpt)->my_lba != lba) {
+ if (le64_to_cpu((*gpt)->my_lba) != lba) {
Dprintk("GPT my_lba incorrect: %" PRIx64 " != %" PRIx64 "\n",
- (*gpt)->my_lba, lba);
+ le64_to_cpu((*gpt)->my_lba), lba);
kfree(*gpt);
*gpt = NULL;
return 0;
/* Check the GUID Partition Entry Array CRC */
crc = efi_crc32((const unsigned char *) (*ptes),
- (*gpt)->num_partition_entries *
- (*gpt)->sizeof_partition_entry);
+ le32_to_cpu((*gpt)->num_partition_entries) *
+ le32_to_cpu((*gpt)->sizeof_partition_entry));
- if (crc != (*gpt)->partition_entry_array_crc32) {
+ if (crc != le32_to_cpu((*gpt)->partition_entry_array_crc32)) {
Dprintk("GUID Partitition Entry Array CRC check failed.\n");
kfree(*gpt);
*gpt = NULL;
int error_found = 0;
if (!pgpt || !agpt)
return;
- if (pgpt->my_lba != agpt->alternate_lba) {
+ if (le64_to_cpu(pgpt->my_lba) != le64_to_cpu(agpt->alternate_lba)) {
printk(KERN_WARNING
"GPT:Primary header LBA != Alt. header alternate_lba\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- pgpt->my_lba, agpt->alternate_lba);
+ le64_to_cpu(pgpt->my_lba),
+ le64_to_cpu(agpt->alternate_lba));
error_found++;
}
- if (pgpt->alternate_lba != agpt->my_lba) {
+ if (le64_to_cpu(pgpt->alternate_lba) != le64_to_cpu(agpt->my_lba)) {
printk(KERN_WARNING
"GPT:Primary header alternate_lba != Alt. header my_lba\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- pgpt->alternate_lba, agpt->my_lba);
+ le64_to_cpu(pgpt->alternate_lba),
+ le64_to_cpu(agpt->my_lba));
error_found++;
}
- if (pgpt->first_usable_lba != agpt->first_usable_lba) {
+ if (le64_to_cpu(pgpt->first_usable_lba) !=
+ le64_to_cpu(agpt->first_usable_lba)) {
printk(KERN_WARNING "GPT:first_usable_lbas don't match.\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- pgpt->first_usable_lba, agpt->first_usable_lba);
+ le64_to_cpu(pgpt->first_usable_lba),
+ le64_to_cpu(agpt->first_usable_lba));
error_found++;
}
- if (pgpt->last_usable_lba != agpt->last_usable_lba) {
+ if (le64_to_cpu(pgpt->last_usable_lba) !=
+ le64_to_cpu(agpt->last_usable_lba)) {
printk(KERN_WARNING "GPT:last_usable_lbas don't match.\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- pgpt->last_usable_lba, agpt->last_usable_lba);
+ le64_to_cpu(pgpt->last_usable_lba),
+ le64_to_cpu(agpt->last_usable_lba));
error_found++;
}
if (efi_guidcmp(pgpt->disk_guid, agpt->disk_guid)) {
printk(KERN_WARNING "GPT:disk_guids don't match.\n");
error_found++;
}
- if (pgpt->num_partition_entries != agpt->num_partition_entries) {
+ if (le32_to_cpu(pgpt->num_partition_entries) !=
+ le32_to_cpu(agpt->num_partition_entries)) {
printk(KERN_WARNING "GPT:num_partition_entries don't match: "
"0x%x != 0x%x\n",
- pgpt->num_partition_entries,
- agpt->num_partition_entries);
+ le32_to_cpu(pgpt->num_partition_entries),
+ le32_to_cpu(agpt->num_partition_entries));
error_found++;
}
- if (pgpt->sizeof_partition_entry != agpt->sizeof_partition_entry) {
+ if (le32_to_cpu(pgpt->sizeof_partition_entry) !=
+ le32_to_cpu(agpt->sizeof_partition_entry)) {
printk(KERN_WARNING
"GPT:sizeof_partition_entry values don't match: "
- "0x%x != 0x%x\n", pgpt->sizeof_partition_entry,
- agpt->sizeof_partition_entry);
+ "0x%x != 0x%x\n",
+ le32_to_cpu(pgpt->sizeof_partition_entry),
+ le32_to_cpu(agpt->sizeof_partition_entry));
error_found++;
}
- if (pgpt->partition_entry_array_crc32 !=
- agpt->partition_entry_array_crc32) {
+ if (le32_to_cpu(pgpt->partition_entry_array_crc32) !=
+ le32_to_cpu(agpt->partition_entry_array_crc32)) {
printk(KERN_WARNING
"GPT:partition_entry_array_crc32 values don't match: "
- "0x%x != 0x%x\n", pgpt->partition_entry_array_crc32,
- agpt->partition_entry_array_crc32);
+ "0x%x != 0x%x\n",
+ le32_to_cpu(pgpt->partition_entry_array_crc32),
+ le32_to_cpu(agpt->partition_entry_array_crc32));
error_found++;
}
- if (pgpt->alternate_lba != lastlba) {
+ if (le64_to_cpu(pgpt->alternate_lba) != lastlba) {
printk(KERN_WARNING
"GPT:Primary header thinks Alt. header is not at the end of the disk.\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- pgpt->alternate_lba, lastlba);
+ le64_to_cpu(pgpt->alternate_lba), lastlba);
error_found++;
}
- if (agpt->my_lba != lastlba) {
+ if (le64_to_cpu(agpt->my_lba) != lastlba) {
printk(KERN_WARNING
"GPT:Alternate GPT header not at the end of the disk.\n");
printk(KERN_WARNING "GPT:%" PRIx64 " != %" PRIx64 "\n",
- agpt->my_lba, lastlba);
+ le64_to_cpu(agpt->my_lba), lastlba);
error_found++;
}
return 0;
lastlba = last_lba(hd, bdev);
- /* Check the Primary GPT */
good_pgpt = is_gpt_valid(hd, bdev, GPT_PRIMARY_PARTITION_TABLE_LBA,
&pgpt, &pptes);
- if (good_pgpt) {
- /* Primary GPT is OK, check the alternate and warn if bad */
- good_agpt = is_gpt_valid(hd, bdev, pgpt->alternate_lba,
+ if (good_pgpt) {
+ good_agpt = is_gpt_valid(hd, bdev,
+ le64_to_cpu(pgpt->alternate_lba),
&agpt, &aptes);
- if (!good_agpt) {
- printk(KERN_WARNING
- "Alternate GPT is invalid, using primary GPT.\n");
- }
-
- compare_gpts(pgpt, agpt, lastlba);
-
- *gpt = pgpt;
- *ptes = pptes;
- if (agpt) {
- kfree(agpt);
- agpt = NULL;
- }
- if (aptes) {
- kfree(aptes);
- aptes = NULL;
- }
- } /* if primary is valid */
- else {
- /* Primary GPT is bad, check the Alternate GPT */
- good_agpt = is_gpt_valid(hd, bdev, lastlba, &agpt, &aptes);
- if (good_agpt) {
- /* Primary is bad, alternate is good.
- Return values from the alternate and warn.
- */
- printk(KERN_WARNING
- "Primary GPT is invalid, using alternate GPT.\n");
- *gpt = agpt;
- *ptes = aptes;
- }
- }
+ if (!good_agpt) {
+ good_agpt = is_gpt_valid(hd, bdev, lastlba,
+ &agpt, &aptes);
+ }
+ }
+ else {
+ good_agpt = is_gpt_valid(hd, bdev, lastlba,
+ &agpt, &aptes);
+ }
+
+ /* The obviously unsuccessful case */
+ if (!good_pgpt && !good_agpt) {
+ goto fail;
+ }
- /* Now test for valid PMBR */
/* This will be added to the EFI Spec. per Intel after v1.02. */
- if (good_pgpt || good_agpt) {
- legacymbr = kmalloc(sizeof (*legacymbr), GFP_KERNEL);
- if (legacymbr) {
- memset(legacymbr, 0, sizeof (*legacymbr));
- read_lba(hd, bdev, 0, (u8 *) legacymbr,
- sizeof (*legacymbr));
- good_pmbr = is_pmbr_valid(legacymbr);
- kfree(legacymbr);
- }
- if (good_pmbr)
- return 1;
- if (!forcegpt) {
- printk
- (" Warning: Disk has a valid GPT signature but invalid PMBR.\n");
- printk(KERN_WARNING
- " Assuming this disk is *not* a GPT disk anymore.\n");
- printk(KERN_WARNING
- " Use gpt kernel option to override. Use GNU Parted to correct disk.\n");
- } else {
- printk(KERN_WARNING
- " Warning: Disk has a valid GPT signature but invalid PMBR.\n");
- printk(KERN_WARNING
- " Use GNU Parted to correct disk.\n");
- printk(KERN_WARNING
- " gpt option taken, disk treated as GPT.\n");
- return 1;
- }
- }
-
- /* Both primary and alternate GPTs are bad, and/or PMBR is invalid.
- * This isn't our disk, return 0.
- */
- if (pgpt) {
- kfree(pgpt);
- pgpt = NULL;
- }
- if (agpt) {
- kfree(agpt);
- agpt = NULL;
- }
- if (pptes) {
- kfree(pptes);
- pptes = NULL;
- }
- if (aptes) {
- kfree(aptes);
- aptes = NULL;
- }
- *gpt = NULL;
- *ptes = NULL;
- return 0;
+ legacymbr = kmalloc(sizeof (*legacymbr), GFP_KERNEL);
+ if (legacymbr) {
+ memset(legacymbr, 0, sizeof (*legacymbr));
+ read_lba(hd, bdev, 0, (u8 *) legacymbr,
+ sizeof (*legacymbr));
+ good_pmbr = is_pmbr_valid(legacymbr);
+ kfree(legacymbr);
+ legacymbr=NULL;
+ }
+
+ /* Failure due to bad PMBR */
+ if ((good_pgpt || good_agpt) && !good_pmbr && !force_gpt) {
+ printk(KERN_WARNING
+ " Warning: Disk has a valid GPT signature "
+ "but invalid PMBR.\n");
+ printk(KERN_WARNING
+ " Assuming this disk is *not* a GPT disk anymore.\n");
+ printk(KERN_WARNING
+ " Use gpt kernel option to override. "
+ "Use GNU Parted to correct disk.\n");
+ goto fail;
+ }
+
+ /* Would fail due to bad PMBR, but force GPT anyhow */
+ if ((good_pgpt || good_agpt) && !good_pmbr && force_gpt) {
+ printk(KERN_WARNING
+ " Warning: Disk has a valid GPT signature but "
+ "invalid PMBR.\n");
+ printk(KERN_WARNING
+ " Use GNU Parted to correct disk.\n");
+ printk(KERN_WARNING
+ " gpt option taken, disk treated as GPT.\n");
+ }
+
+ compare_gpts(pgpt, agpt, lastlba);
+
+ /* The good cases */
+ if (good_pgpt && (good_pmbr || force_gpt)) {
+ *gpt = pgpt;
+ *ptes = pptes;
+ if (agpt) { kfree(agpt); agpt = NULL; }
+ if (aptes) { kfree(aptes); aptes = NULL; }
+ if (!good_agpt) {
+ printk(KERN_WARNING
+ "Alternate GPT is invalid, "
+ "using primary GPT.\n");
+ }
+ return 1;
+ }
+ else if (good_agpt && (good_pmbr || force_gpt)) {
+ *gpt = agpt;
+ *ptes = aptes;
+ if (pgpt) { kfree(pgpt); pgpt = NULL; }
+ if (pptes) { kfree(pptes); pptes = NULL; }
+ printk(KERN_WARNING
+ "Primary GPT is invalid, using alternate GPT.\n");
+ return 1;
+ }
+
+ fail:
+ if (pgpt) { kfree(pgpt); pgpt=NULL; }
+ if (agpt) { kfree(agpt); agpt=NULL; }
+ if (pptes) { kfree(pptes); pptes=NULL; }
+ if (aptes) { kfree(aptes); aptes=NULL; }
+ *gpt = NULL;
+ *ptes = NULL;
+ return 0;
}
/**
{
gpt_header *gpt = NULL;
gpt_entry *ptes = NULL;
- u32 i, nummade = 0;
+ u32 i;
int max_p;
- efi_guid_t unusedGuid = UNUSED_ENTRY_GUID;
-#if CONFIG_BLK_DEV_MD
- efi_guid_t raidGuid = PARTITION_LINUX_RAID_GUID;
-#endif
-
if (!hd || !bdev)
return -1;
if (!find_valid_gpt(hd, bdev, &gpt, &ptes) || !gpt || !ptes) {
- if (gpt)
+ if (gpt) {
kfree(gpt);
- if (ptes)
+ gpt = NULL;
+ }
+ if (ptes) {
kfree(ptes);
+ ptes = NULL;
+ }
return 0;
}
Dprintk("GUID Partition Table is valid! Yea!\n");
max_p = (1 << hd->minor_shift) - 1;
- for (i = 0; i < gpt->num_partition_entries && nummade < max_p; i++) {
- if (!efi_guidcmp(unusedGuid, ptes[i].partition_type_guid))
+ for (i = 0; i < le32_to_cpu(gpt->num_partition_entries) && i < max_p; i++) {
+ if (!efi_guidcmp(ptes[i].partition_type_guid, NULL_GUID))
continue;
- add_gd_partition(hd, nextminor, ptes[i].starting_lba,
- (ptes[i].ending_lba - ptes[i].starting_lba +
+ add_gd_partition(hd, nextminor+i,
+ le64_to_cpu(ptes[i].starting_lba),
+ (le64_to_cpu(ptes[i].ending_lba) -
+ le64_to_cpu(ptes[i].starting_lba) +
1));
/* If there's this is a RAID volume, tell md */
#if CONFIG_BLK_DEV_MD
- if (!efi_guidcmp(raidGuid, ptes[i].partition_type_guid)) {
+ if (!efi_guidcmp(ptes[i].partition_type_guid,
+ PARTITION_LINUX_RAID_GUID)) {
md_autodetect_dev(mk_kdev(hd->major,
nextminor));
}
#endif
- nummade++;
- nextminor++;
-
}
kfree(ptes);
+ ptes=NULL;
kfree(gpt);
+ gpt=NULL;
printk("\n");
return 1;
}
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1
-#define UNUSED_ENTRY_GUID \
- ((efi_guid_t) { 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }})
#define PARTITION_SYSTEM_GUID \
-((efi_guid_t) { 0xC12A7328, 0xF81F, 0x11d2, { 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B }})
+ EFI_GUID( 0xC12A7328, 0xF81F, 0x11d2, \
+ 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B)
#define LEGACY_MBR_PARTITION_GUID \
- ((efi_guid_t) { 0x024DEE41, 0x33E7, 0x11d3, { 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F }})
+ EFI_GUID( 0x024DEE41, 0x33E7, 0x11d3, \
+ 0x9D, 0x69, 0x00, 0x08, 0xC7, 0x81, 0xF3, 0x9F)
#define PARTITION_MSFT_RESERVED_GUID \
- ((efi_guid_t) { 0xE3C9E316, 0x0B5C, 0x4DB8, { 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE }})
+ EFI_GUID( 0xE3C9E316, 0x0B5C, 0x4DB8, \
+ 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE)
#define PARTITION_BASIC_DATA_GUID \
- ((efi_guid_t) { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 }})
+ EFI_GUID( 0xEBD0A0A2, 0xB9E5, 0x4433, \
+ 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7)
#define PARTITION_LINUX_RAID_GUID \
- ((efi_guid_t) { 0xa19d880f, 0x05fc, 0x4d3b, { 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e }})
+ EFI_GUID( 0xa19d880f, 0x05fc, 0x4d3b, \
+ 0xa0, 0x06, 0x74, 0x3f, 0x0f, 0x84, 0x91, 0x1e)
#define PARTITION_LINUX_SWAP_GUID \
- ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, { 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f }})
+ EFI_GUID( 0x0657fd6d, 0xa4ab, 0x43c4, \
+ 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f)
#define PARTITION_LINUX_LVM_GUID \
- ((efi_guid_t) { 0xe6d6d379, 0xf507, 0x44c2, { 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28 }})
+ EFI_GUID( 0xe6d6d379, 0xf507, 0x44c2, \
+ 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28)
typedef struct _gpt_header {
u64 signature;
typedef u8 efi_bool_t;
typedef u16 efi_char16_t; /* UNICODE character */
+
typedef struct {
- u32 data1;
- u16 data2;
- u16 data3;
- u8 data4[8];
+ u8 b[16];
} efi_guid_t;
+#define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
+((efi_guid_t) \
+{{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \
+ (b) & 0xff, ((b) >> 8) & 0xff, \
+ (c) & 0xff, ((c) >> 8) & 0xff, \
+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
+
/*
* Generic EFI table header
*/
/*
* EFI Configuration Table and GUID definitions
*/
+#define NULL_GUID \
+ EFI_GUID( 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
#define MPS_TABLE_GUID \
- ((efi_guid_t) { 0xeb9d2d2f, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
+ EFI_GUID( 0xeb9d2d2f, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
#define ACPI_TABLE_GUID \
- ((efi_guid_t) { 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
+ EFI_GUID( 0xeb9d2d30, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
#define ACPI_20_TABLE_GUID \
- ((efi_guid_t) { 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 }})
+ EFI_GUID( 0x8868e871, 0xe4f1, 0x11d3, 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 )
#define SMBIOS_TABLE_GUID \
- ((efi_guid_t) { 0xeb9d2d31, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
+ EFI_GUID( 0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
#define SAL_SYSTEM_TABLE_GUID \
- ((efi_guid_t) { 0xeb9d2d32, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }})
+ EFI_GUID( 0xeb9d2d32, 0x2d88, 0x11d3, 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d )
typedef struct {
efi_guid_t guid;
return memcmp(&left, &right, sizeof (efi_guid_t));
}
+static inline char *
+efi_guid_unparse(efi_guid_t *guid, char *out)
+{
+ sprintf(out, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid->b[3], guid->b[2], guid->b[1], guid->b[0],
+ guid->b[5], guid->b[4], guid->b[7], guid->b[6],
+ guid->b[8], guid->b[9], guid->b[10], guid->b[11],
+ guid->b[12], guid->b[13], guid->b[14], guid->b[15]);
+ return out;
+}
+
extern void efi_init (void);
extern void efi_map_pal_code (void);
extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
/* SAL Error Record Section GUID Definitions */
#define SAL_PROC_DEV_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf1, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID ( 0xe429faf1, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_MEM_DEV_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf2, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf2, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_SEL_DEV_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf3, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf3, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_PCI_BUS_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf4, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf4, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_SMBIOS_DEV_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf5, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf5, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_PCI_COMP_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf6, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf6, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_SPECIFIC_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf7, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf7, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_HOST_CTLR_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf8, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define SAL_PLAT_BUS_ERR_SECT_GUID \
- ((efi_guid_t) { 0xe429faf9, 0x3cb7, 0x11d4, { 0xbc, 0xa7, 0x0, 0x80, \
- 0xc7, 0x3c, 0x88, 0x81 }} )
+ EFI_GUID( 0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, \
+ 0xc7, 0x3c, 0x88, 0x81 )
#define MAX_CACHE_ERRORS 6
#define MAX_TLB_ERRORS 6