diff -burN linux-2.4.0-test9.orig/Documentation/Configure.help linux-2.4.0-test9-efigpt/Documentation/Configure.help
--- linux-2.4.0-test9.orig/Documentation/Configure.help	Fri Sep 22 19:11:37 2000
+++ linux-2.4.0-test9-efigpt/Documentation/Configure.help	Wed Oct 25 10:49:21 2000
@@ -11279,6 +11279,12 @@
   Say Y here if you would like to be able to read the hard disk
   partition table format used by SGI machines.
 
+Intel EFI GUID partition support
+CONFIG_EFI_PARTITION
+  Say Y here if you would like to use hard disks under Linux which
+  were partitioned using EFI GPT.  Presently only useful on the
+  IA-64 platform.
+
 ADFS file system support (EXPERIMENTAL)
 CONFIG_ADFS_FS
   The Acorn Disc Filing System is the standard file system of the
diff -burN linux-2.4.0-test9.orig/fs/partitions/Config.in linux-2.4.0-test9-efigpt/fs/partitions/Config.in
--- linux-2.4.0-test9.orig/fs/partitions/Config.in	Mon Jul 10 00:21:41 2000
+++ linux-2.4.0-test9-efigpt/fs/partitions/Config.in	Wed Oct 25 10:49:21 2000
@@ -23,6 +23,7 @@
       bool '    BSD disklabel (FreeBSD partition tables) support' CONFIG_BSD_DISKLABEL
       bool '    Solaris (x86) partition table support' CONFIG_SOLARIS_X86_PARTITION
       bool '    Unixware slices support' CONFIG_UNIXWARE_DISKLABEL
+      bool '    EFI GUID Partition support' CONFIG_EFI_PARTITION
    fi
    bool '  SGI partition support' CONFIG_SGI_PARTITION
    bool '  Ultrix partition table support' CONFIG_ULTRIX_PARTITION
diff -burN linux-2.4.0-test9.orig/fs/partitions/Makefile linux-2.4.0-test9-efigpt/fs/partitions/Makefile
--- linux-2.4.0-test9.orig/fs/partitions/Makefile	Wed Jul 19 00:49:47 2000
+++ linux-2.4.0-test9-efigpt/fs/partitions/Makefile	Wed Oct 25 10:49:21 2000
@@ -20,6 +20,7 @@
 obj-$(CONFIG_SUN_PARTITION) += sun.o
 obj-$(CONFIG_ULTRIX_PARTITION) += ultrix.o
 obj-$(CONFIG_IBM_PARTITION) += ibm.o
+obj-$(CONFIG_EFI_PARTITION) += efi.o
 
 O_OBJS += $(obj-y)
 M_OBJS += $(obj-m)
diff -burN linux-2.4.0-test9.orig/fs/partitions/check.c linux-2.4.0-test9-efigpt/fs/partitions/check.c
--- linux-2.4.0-test9.orig/fs/partitions/check.c	Wed Sep 27 15:39:23 2000
+++ linux-2.4.0-test9-efigpt/fs/partitions/check.c	Wed Oct 25 10:49:21 2000
@@ -32,6 +32,7 @@
 #include "sun.h"
 #include "ibm.h"
 #include "ultrix.h"
+#include "efi.h"
 
 extern void device_init(void);
 extern int *blk_size[];
@@ -71,6 +72,9 @@
 #endif
 #ifdef CONFIG_IBM_PARTITION
 	ibm_partition,
+#endif
+#ifdef CONFIG_EFI_PARTITION
+	efi_partition,
 #endif
 	NULL
 };
diff -burN linux-2.4.0-test9.orig/fs/partitions/efi.c linux-2.4.0-test9-efigpt/fs/partitions/efi.c
--- linux-2.4.0-test9.orig/fs/partitions/efi.c	Wed Dec 31 18:00:00 1969
+++ linux-2.4.0-test9-efigpt/fs/partitions/efi.c	Wed Oct 25 11:26:28 2000
@@ -0,0 +1,646 @@
+/************************************************************
+ * EFI GUID Partition Table handling
+ * Per Intel EFI Specification v0.99
+ * http://developer.intel.com/technology/efi/efi.htm
+ * efi.[ch] by Matt Domsch <Matt_Domsch@dell.com> 
+ *   Copyright 2000 Dell Computer Corporation
+ * CRC routines taken from the EFI Sample Implementation,
+ *   1999.12.31, lib/crc.c
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * 
+ * TODO:
+ *
+ * Changelog:
+ * Wed Oct 25 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * - Fixed the LastLBA() call to return the proper last block
+ * 
+ * Thu Oct 12 2000 Matt Domsch <Matt_Domsch@dell.com>
+ * - Thanks to Andries Brouwer for his debugging assistance.
+ * - Code works, detects all the partitions.
+ *
+ ************************************************************/
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+#include <linux/malloc.h>
+#include <linux/smp_lock.h>
+#include <asm/system.h>
+#include <asm/efi.h>
+
+#include "check.h"
+#include "efi.h"
+
+#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+extern void md_autodetect_dev(kdev_t dev);
+#endif
+
+
+#undef EFI_DEBUG
+#ifdef EFI_DEBUG
+static char *efi_printk_level = KERN_DEBUG;
+#define debug_printk printk
+#else
+#define debug_printk(...)
+#endif
+
+/* CRC routines taken from the EFI Sample Implementation,
+ *   1999.12.31, lib/crc.c
+ *
+ * Note, the EFI Specification, v0.99, has a reference to
+ * Dr. Dobbs Journal, May 1994 (actually it's in May 1992)
+ * but that isn't the CRC function being used by EFI.
+ */
+
+static u32 CRCTable[256] = {
+	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
+	0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+	0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
+	0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+	0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+	0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+	0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
+	0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+	0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
+	0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+	0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
+	0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+	0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
+	0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+	0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+	0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+	0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
+	0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+	0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
+	0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+	0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
+	0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+	0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
+	0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+	0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+	0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+	0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
+	0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+	0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
+	0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+	0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
+	0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+	0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
+	0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+	0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+	0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+	0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
+	0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+	0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
+	0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+	0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
+	0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 
+};
+
+static u32
+CalculateCrc (void *_pt, u32 Size)
+{
+	u8 *pt = (u8 *)_pt;
+	register u32 Crc;
+
+	/*  compute crc */
+	Crc = 0xffffffff;
+	while (Size) {
+		Crc = (Crc >> 8) ^ CRCTable[(__u8) Crc ^ *pt];
+		pt += 1;
+		Size -= 1;
+	}
+	Crc = Crc ^ 0xffffffff;
+	return Crc;
+}
+
+
+
+/************************************************************
+ * IsLegacyMBRValid()
+ * Requires:
+ *  - mbr is a pointer to a legacy mbr structure
+ * Modifies: nothing
+ * Returns:
+ *  1 on true
+ *  0 on false
+ ************************************************************/
+static inline int
+IsLegacyMBRValid(LegacyMBR_t *mbr)
+{
+	return (mbr ? (mbr->Signature == MSDOS_MBR_SIGNATURE) : 0);
+}
+
+
+
+/************************************************************
+ * LastLBA()
+ * Requires:
+ *  - struct gendisk hd
+ *  - kdev_t dev
+ * Modifies: nothing
+ * Returns:
+ *  Last LBA value on success.  This is stored (by sd and
+ *  ide-geometry) in 
+ *  the part[0] entry for this disk, and is the number of
+ *  physical sectors available on the disk.
+ *  0 on error
+ ************************************************************/
+u64
+LastLBA(struct gendisk *hd, kdev_t dev)
+{
+  if (!hd || !hd->part) return 0;
+  return hd->part[MINOR(dev)].nr_sects - 1;
+}
+
+
+/************************************************************
+ * ReadLBA()
+ * Requires:
+ *  - hd is our disk device.
+ *  - dev is our device major number
+ *  - lba is the logical block address desired (disk hardsector number)
+ *  - buffer is a buffer of size size into which data copied
+ *  - size_t count is size of the read (in bytes)
+ * Modifies:
+ *  - buffer
+ * Returns:
+ *  - count of bytes read
+ *  - 0 on error
+ * Bugs:
+ *  - bread() takes second argument as a signed int, not a u64.
+ *    This is because getblk() takes the block number as a signed int.
+ *    This overflow is known on l-k.   We overflow at about 1TB.
+ *
+ ************************************************************/
+
+static size_t
+ReadLBA(struct gendisk *hd, kdev_t dev, u64 _lba, u8 *buffer, size_t count)
+{
+	struct buffer_head *bh;
+	size_t totalreadcount = 0, bytesread;
+	int lba = (_lba & 0x7FFFFFFF), i, blockstoread, blocksize;
+	debug_printk(efi_printk_level "ReadLBA(%p,%s,%x,%p,%x)\n",
+		     hd, kdevname(dev), lba, buffer, count);
+  
+	if (!hd || !buffer || !count) return 0;
+  
+  
+	blocksize = get_hardblocksize(dev);
+	if (!blocksize) blocksize = 512;
+	blockstoread = count / blocksize;
+	if (count % blocksize) blockstoread += 1;
+	debug_printk(efi_printk_level "about to read %d blocks\n",
+		     blockstoread);
+  
+  
+	for (i=0; i<blockstoread; i++) {
+		bh = bread(dev, lba+i, blocksize);
+		if (!bh) {
+			/* We hit the end of the disk */
+			debug_printk(efi_printk_level
+				     "bread returned NULL.\n");
+			return totalreadcount;
+		}
+    
+		bytesread = (count > bh->b_size ? bh->b_size : count);
+		memcpy(buffer, bh->b_data, bytesread);
+    
+		buffer += bytesread;         /* Advance the buffer pointer */
+		totalreadcount += bytesread; /* Advance the total read count */
+		count -= bytesread;         /* Subtract bytesread from count */
+    
+		brelse(bh); 
+	}
+  
+	return totalreadcount;
+}
+
+void
+PrintGuidPartitionTableHeader(GuidPartitionTableHeader_t *gpt)
+{
+	debug_printk(efi_printk_level "GUID Partition Table Header\n");
+	if (!gpt) return;
+	debug_printk(efi_printk_level "Signature      : %lx\n",
+		     gpt->Signature);
+	debug_printk(efi_printk_level "Revision       : %x\n",
+		     gpt->Revision);
+	debug_printk(efi_printk_level "HeaderSize     : %x\n",
+		     gpt->HeaderSize);
+	debug_printk(efi_printk_level "HeaderCRC32    : %x\n",
+		     gpt->HeaderCRC32);
+	debug_printk(efi_printk_level "MyLBA          : %lx\n",
+		     gpt->MyLBA);
+	debug_printk(efi_printk_level "AlternateLBA   : %lx\n",
+		     gpt->AlternateLBA);
+	debug_printk(efi_printk_level "FirstUsableLBA : %lx\n",
+		     gpt->FirstUsableLBA);
+	debug_printk(efi_printk_level "LastUsableLBA  : %lx\n",
+		     gpt->LastUsableLBA);
+  
+	debug_printk(efi_printk_level "PartitionEntryLBA : %lx\n",
+		     gpt->PartitionEntryLBA);
+	debug_printk(efi_printk_level "NumberOfPartitionEntries : %x\n",
+		     gpt->NumberOfPartitionEntries);
+	debug_printk(efi_printk_level "SizeOfPartitionEntry : %x\n",
+		     gpt->SizeOfPartitionEntry);
+	debug_printk(efi_printk_level "PartitionEntryArrayCRC32 : %x\n",
+		     gpt->PartitionEntryArrayCRC32);
+  
+	return;
+}
+
+
+
+/************************************************************
+ * ReadGuidPartitionEntries()
+ * Requires:
+ *  - filedes is an open file descriptor, suitable for reading
+ *  - lba is the Logical Block Address of the partition table
+ *  - gpt is a buffer into which the GPT will be put  
+ * Modifies:
+ *  - filedes file and pointer
+ *  - gpt
+ * Returns:
+ *   pte on success
+ *   NULL on error
+ * Notes: remember to free pte when you're done!
+ ************************************************************/
+GuidPartitionEntry_t *
+ReadGuidPartitionEntries(struct gendisk *hd, kdev_t dev,
+			 GuidPartitionTableHeader_t *gpt)
+{
+	size_t count;
+	GuidPartitionEntry_t *pte;
+	if (!hd || !gpt) return NULL;
+  
+	count = gpt->NumberOfPartitionEntries * gpt->SizeOfPartitionEntry;
+	debug_printk(efi_printk_level "ReadGPTEs() kmallocing %x bytes\n",
+		     count);
+	if (!count) return NULL;
+	pte = kmalloc(count, GFP_KERNEL);
+	if (!pte)  return NULL;
+	memset(pte, 0, count);
+  
+	if (ReadLBA(hd, dev, gpt->PartitionEntryLBA, (u8 *)pte,
+		    count) < count) {
+		kfree(pte);
+		return NULL;
+	}
+	return pte;
+}
+
+
+
+/************************************************************
+ * ReadGuidPartitionTableHeader()
+ * Requires:
+ *  - hd is our struct gendisk
+ *  - dev is our device major number
+ *  - lba is the Logical Block Address of the partition table
+ *  - gpt is a buffer into which the GPT will be put  
+ *  - pte is a buffer into which the PTEs will be put  
+ * Modifies:
+ *  - gpt and pte
+ * Returns:
+ *   1 on success
+ *   0 on error
+ ************************************************************/
+
+GuidPartitionTableHeader_t *
+ReadGuidPartitionTableHeader(struct gendisk *hd, kdev_t dev, u64 lba)
+     
+{
+	GuidPartitionTableHeader_t *gpt;
+	if (!hd) return NULL;
+  
+	gpt = kmalloc(sizeof(GuidPartitionTableHeader_t), GFP_KERNEL);
+	if (!gpt) return NULL;
+	memset(gpt, 0, sizeof(GuidPartitionTableHeader_t));
+  
+	debug_printk(efi_printk_level "GPTH() calling ReadLBA().\n");
+	if (ReadLBA(hd, dev, lba, (u8 *)gpt,
+		    sizeof(GuidPartitionTableHeader_t)) <
+	    sizeof(GuidPartitionTableHeader_t)) {
+		debug_printk(efi_printk_level "ReadGPTH(%lx) read failed.\n",
+			     lba);
+		kfree(gpt);
+		return NULL;
+	}
+	PrintGuidPartitionTableHeader(gpt);
+  
+	return gpt;
+}
+
+
+
+/************************************************************
+ * IsGuidPartitionTableValid()
+ * Requires:
+ *  - gd points to our struct gendisk
+ *  - dev is our device major number
+ *  - lba is the logical block address of the GPTH to test
+ *  - gpt is a GPTH if it's valid
+ *  - ptes is a PTEs if it's valid
+ * Modifies:
+ *  - gpt and ptes
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ ************************************************************/
+static int
+IsGuidPartitionTableValid(struct gendisk *hd, kdev_t dev, u64 lba, 
+                          GuidPartitionTableHeader_t **gpt,
+                          GuidPartitionEntry_t **ptes)
+{
+	u32 crc, origcrc;
+  
+	if (!hd || !gpt || !ptes) return 0;
+	if (!(*gpt = ReadGuidPartitionTableHeader(hd, dev, lba))) return 0;
+  
+	/* Check the GUID Partition Table Signature */
+	if ((*gpt)->Signature != GUID_PT_HEADER_SIGNATURE) {
+		debug_printk(efi_printk_level "GUID Partition Table Header Signature is wrong: %x != %x\n", (*gpt)->Signature, GUID_PT_HEADER_SIGNATURE);
+		kfree(*gpt);
+		*gpt = NULL;
+		return 0;
+	}
+  
+	/* Check the GUID Partition Table CRC */
+	origcrc = (*gpt)->HeaderCRC32;
+	(*gpt)->HeaderCRC32 = 0;
+	crc = CalculateCrc(*gpt, (*gpt)->HeaderSize);
+  
+  
+	if (crc != origcrc) {
+		debug_printk(efi_printk_level "GUID Partition Table Header CRC is wrong: %x != %x\n", (*gpt)->HeaderCRC32, origcrc);
+		kfree(*gpt);
+		*gpt = NULL;
+		return 0;
+	}
+	(*gpt)->HeaderCRC32 = origcrc;
+  
+	/* Check that the MyLBA entry points to the LBA that contains
+	 * the GUID Partition Table */
+	if ((*gpt)->MyLBA != lba) {
+		debug_printk(efi_printk_level "GPT MyLBA incorrect: %lx != %lx\n", (*gpt)->MyLBA, lba);
+		kfree(*gpt);
+		*gpt = NULL;
+		return 0;
+	}
+  
+	if (!(*ptes = ReadGuidPartitionEntries(hd, dev, *gpt))) {
+		debug_printk(efi_printk_level "read PTEs failed.\n");
+		kfree(*gpt);
+		*gpt = NULL;
+		return 0;
+	}
+  
+	/* Check the GUID Partition Entry Array CRC */
+	crc = CalculateCrc(*ptes, (*gpt)->NumberOfPartitionEntries *
+			   (*gpt)->SizeOfPartitionEntry);
+  
+	if (crc != (*gpt)->PartitionEntryArrayCRC32)  {
+		debug_printk(efi_printk_level "GUID Partitition Entry Array CRC check failed.\n");
+		kfree(*gpt);
+		*gpt = NULL;
+		kfree(*ptes);
+		*ptes = NULL;
+		return 0;
+	}
+  
+  
+	/* We're done, all's well */
+	return 1;
+}
+
+
+
+/************************************************************
+ * FindValidGPT()
+ * Requires:
+ *  - gd points to our struct gendisk
+ *  - dev is our device major number
+ *  - gpt is a GPTH if it's valid
+ *  - ptes is a PTE
+ * Modifies:
+ *  - gpt & ptes
+ * Returns:
+ *   1 if valid
+ *   0 on error
+ ************************************************************/
+static int
+FindValidGPT(struct gendisk *hd, kdev_t dev,
+             GuidPartitionTableHeader_t **gpt,
+             GuidPartitionEntry_t **ptes)
+{
+	int rc = 0;
+	GuidPartitionTableHeader_t *pgpt = NULL, *agpt = NULL;
+	GuidPartitionEntry_t *pptes = NULL, *aptes = NULL;
+	u64 lastlba;
+	if (!hd || !gpt || !ptes) return 0;
+
+	lastlba = LastLBA(hd, dev);
+	/* Check the Primary GPT */
+	rc = IsGuidPartitionTableValid(hd, dev, 1, &pgpt, &pptes);
+	if (rc) {
+		/* Primary GPT is OK, check the alternate and warn if bad */
+		rc = IsGuidPartitionTableValid(hd, dev, pgpt->AlternateLBA,
+					       &agpt, &aptes);    
+		if (!rc){
+			printk(KERN_WARNING "Alternate GPT is invalid, using primary GPT.\n");
+		}
+    
+		*gpt = pgpt;
+		*ptes = pptes;
+		if (agpt)  kfree(agpt);
+		if (aptes) kfree(aptes);
+		return 1;
+	} /* if primary is valid */
+	else {
+		/* Primary GPT is bad, check the Alternate GPT */
+		rc = IsGuidPartitionTableValid(hd, dev, lastlba,
+					       &agpt, &aptes);    
+		if (rc) {
+			/* 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;
+			return 1;
+		}
+		else {
+			/* Primary is bad, alternate is bad, try "other"
+			 * alternate.  This is necessary because if we
+			 * have an odd-sized disk, user-space might
+			 * have put the alternate in block lastlba-1.
+			 */
+			if (!(lastlba & 1)) {
+				lastlba--;
+				rc = IsGuidPartitionTableValid(hd, dev,
+							       lastlba,
+							       &agpt, &aptes);
+				if (rc) {
+					/* Primary is bad, alternate is good.
+					 * Return values from the alternate
+					 * and warn.
+					 */
+					printk("Primary GPT is invalid, using alternate GPT.\n");
+					*gpt = agpt;
+					*ptes = aptes;
+					return 1;
+				}
+			}
+		}
+	}
+	/* Both primary and alternate GPTs are bad.
+	 * This isn't our disk, return 0.
+	 */
+	return 0;
+}
+
+
+
+/*
+ * Create devices for each entry in the GUID Partition Table Entries.
+ * The first block of each partition is a Legacy MBR.
+ *
+ * We do not create a Linux partition for GPT, but
+ * only for the actual data partitions.
+ * Returns:
+ * -1 if unable to read the partition table
+ *  0 if this isn't our partition table
+ *  1 if successful
+ *
+ */
+
+static int
+add_gpt_partitions(struct gendisk *hd, kdev_t dev, int nextminor)
+{
+	GuidPartitionTableHeader_t *gpt = NULL;
+	GuidPartitionEntry_t *ptes = NULL;
+	u32 i, nummade=0;
+
+	efi_guid_t unusedGuid = UNUSED_ENTRY_GUID;
+#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+	efi_guid_t raidGuid = PARTITION_LINUX_RAID_GUID;
+#endif
+
+	if (!hd) return -1;
+  
+	if (!FindValidGPT(hd, dev, &gpt, &ptes) || 
+	    !gpt || !ptes) {
+		if (gpt) kfree(gpt);
+		if (ptes) kfree(ptes);
+		return 0;
+	}
+  
+	debug_printk(efi_printk_level "GUID Partition Table is valid!  Yea!\n");
+	for (i = 0; i < gpt->NumberOfPartitionEntries &&
+		     nummade < (hd->max_p - 1); i++) {
+		if (!efi_guidcmp(unusedGuid, ptes[i].PartitionTypeGuid))
+			continue;
+
+		add_gd_partition(hd, nextminor, ptes[i].StartingLBA,
+				 (ptes[i].EndingLBA-ptes[i].StartingLBA + 1));
+
+		/* If there's this is a RAID volume, tell md */
+#if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
+		if (!efi_guidcmp(raidGuid, ptes[i].PartitionTypeGuid)) {
+			md_autodetect_dev(MKDEV(MAJOR(dev),nextminor));
+		}
+#endif
+		nummade++;
+		nextminor++;
+
+	}
+	kfree(ptes);
+	kfree(gpt);
+	printk("\n");
+	return 1;
+  
+}
+
+
+/* 
+ * efi_partition()
+ *
+ * If the first block on the disk is a legacy MBR,
+ * it got handled already by msdos_partition().
+ * If it's a Protective MBR, we'll handle it here.
+ *
+ * Returns:
+ * -1 if unable to read the partition table
+ *  0 if this isn't our partitoin table
+ *  1 if successful
+ *
+ */
+
+int
+efi_partition(struct gendisk *hd, kdev_t dev,
+              unsigned long first_sector, int first_part_minor) {
+	int hardblocksize = get_hardblocksize(dev);
+	int orig_blksize_size = BLOCK_SIZE;
+	int rc = 0;
+  
+  /* not good, but choose something! */
+	if (!hardblocksize) hardblocksize = 512;
+  
+	/* Need to change the block size that the block layer uses */
+	if (blksize_size[MAJOR(dev)]){
+		orig_blksize_size = blksize_size[MAJOR(dev)][MINOR(dev)];
+	}
+  
+	if (orig_blksize_size != hardblocksize)
+		set_blocksize(dev, hardblocksize);
+  
+	rc = add_gpt_partitions(hd, dev, first_part_minor);
+  
+	/* change back */
+	if (orig_blksize_size != hardblocksize)
+		set_blocksize(dev, orig_blksize_size);
+  
+	return rc;
+}
+
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
+
+
+
diff -burN linux-2.4.0-test9.orig/fs/partitions/efi.h linux-2.4.0-test9-efigpt/fs/partitions/efi.h
--- linux-2.4.0-test9.orig/fs/partitions/efi.h	Wed Dec 31 18:00:00 1969
+++ linux-2.4.0-test9-efigpt/fs/partitions/efi.h	Wed Oct 25 10:59:37 2000
@@ -0,0 +1,154 @@
+/************************************************************
+ * EFI GUID Partition Table
+ * Per Intel EFI Specification v0.99
+ * http://developer.intel.com/technology/efi/efi.htm
+ *
+ * By Matt Domsch <Matt_Domsch@dell.com>  Fri Sep 22 22:15:56 CDT 2000  
+ *   Copyright 2000 Dell Computer Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ * 
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * 
+ ************************************************************/
+
+#ifndef FS_PART_EFI_H_INCLUDED
+#define FS_PART_EFI_H_INCLUDED
+
+#include <linux/types.h>
+#include <asm/efi.h>
+
+#include <linux/config.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/blk.h>
+
+#define MSDOS_MBR_SIGNATURE 0xaa55
+#define EFI_PMBR_OSTYPE_EFI 0xEF
+#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
+
+#define GUID_PT_BLOCK_SIZE 512
+
+#define GUID_PT_HEADER_SIGNATURE 0x5452415020494645L
+#define GUID_PT_HEADER_REVISION_V1 0x00010000
+#define GUID_PT_HEADER_REVISION_V0_99 0x00000099
+#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 }})
+#define LEGACY_MBR_PARTITION_GUID \
+    ((efi_guid_t) { 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 }})
+#define PARTITION_BASIC_DATA_GUID \
+    ((efi_guid_t) { 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  }})
+#define PARTITION_LINUX_SWAP_GUID \
+    ((efi_guid_t) { 0x0657fd6d, 0xa4ab, 0x43c4, { 0x84, 0xe5, 0x09, 0x33, 0xc8, 0x4b, 0x4f, 0x4f  }})
+
+typedef struct _GuidPartitionTableHeader_t {
+  u64 Signature;
+  u32 Revision;
+  u32 HeaderSize;
+  u32 HeaderCRC32;
+  u32 Reserved1;
+  u64 MyLBA;
+  u64 AlternateLBA;
+  u64 FirstUsableLBA;
+  u64 LastUsableLBA;
+  efi_guid_t DiskGUID;
+  u64 PartitionEntryLBA;
+  u32 NumberOfPartitionEntries;
+  u32 SizeOfPartitionEntry;
+  u32 PartitionEntryArrayCRC32;
+  u8 Reserved2[GUID_PT_BLOCK_SIZE - 92];
+} GuidPartitionTableHeader_t;
+
+typedef struct _GuidPartitionEntryAttributes_t {
+  __u64 RequiredToFunction:1;
+  __u64 Reserved:63;
+} GuidPartitionEntryAttributes_t;
+
+typedef struct _GuidPartitionEntry_t {
+  efi_guid_t PartitionTypeGuid;
+  efi_guid_t UniquePartitionGuid;
+  u64 StartingLBA;
+  u64 EndingLBA;
+  GuidPartitionEntryAttributes_t Attributes;
+  efi_char16_t PartitionName[72/sizeof(efi_char16_t)];
+} GuidPartitionEntry_t;
+
+
+
+typedef struct _PartitionRecord_t {
+  u8 BootIndicator;  /* Not used by EFI firmware. Set to 0x80 to indicate that this
+                        is the bootable legacy partition. */
+  u8 StartHead;      /* Start of partition in CHS address, not used by EFI firmware. */
+  u8 StartSector;    /* Start of partition in CHS address, not used by EFI firmware. */
+  u8 StartTrack;     /* Start of partition in CHS address, not used by EFI firmware. */
+  u8 OSType;         /* OS type. A value of 0xEF defines an EFI system partition.
+                        Other values are reserved for legacy operating systems, and
+                        allocated independently of the EFI specification. */
+  u8 EndHead;        /* End of partition in CHS address, not used by EFI firmware. */
+  u8 EndSector;      /* End of partition in CHS address, not used by EFI firmware. */
+  u8 EndTrack;       /* End of partition in CHS address, not used by EFI firmware. */
+  u32 StartingLBA;   /* Starting LBA address of the partition on the disk. Used by
+                        EFI firmware to define the start of the partition. */
+  u32 SizeInLBA;     /* Size of partition in LBA. Used by EFI firmware to determine
+                        the size of the partition. */
+} PartitionRecord_t;
+
+typedef struct _LegacyMBR_t {
+  u8 BootCode[440];
+  u32 UniqueMBRSignature;
+  u16 Unknown;
+  PartitionRecord_t PartitionRecord[4];
+  u16 Signature;
+} __attribute__ ((packed)) LegacyMBR_t;
+
+
+
+#define EFI_GPT_PRIMARY_PARTITION_TABLE_LBA 1
+
+/* Functions */
+extern int
+efi_partition(struct gendisk *hd, kdev_t dev,
+              unsigned long first_sector, int first_part_minor);
+
+
+
+
+#endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * --------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -burN linux-2.4.0-test9.orig/fs/partitions/msdos.c linux-2.4.0-test9-efigpt/fs/partitions/msdos.c
--- linux-2.4.0-test9.orig/fs/partitions/msdos.c	Wed Jul 19 01:29:16 2000
+++ linux-2.4.0-test9-efigpt/fs/partitions/msdos.c	Wed Oct 25 10:49:21 2000
@@ -36,6 +36,10 @@
 #include "check.h"
 #include "msdos.h"
 
+#ifdef CONFIG_EFI_PARTITION
+#include "efi.h"
+#endif
+
 #if CONFIG_BLK_DEV_MD && CONFIG_AUTODETECT_RAID
 extern void md_autodetect_dev(kdev_t dev);
 #endif
@@ -378,6 +382,16 @@
 		bforget(bh);
 		return 0;
 	}
+#ifdef CONFIG_EFI_PARTITION
+	p = (struct partition *) (0x1be + data);
+	for (i=1 ; i<=4 ; i++,p++) {
+	  /* If this is an EFI GPT disk, msdos should ignore it. */
+	  if (SYS_IND(p) == EFI_PMBR_OSTYPE_EFI_GPT) {
+	    bforget(bh);
+	    return 0;
+	  }
+	}
+#endif
 	p = (struct partition *) (0x1be + data);
 
 #ifdef CONFIG_BLK_DEV_IDE
