# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1069+1.1019.1.24 -> 1.1070 
#	      fs/proc/base.c	1.12.1.2 -> 1.16   
#	     kernel/sysctl.c	1.19.1.4 -> 1.22.1.1
#	            Makefile	1.190.1.42 -> 1.223  
#	 fs/proc/proc_misc.c	1.20.1.1 -> 1.22.1.1
#	drivers/char/agp/agpgart_be.c	1.35.1.9 -> 1.49   
#	drivers/char/Config.in	1.36.1.12 -> 1.49   
#	drivers/net/Makefile	1.29.1.8 -> 1.36   
#	arch/i386/kernel/io_apic.c	1.27.1.2 -> 1.31   
#	include/linux/pci_ids.h	1.44.5.1 -> 1.64   
#	arch/i386/kernel/setup.c	1.68.1.2 -> 1.72   
#	arch/ia64/kernel/acpi.c	1.6.3.10 -> 1.24   
#	Documentation/Configure.help	1.162.1.14 -> 1.170  
#	include/asm-i386/hw_irq.h	1.4.1.2 -> 1.5.1.1
#	arch/i386/kernel/pci-irq.c	1.20.1.2 -> 1.24   
#
diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help
--- a/Documentation/Configure.help	Wed Oct  8 09:06:06 2003
+++ b/Documentation/Configure.help	Wed Oct  8 09:06:06 2003
@@ -17531,6 +17531,11 @@
   purpose port, say Y here. See
   <http://www.dig64.org/specifications/DIG64_HCDPv10a_01.pdf>.
 
+Support for serial ports defined in ACPI namespace
+CONFIG_SERIAL_ACPI
+  If you wish to enable serial port discovery via the ACPI
+  namespace, say Y here.  If unsure, say N.
+
 Support for PowerMac serial ports
 CONFIG_MAC_SERIAL
   If you have Macintosh style serial ports (8 pin mini-DIN), say Y
@@ -18909,20 +18914,6 @@
   down the system.  Until then, you can cat it, and see output when
   a button is pressed.
 
-CONFIG_ACPI_BATTERY
-  This driver adds support for battery information through
-  /proc/acpi/battery. If you have a mobile system with a battery, 
-  say Y.
-
-CONFIG_ACPI_FAN
-  This driver adds support for ACPI fan devices, allowing user-mode 
-  applications to perform basic fan control (on, off, status).
-
-CONFIG_ACPI_PROCESSOR
-  This driver installs ACPI as the idle handler for Linux, and uses
-  ACPI C2 and C3 processor states to save power, on systems that
-  support it.
-
 ACPI AC Adapter
 CONFIG_ACPI_AC
   This driver adds support for the AC Adapter object, which indicates
@@ -18932,65 +18923,18 @@
 ACPI Embedded Controller
 CONFIG_ACPI_EC
   This driver is required on some systems for the proper operation of
-  the battery and thermal drivers.  If you are compiling for a laptop,
-  say Y.
+  the battery and thermal drivers.  If you are compiling for a 
+  mobile system, say Y.
 
-ACPI Control Method Battery
-CONFIG_ACPI_CMBATT
-  This driver adds support for battery information through
-  /proc/acpi/battery. If you have a laptop with a battery, say Y.
+CONFIG_ACPI_PROCESSOR
+  This driver installs ACPI as the idle handler for Linux, and uses
+  ACPI C2 and C3 processor states to save power, on systems that
+  support it.
 
-ACPI Thermal
 CONFIG_ACPI_THERMAL
   This driver handles overheating conditions on laptops. It is HIGHLY
   recommended, as your laptop CPU may be damaged without it.
 
-ACPI ASUS/Medion Laptop Extras
-CONFIG_ACPI_ASUS
-  This driver provides support for extra features of ACPI-compatible
-  ASUS laptops. As some of Medion laptops are made by ASUS, it may also
-  support some Medion laptops (such as 9675 for example).  It makes all
-  the extra buttons generate standard ACPI events that go through
-  /proc/acpi/events, and (on some models) adds support for changing the
-  display brightness and output, switching the LCD backlight on and off,
-  and most importantly, allows you to blink those fancy LEDs intended
-  for reporting mail and wireless status.
-  
-  All settings are changed via /proc/acpi/asus directory entries. Owner
-  and group for these entries can be set with asus_uid and asus_gid
-  parameters.
-  
-  More information and a userspace daemon for handling the extra buttons
-  at <http://sourceforge.net/projects/acpi4asus/>.
-  
-  If you have an ACPI-compatible ASUS laptop, say Y or M here. This
-  driver is still under development, so if your laptop is unsupported or
-  something works not quite as expected, please use the mailing list
-  available on the above page (acpi4asus-user@lists.sourceforge.net)
-  
-ACPI Toshiba Laptop Extras
-CONFIG_ACPI_TOSHIBA
-  This driver adds support for access to certain system settings
-  on "legacy free" Toshiba laptops.  These laptops can be recognized by
-  their lack of a BIOS setup menu and APM support.
-
-  On these machines, all system configuration is handled through the
-  ACPI.  This driver is required for access to controls not covered
-  by the general ACPI drivers, such as LCD brightness, video output,
-  etc.
-
-  This driver differs from the non-ACPI Toshiba laptop driver (located
-  under "Processor type and features") in several aspects.
-  Configuration is accessed by reading and writing text files in the
-  /proc tree instead of by program interface to /dev.  Furthermore, no
-  power management functions are exposed, as those are handled by the
-  general ACPI drivers.
-
-  More information about this driver is available at
-  <http://memebeam.org/toys/ToshibaAcpiDriver>.
-
-  If you have a legacy free Toshiba laptop (such as the Libretto L1
-  series), say Y.
 
 Advanced Power Management BIOS support
 CONFIG_APM
@@ -26130,11 +26074,13 @@
 # Choice: ia64type
 Itanium
 CONFIG_ITANIUM
-  Select your IA64 processor type.  The default is Intel Itanium.
+  Select your IA-64 processor type.  The default is Intel Itanium.
+  This choice is safe for all IA-64 systems, but may not perform
+  optimally on systems with, say, Itanium 2 or newer processors.
 
-McKinley
+Itanium 2
 CONFIG_MCKINLEY
-  Select this to configure for a McKinley processor.
+  Select this to configure for an Itanium 2 (McKinley) processor.
 
 # Choice: ia64system
 IA-64 system type
@@ -26191,6 +26137,14 @@
   Say Y here to enable machine check support for IA-64.  If you're
   unsure, answer Y.
 
+Use PAL_HALT_LIGHT in idle loop
+CONFIG_IA64_PAL_IDLE
+  Say Y here to enable use of PAL_HALT_LIGHT in the cpu_idle loop.
+  This allows the CPU to enter a low power state when idle.  You
+  can enable CONFIG_IA64_PALINFO and check /proc/pal/cpu0/power_info
+  to see the power consumption and latency for this state.  If you're
+  unsure your firmware supports it, answer N.
+
 Disable IA-64 Virtual Hash Page Table
 CONFIG_DISABLE_VHPT
   The Virtual Hash Page Table (VHPT) enhances virtual address
@@ -26211,12 +26165,31 @@
   and restore instructions.  It's useful for tracking down spinlock
   problems, but slow!  If you're unsure, select N.
 
-Early printk support (requires VGA!)
+Early printk support
 CONFIG_IA64_EARLY_PRINTK
-  Selecting this option uses the VGA screen for printk() output before
-  the consoles are initialised.  It is useful for debugging problems
-  early in the boot process, but only if you have a VGA screen
-  attached.  If you're unsure, select N.
+  Selecting this option uses a UART or VGA screen (or both) for
+  printk() output before the consoles are initialised.  It is useful
+  for debugging problems early in the boot process, but only if you
+  have a serial terminal or a VGA screen attached.  If you're unsure,
+  select N.
+
+Early printk on serial port
+CONFIG_IA64_EARLY_PRINTK_UART
+  Select this option to use a serial port for early printk() output.
+  You must also select either CONFIG_IA64_EARLY_PRINTK_UART_BASE or
+  CONFIG_SERIAL_HCDP.  If you select CONFIG_SERIAL_HCDP, early
+  printk() output will appear on the first console device described by
+  the HCDP.  If you set CONFIG_IA64_EARLY_PRINTK_UART_BASE, the HCDP
+  will be ignored.
+
+UART base address
+CONFIG_IA64_EARLY_PRINTK_UART_BASE
+  The physical MMIO address of the UART to use for early printk().
+  This overrides any UART located using the EFI HCDP table.
+
+Early printk on VGA
+CONFIG_IA64_EARLY_PRINTK_VGA
+  Select this option to use VGA for early printk() output.
 
 Print possible IA64 hazards to console
 CONFIG_IA64_PRINT_HAZARDS
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Wed Oct  8 09:06:06 2003
+++ b/Makefile	Wed Oct  8 09:06:06 2003
@@ -93,6 +93,7 @@
 
 CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
 	  -fno-strict-aliasing -fno-common
+CFLAGS += -g
 ifndef CONFIG_FRAME_POINTER
 CFLAGS += -fomit-frame-pointer
 endif
@@ -305,8 +306,7 @@
 	$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
 
 xconfig: symlinks
-	$(MAKE) -C scripts kconfig.tk
-	wish -f scripts/kconfig.tk
+	@echo -e "***\n* Sorry, xconfig is broken; use \"make menuconfig\" instead.\n***"
 
 menuconfig: include/linux/version.h symlinks
 	$(MAKE) -C scripts/lxdialog all
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	Wed Oct  8 09:06:06 2003
+++ b/arch/ia64/kernel/acpi.c	Wed Oct  8 09:06:06 2003
@@ -623,4 +623,21 @@
 	return gsi_to_vector(irq);
 }
 
+int
+acpi_register_irq (u32 gsi, u32 polarity, u32 mode)
+{
+	int vector = 0;
+
+	if (has_8259 && gsi < 16)
+		return isa_irq_to_vector(gsi);
+
+	if (!iosapic_register_intr)
+		return 0;
+
+	/* Turn it on */
+	vector = iosapic_register_intr(gsi, polarity ? IOSAPIC_POL_HIGH : IOSAPIC_POL_LOW,
+			mode ? IOSAPIC_EDGE : IOSAPIC_LEVEL);
+	return vector;
+}
+
 #endif /* CONFIG_ACPI_BOOT */
diff -Nru a/drivers/char/Config.in b/drivers/char/Config.in
--- a/drivers/char/Config.in	Wed Oct  8 09:06:06 2003
+++ b/drivers/char/Config.in	Wed Oct  8 09:06:06 2003
@@ -24,6 +24,9 @@
       tristate '   Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
       tristate '   Dual serial port support' CONFIG_DUALSP_SERIAL
    fi
+   if [ "$CONFIG_ACPI" = "y" ]; then
+      bool '  Support for serial ports defined in ACPI namespace' CONFIG_SERIAL_ACPI
+   fi
 fi
 dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
 if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
@@ -313,6 +316,7 @@
       bool '  NVIDIA chipset support' CONFIG_AGP_NVIDIA
    fi
    if [ "$CONFIG_IA64" = "y" ]; then
+      bool '  Intel 460GX support' CONFIG_AGP_I460
       bool '  HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
    fi
 fi
diff -Nru a/drivers/char/agp/agpgart_be.c b/drivers/char/agp/agpgart_be.c
--- a/drivers/char/agp/agpgart_be.c	Wed Oct  8 09:06:06 2003
+++ b/drivers/char/agp/agpgart_be.c	Wed Oct  8 09:06:06 2003
@@ -45,10 +45,14 @@
 #include <linux/pagemap.h>
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
+#include <linux/acpi.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/smplock.h>
 #ifdef CONFIG_AGP_NVIDIA
     #include <asm/msr.h>
 #endif
@@ -216,10 +220,14 @@
 		agp_bridge.free_by_type(curr);
 		return;
 	}
-	if (curr->page_count != 0) {
-		for (i = 0; i < curr->page_count; i++) {
-			agp_bridge.agp_destroy_page((unsigned long)
-					 phys_to_virt(curr->memory[i]));
+	if (agp_bridge.cant_use_aperture) {
+		vfree(curr->vmptr);
+	} else {
+		if (curr->page_count != 0) {
+			for (i = 0; i < curr->page_count; i++) {
+				agp_bridge.agp_destroy_page((unsigned long)
+						 phys_to_virt(curr->memory[i]));
+			}
 		}
 	}
 	agp_free_key(curr->key);
@@ -228,6 +236,37 @@
 	MOD_DEC_USE_COUNT;
 }
 
+#define IN_VMALLOC(_x)	  (((_x) >= VMALLOC_START) && ((_x) < VMALLOC_END))
+
+/*
+ * Look up and return the pte corresponding to addr.  We only do this for
+ * agp_ioremap'ed addresses. 
+ */
+static pte_t *agp_lookup_pte(unsigned long addr)
+{ 
+	pgd_t			*dir;
+	pmd_t			*pmd;
+	pte_t			*pte;
+
+	if (!IN_VMALLOC(addr))
+		return NULL;
+
+	dir = pgd_offset_k(addr);
+	pmd = pmd_offset(dir, addr);
+
+	if (pmd) {
+		pte = pte_offset(pmd, addr);
+
+		if (pte) {
+			return pte;
+		} else {
+			return NULL;
+		}
+	} else {
+		return NULL;
+	}
+}
+
 #define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
 
 agp_memory *agp_allocate_memory(size_t page_count, u32 type)
@@ -262,18 +301,43 @@
 	      	MOD_DEC_USE_COUNT;
 		return NULL;
 	}
-	for (i = 0; i < page_count; i++) {
-		new->memory[i] = agp_bridge.agp_alloc_page();
 
-		if (new->memory[i] == 0) {
-			/* Free this structure */
-			agp_free_memory(new);
+	if (agp_bridge.cant_use_aperture) {
+		void *vmblock;
+		unsigned long vaddr;
+		pte_t *pte;
+
+		vmblock = __vmalloc(page_count << PAGE_SHIFT, GFP_KERNEL, PAGE_KERNEL);
+		if (vmblock == NULL) {
+			MOD_DEC_USE_COUNT;
 			return NULL;
 		}
-		new->memory[i] = virt_to_phys((void *) new->memory[i]);
-		new->page_count++;
-	}
+		new->vmptr = vmblock;
+		vaddr = (unsigned long) vmblock;
 
+		for (i = 0; i < page_count; i++, vaddr += PAGE_SIZE) {
+			pte = agp_lookup_pte(vaddr);
+			if (pte == NULL) {
+				MOD_DEC_USE_COUNT;
+				return NULL;
+			}
+			new->memory[i] = virt_to_phys(page_address(pte_page(*pte)));
+		}
+
+		new->page_count = page_count;
+	} else {
+		for (i = 0; i < page_count; i++) {
+			new->memory[i] = agp_bridge.agp_alloc_page();
+
+			if (new->memory[i] == 0) {
+				/* Free this structure */
+				agp_free_memory(new);
+				return NULL;
+			}
+			new->memory[i] = virt_to_phys((void *) new->memory[i]);
+			new->page_count++;
+		}
+	}
 	return new;
 }
 
@@ -286,26 +350,18 @@
 
 	temp = agp_bridge.current_size;
 
-	switch (agp_bridge.size_type) {
-	case U8_APER_SIZE:
+	if (agp_bridge.size_type == U8_APER_SIZE)
 		current_size = A_SIZE_8(temp)->size;
-		break;
-	case U16_APER_SIZE:
+	else if (agp_bridge.size_type ==  U16_APER_SIZE)
 		current_size = A_SIZE_16(temp)->size;
-		break;
-	case U32_APER_SIZE:
+	else if (agp_bridge.size_type ==  U32_APER_SIZE)
 		current_size = A_SIZE_32(temp)->size;
-		break;
-	case LVL2_APER_SIZE:
+	else if (agp_bridge.size_type ==  LVL2_APER_SIZE)
 		current_size = A_SIZE_LVL2(temp)->size;
-		break;
-	case FIXED_APER_SIZE:
+	else if (agp_bridge.size_type ==  FIXED_APER_SIZE)
 		current_size = A_SIZE_FIX(temp)->size;
-		break;
-	default:
+	else
 		current_size = 0;
-		break;
-	}
 
 	current_size -= (agp_memory_reserved / (1024*1024));
 
@@ -314,6 +370,9 @@
 
 /* Routine to copy over information structure */
 
+/* AGP bridge need not be PCI device, but DRM thinks it is. */
+static struct pci_dev fake_bridge_dev;
+
 int agp_copy_info(agp_kern_info * info)
 {
 	memset(info, 0, sizeof(agp_kern_info));
@@ -323,7 +382,7 @@
 	}
 	info->version.major = agp_bridge.version->major;
 	info->version.minor = agp_bridge.version->minor;
-	info->device = agp_bridge.dev;
+	info->device = agp_bridge.dev ? agp_bridge.dev : &fake_bridge_dev;
 	info->chipset = agp_bridge.type;
 	info->mode = agp_bridge.mode;
 	info->aper_base = agp_bridge.gart_bus_addr;
@@ -397,97 +456,104 @@
 
 /* Generic Agp routines - Start */
 
-static void agp_generic_agp_enable(u32 mode)
+static u32 agp_collect_device_status(u32 mode, u32 command)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch;
-	u8 cap_ptr;
-
-	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + 4,
-			      &command);
-
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
+	struct pci_dev *device;
+	u8 agp;
+	u32 scratch;
 
 	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
+		agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
+
+		/*
+		 * Ok, here we have a AGP device. Disable impossible 
+		 * settings, and adjust the readqueue to the minimum.
+		 */
+		pci_read_config_dword(device, agp + PCI_AGP_STATUS, &scratch);
 
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
+		/* adjust RQ depth */
+		command =
+		    ((command & ~0xff000000) |
+		     min_t(u32, (mode & 0xff000000),
+			 min_t(u32, (command & 0xff000000),
+			     (scratch & 0xff000000))));
+
+		/* disable SBA if it's not supported */
+		if (!((command & 0x00000200) &&
+		      (scratch & 0x00000200) &&
+		      (mode & 0x00000200)))
+			command &= ~0x00000200;
+
+		/* disable FW if it's not supported */
+		if (!((command & 0x00000010) &&
+		      (scratch & 0x00000010) &&
+		      (mode & 0x00000010)))
+			command &= ~0x00000010;
 
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x00000010) &&
-			      (scratch & 0x00000010) &&
-			      (mode & 0x00000010)))
-				command &= ~0x00000010;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
+		if (!((command & 4) &&
+		      (scratch & 4) &&
+		      (mode & 4)))
+			command &= ~0x00000004;
+
+		if (!((command & 2) &&
+		      (scratch & 2) &&
+		      (mode & 2)))
+			command &= ~0x00000002;
+
+		if (!((command & 1) &&
+		      (scratch & 1) &&
+		      (mode & 1)))
+			command &= ~0x00000001;
 	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
 
-	if (command & 4) {
+	if (command & 4)
 		command &= ~3;	/* 4X */
+	if (command & 2)
+		command &= ~5;	/* 2X (8X for AGP3.0) */
+	if (command & 1)
+		command &= ~6;	/* 1X (4X for AGP3.0) */
+
+	return command;
+}
+
+static void agp_device_command(u32 command, int agp_v3)
+{
+	struct pci_dev *device;
+	int mode;
+
+	mode = command & 0x7;
+	if (agp_v3)
+		mode *= 4;
+
+	pci_for_each_dev(device) {
+		u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
+		if (!agp)
+			continue;
+
+		printk(KERN_INFO PFX "Putting AGP V%d device at %s into %dx mode\n",
+				agp_v3 ? 3 : 2, device->slot_name, mode);
+		pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
 	}
-	if (command & 2) {
-		command &= ~5;	/* 2X */
-	}
-	if (command & 1) {
-		command &= ~6;	/* 1X */
-	}
+}
+
+static void agp_generic_agp_enable(u32 mode)
+{
+	u32 command;
+
+	pci_read_config_dword(agp_bridge.dev,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
+			      &command);
+
+	command = agp_collect_device_status(mode, command);
 	command |= 0x00000100;
 
 	pci_write_config_dword(agp_bridge.dev,
-			       agp_bridge.capndx + 8,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
 			       command);
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 0);
 }
 
 static int agp_generic_create_gatt_table(void)
@@ -1427,9 +1493,605 @@
 
 #endif /* CONFIG_AGP_I810 */
  
- #ifdef CONFIG_AGP_INTEL
+#ifdef CONFIG_AGP_I460
 
-#endif /* CONFIG_AGP_I810 */
+/* BIOS configures the chipset so that one of two apbase registers are used */
+static u8 intel_i460_dynamic_apbase = 0x10;
+
+/* 460 supports multiple GART page sizes, so GART pageshift is dynamic */ 
+static u8 intel_i460_pageshift = 12;
+static u32 intel_i460_pagesize;
+
+/* Keep track of which is larger, chipset or kernel page size. */
+static u32 intel_i460_cpk = 1;
+
+/* Structure for tracking partial use of 4MB GART pages */
+static u32 **i460_pg_detail = NULL;
+static u32 *i460_pg_count = NULL;
+
+#define I460_CPAGES_PER_KPAGE (PAGE_SIZE >> intel_i460_pageshift)
+#define I460_KPAGES_PER_CPAGE ((1 << intel_i460_pageshift) >> PAGE_SHIFT)
+
+#define I460_SRAM_IO_DISABLE		(1 << 4)
+#define I460_BAPBASE_ENABLE		(1 << 3)
+#define I460_AGPSIZ_MASK		0x7
+#define I460_4M_PS			(1 << 1)
+
+#define log2(x)				ffz(~(x))
+
+static gatt_mask intel_i460_masks[] =
+{
+	{ INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT, 0 }
+};
+
+static unsigned long intel_i460_mask_memory(unsigned long addr, int type) 
+{
+	/* Make sure the returned address is a valid GATT entry */
+	return (agp_bridge.masks[0].mask | (((addr & 
+		     ~((1 << intel_i460_pageshift) - 1)) & 0xffffff000) >> 12));
+}
+
+static unsigned long intel_i460_unmask_memory(unsigned long addr)
+{
+	/* Turn a GATT entry into a physical address */
+	return ((addr & 0xffffff) << 12);
+}
+
+static int intel_i460_fetch_size(void)
+{
+	int i;
+	u8 temp;
+	aper_size_info_8 *values;
+
+	/* Determine the GART page size */
+	pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &temp);
+	intel_i460_pageshift = (temp & I460_4M_PS) ? 22 : 12;
+	intel_i460_pagesize = 1UL << intel_i460_pageshift;
+
+	values = A_SIZE_8(agp_bridge.aperture_sizes);
+
+	pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp);
+
+	/* Exit now if the IO drivers for the GART SRAMS are turned off */
+	if (temp & I460_SRAM_IO_DISABLE) {
+		printk(KERN_WARNING PFX "GART SRAMS disabled on 460GX chipset\n");
+		printk(KERN_WARNING PFX "AGPGART operation not possible\n");
+		return 0;
+	}
+
+	/* Make sure we don't try to create an 2 ^ 23 entry GATT */
+	if ((intel_i460_pageshift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) {
+		printk(KERN_WARNING PFX "We can't have a 32GB aperture with 4KB"
+			" GART pages\n");
+		return 0;
+	}
+
+	/* Determine the proper APBASE register */
+	if (temp & I460_BAPBASE_ENABLE)
+		intel_i460_dynamic_apbase = INTEL_I460_BAPBASE;
+	else
+		intel_i460_dynamic_apbase = INTEL_I460_APBASE;
+
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+
+		/*
+		 * Dynamically calculate the proper num_entries and page_order 
+		 * values for the define aperture sizes. Take care not to
+		 * shift off the end of values[i].size.
+		 */	
+		values[i].num_entries = (values[i].size << 8) >>
+						(intel_i460_pageshift - 12);
+		values[i].page_order = log2((sizeof(u32)*values[i].num_entries)
+						>> PAGE_SHIFT);
+	}
+
+	for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+		/* Neglect control bits when matching up size_value */
+		if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
+			agp_bridge.previous_size =
+			    agp_bridge.current_size = (void *) (values + i);
+			agp_bridge.aperture_size_idx = i;
+			return values[i].size;
+		}
+	}
+
+	return 0;
+}
+
+/* There isn't anything to do here since 460 has no GART TLB. */ 
+static void intel_i460_tlb_flush(agp_memory * mem)
+{
+	return;
+}
+
+/*
+ * This utility function is needed to prevent corruption of the control bits
+ * which are stored along with the aperture size in 460's AGPSIZ register
+ */
+static void intel_i460_write_agpsiz(u8 size_value)
+{
+	u8 temp;
+
+	pci_read_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ, &temp);
+	pci_write_config_byte(agp_bridge.dev, INTEL_I460_AGPSIZ,
+		((temp & ~I460_AGPSIZ_MASK) | size_value));
+}
+
+static void intel_i460_cleanup(void)
+{
+	aper_size_info_8 *previous_size;
+
+	previous_size = A_SIZE_8(agp_bridge.previous_size);
+	intel_i460_write_agpsiz(previous_size->size_value);
+
+	if (intel_i460_cpk == 0) {
+		vfree(i460_pg_detail);
+		vfree(i460_pg_count);
+	}
+}
+
+
+/* Control bits for Out-Of-GART coherency and Burst Write Combining */
+#define I460_GXBCTL_OOG		(1UL << 0)
+#define I460_GXBCTL_BWC		(1UL << 2)
+
+static int intel_i460_configure(void)
+{
+	union {
+		u32 small[2];
+		u64 large;
+	} temp;
+	u8 scratch;
+	int i;
+
+	aper_size_info_8 *current_size;
+
+	temp.large = 0;
+
+	current_size = A_SIZE_8(agp_bridge.current_size);
+	intel_i460_write_agpsiz(current_size->size_value);	
+
+	/*
+	 * Do the necessary rigmarole to read all eight bytes of APBASE.
+	 * This has to be done since the AGP aperture can be above 4GB on
+	 * 460 based systems.
+	 */
+	pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase, 
+		&(temp.small[0]));
+	pci_read_config_dword(agp_bridge.dev, intel_i460_dynamic_apbase + 4,
+		&(temp.small[1]));
+
+	/* Clear BAR control bits */
+	agp_bridge.gart_bus_addr = temp.large & ~((1UL << 3) - 1); 
+
+	pci_read_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL, &scratch);
+	pci_write_config_byte(agp_bridge.dev, INTEL_I460_GXBCTL,
+			  (scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC);
+
+	/* 
+	 * Initialize partial allocation trackers if a GART page is bigger than
+	 * a kernel page.
+	 */
+	if (I460_CPAGES_PER_KPAGE >= 1) {
+		intel_i460_cpk = 1;
+	} else {
+		intel_i460_cpk = 0;
+
+		i460_pg_detail = (void *) vmalloc(sizeof(*i460_pg_detail) *
+					current_size->num_entries);
+		i460_pg_count = (void *) vmalloc(sizeof(*i460_pg_count) *
+					current_size->num_entries);
+	
+		for (i = 0; i < current_size->num_entries; i++) {
+			i460_pg_count[i] = 0;
+			i460_pg_detail[i] = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static int intel_i460_create_gatt_table(void) {
+
+	char *table;
+	int i;
+	int page_order;
+	int num_entries;
+	void *temp;
+	unsigned int read_back;
+
+	/*
+	 * Load up the fixed address of the GART SRAMS which hold our
+	 * GATT table.
+	 */
+	table = (char *) __va(INTEL_I460_ATTBASE);
+
+	temp = agp_bridge.current_size;
+	page_order = A_SIZE_8(temp)->page_order;
+	num_entries = A_SIZE_8(temp)->num_entries;
+
+	agp_bridge.gatt_table_real = (u32 *) table;
+	agp_bridge.gatt_table = ioremap_nocache(virt_to_phys(table),
+		 			     (PAGE_SIZE * (1 << page_order)));
+	agp_bridge.gatt_bus_addr = virt_to_phys(agp_bridge.gatt_table_real);
+
+	for (i = 0; i < num_entries; i++) {
+		agp_bridge.gatt_table[i] = 0;
+	}
+
+	/* 
+	 * The 460 spec says we have to read the last location written to 
+	 * make sure that all writes have taken effect
+	 */
+	read_back = agp_bridge.gatt_table[i - 1];
+
+	return 0;
+}
+
+static int intel_i460_free_gatt_table(void)
+{
+	int num_entries;
+	int i;
+	void *temp;
+	unsigned int read_back;
+
+	temp = agp_bridge.current_size;
+
+	num_entries = A_SIZE_8(temp)->num_entries;
+
+	for (i = 0; i < num_entries; i++) {
+		agp_bridge.gatt_table[i] = 0;
+	}
+	
+	/* 
+	 * The 460 spec says we have to read the last location written to 
+	 * make sure that all writes have taken effect
+	 */
+	read_back = agp_bridge.gatt_table[i - 1];
+
+	iounmap(agp_bridge.gatt_table);
+
+	return 0;
+}
+
+/* These functions are called when PAGE_SIZE exceeds the GART page size */	
+
+static int intel_i460_insert_memory_cpk(agp_memory * mem,
+				     off_t pg_start, int type)
+{
+	int i, j, k, num_entries;
+	void *temp;
+	unsigned long paddr;
+	unsigned int read_back;
+
+	/* 
+	 * The rest of the kernel will compute page offsets in terms of
+	 * PAGE_SIZE.
+	 */
+	pg_start = I460_CPAGES_PER_KPAGE * pg_start;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_8(temp)->num_entries;
+
+	if ((pg_start + I460_CPAGES_PER_KPAGE * mem->page_count) > num_entries) {
+		printk(KERN_WARNING PFX "Looks like we're out of AGP memory\n");
+		return -EINVAL;
+	}
+
+	j = pg_start;
+	while (j < (pg_start + I460_CPAGES_PER_KPAGE * mem->page_count)) {
+		if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+			return -EBUSY;
+		}
+		j++;
+	}
+
+	for (i = 0, j = pg_start; i < mem->page_count; i++) {
+
+		paddr = mem->memory[i];
+
+		for (k = 0; k < I460_CPAGES_PER_KPAGE; k++, j++, paddr += intel_i460_pagesize)
+			agp_bridge.gatt_table[j] = (unsigned int)
+			    agp_bridge.mask_memory(paddr, mem->type);
+	}
+
+	/* 
+	 * The 460 spec says we have to read the last location written to 
+	 * make sure that all writes have taken effect
+	 */
+	read_back = agp_bridge.gatt_table[j - 1];
+
+	return 0;
+}
+
+static int intel_i460_remove_memory_cpk(agp_memory * mem, off_t pg_start,
+				     int type)
+{
+	int i;
+	unsigned int read_back;
+
+	pg_start = I460_CPAGES_PER_KPAGE * pg_start;
+
+	for (i = pg_start; i < (pg_start + I460_CPAGES_PER_KPAGE * 
+							mem->page_count); i++) 
+		agp_bridge.gatt_table[i] = 0;
+
+	/* 
+	 * The 460 spec says we have to read the last location written to 
+	 * make sure that all writes have taken effect
+	 */
+	read_back = agp_bridge.gatt_table[i - 1];
+
+	return 0;
+}
+
+/*
+ * These functions are called when the GART page size exceeds PAGE_SIZE.
+ *
+ * This situation is interesting since AGP memory allocations that are
+ * smaller than a single GART page are possible.  The structures i460_pg_count
+ * and i460_pg_detail track partial allocation of the large GART pages to
+ * work around this issue.
+ *
+ * i460_pg_count[pg_num] tracks the number of kernel pages in use within
+ * GART page pg_num.  i460_pg_detail[pg_num] is an array containing a
+ * psuedo-GART entry for each of the aforementioned kernel pages.  The whole
+ * of i460_pg_detail is equivalent to a giant GATT with page size equal to
+ * that of the kernel.
+ */	
+
+static void *intel_i460_alloc_large_page(int pg_num)
+{
+	int i;
+	void *bp, *bp_end;
+	struct page *page;
+
+	i460_pg_detail[pg_num] = (void *) vmalloc(sizeof(u32) * 
+							I460_KPAGES_PER_CPAGE);
+	if (i460_pg_detail[pg_num] == NULL) {
+		printk(KERN_WARNING PFX "Out of memory, we're in trouble...\n");
+		return NULL;
+	}
+
+	for (i = 0; i < I460_KPAGES_PER_CPAGE; i++)
+		i460_pg_detail[pg_num][i] = 0;
+
+	bp = (void *) __get_free_pages(GFP_KERNEL, 
+					intel_i460_pageshift - PAGE_SHIFT);
+	if (bp == NULL) {
+		printk(KERN_WARNING PFX "Couldn't alloc 4M GART page...\n");
+		return NULL;
+	}
+
+	bp_end = bp + ((PAGE_SIZE * 
+			    (1 << (intel_i460_pageshift - PAGE_SHIFT))) - 1);
+
+	for (page = virt_to_page(bp); page <= virt_to_page(bp_end); page++) {
+		atomic_inc(&page->count);
+		set_bit(PG_locked, &page->flags);
+		atomic_inc(&agp_bridge.current_memory_agp);
+	}
+
+	return bp;		
+}
+
+static void intel_i460_free_large_page(int pg_num, unsigned long addr)
+{
+	struct page *page;
+	void *bp, *bp_end;
+
+	bp = (void *) __va(addr);
+	bp_end = bp + (PAGE_SIZE * 
+			(1 << (intel_i460_pageshift - PAGE_SHIFT)));
+
+	vfree(i460_pg_detail[pg_num]);
+	i460_pg_detail[pg_num] = NULL;
+
+	for (page = virt_to_page(bp); page < virt_to_page(bp_end); page++) {
+		put_page(page);
+		UnlockPage(page);
+		atomic_dec(&agp_bridge.current_memory_agp);
+	}
+
+	free_pages((unsigned long) bp, intel_i460_pageshift - PAGE_SHIFT);
+}
+	
+static int intel_i460_insert_memory_kpc(agp_memory * mem,
+				     off_t pg_start, int type)
+{
+	int i, pg, start_pg, end_pg, start_offset, end_offset, idx;
+	int num_entries;	
+	void *temp;
+	unsigned int read_back;
+	unsigned long paddr;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_8(temp)->num_entries;
+
+	/* Figure out what pg_start means in terms of our large GART pages */
+	start_pg 	= pg_start / I460_KPAGES_PER_CPAGE;
+	start_offset 	= pg_start % I460_KPAGES_PER_CPAGE;
+	end_pg 		= (pg_start + mem->page_count - 1) / 
+							I460_KPAGES_PER_CPAGE;
+	end_offset 	= (pg_start + mem->page_count - 1) % 
+							I460_KPAGES_PER_CPAGE;
+
+	if (end_pg > num_entries) {
+		printk(KERN_WARNING PFX "Looks like we're out of AGP memory\n");
+		return -EINVAL;
+	}
+
+	/* Check if the requested region of the aperture is free */
+	for (pg = start_pg; pg <= end_pg; pg++) {
+		/* Allocate new GART pages if necessary */
+		if (i460_pg_detail[pg] == NULL) {
+			temp = intel_i460_alloc_large_page(pg);
+			if (temp == NULL)
+				return -ENOMEM;
+			agp_bridge.gatt_table[pg] = agp_bridge.mask_memory(
+			    			       (unsigned long) temp, 0);
+			read_back = agp_bridge.gatt_table[pg];
+		}
+
+		for (idx = ((pg == start_pg) ? start_offset : 0);
+		     idx < ((pg == end_pg) ? (end_offset + 1) 
+				       : I460_KPAGES_PER_CPAGE);
+		     idx++) {
+			if(i460_pg_detail[pg][idx] != 0)
+				return -EBUSY;
+		}
+	}
+		
+	for (pg = start_pg, i = 0; pg <= end_pg; pg++) {
+		paddr = intel_i460_unmask_memory(agp_bridge.gatt_table[pg]);
+		for (idx = ((pg == start_pg) ? start_offset : 0);
+		     idx < ((pg == end_pg) ? (end_offset + 1)
+				       : I460_KPAGES_PER_CPAGE);
+		     idx++, i++) {
+			mem->memory[i] = paddr + (idx * PAGE_SIZE);
+			i460_pg_detail[pg][idx] =
+			    agp_bridge.mask_memory(mem->memory[i], mem->type);
+			    
+			i460_pg_count[pg]++;
+		}
+	}
+
+	return 0;
+}
+	
+static int intel_i460_remove_memory_kpc(agp_memory * mem,
+				     off_t pg_start, int type)
+{
+	int i, pg, start_pg, end_pg, start_offset, end_offset, idx;
+	int num_entries;
+	void *temp;
+	unsigned int read_back;
+	unsigned long paddr;
+
+	temp = agp_bridge.current_size;
+	num_entries = A_SIZE_8(temp)->num_entries;
+
+	/* Figure out what pg_start means in terms of our large GART pages */
+	start_pg 	= pg_start / I460_KPAGES_PER_CPAGE;
+	start_offset 	= pg_start % I460_KPAGES_PER_CPAGE;
+	end_pg 		= (pg_start + mem->page_count - 1) / 
+						I460_KPAGES_PER_CPAGE;
+	end_offset 	= (pg_start + mem->page_count - 1) % 
+						I460_KPAGES_PER_CPAGE;
+
+	for (i = 0, pg = start_pg; pg <= end_pg; pg++) {
+		for (idx = ((pg == start_pg) ? start_offset : 0);
+		     idx < ((pg == end_pg) ? (end_offset + 1)
+				       : I460_KPAGES_PER_CPAGE);
+		     idx++, i++) {
+			mem->memory[i] = 0;
+			i460_pg_detail[pg][idx] = 0;
+			i460_pg_count[pg]--;
+		}
+
+		/* Free GART pages if they are unused */
+		if (i460_pg_count[pg] == 0) {
+			paddr = intel_i460_unmask_memory(agp_bridge.gatt_table[pg]);
+			agp_bridge.gatt_table[pg] = agp_bridge.scratch_page;
+			read_back = agp_bridge.gatt_table[pg];
+
+			intel_i460_free_large_page(pg, paddr);
+		}
+	}
+		
+	return 0;
+}
+
+/* Dummy routines to call the approriate {cpk,kpc} function */
+
+static int intel_i460_insert_memory(agp_memory * mem,
+				     off_t pg_start, int type)
+{
+	if (intel_i460_cpk)
+		return intel_i460_insert_memory_cpk(mem, pg_start, type);
+	else
+		return intel_i460_insert_memory_kpc(mem, pg_start, type);
+}
+
+static int intel_i460_remove_memory(agp_memory * mem,
+				     off_t pg_start, int type)
+{
+	if (intel_i460_cpk)
+		return intel_i460_remove_memory_cpk(mem, pg_start, type);
+	else
+		return intel_i460_remove_memory_kpc(mem, pg_start, type);
+}
+
+/*
+ * If the kernel page size is smaller that the chipset page size, we don't
+ * want to allocate memory until we know where it is to be bound in the
+ * aperture (a multi-kernel-page alloc might fit inside of an already
+ * allocated GART page).  Consequently, don't allocate or free anything
+ * if i460_cpk (meaning chipset pages per kernel page) isn't set.
+ *
+ * Let's just hope nobody counts on the allocated AGP memory being there
+ * before bind time (I don't think current drivers do)...
+ */ 
+static unsigned long intel_i460_alloc_page(void)
+{
+	if (intel_i460_cpk)
+		return agp_generic_alloc_page();
+
+	/* Returning NULL would cause problems */
+	return ((unsigned long) ~0UL);
+}
+
+static void intel_i460_destroy_page(unsigned long page)
+{
+	if (intel_i460_cpk)
+		agp_generic_destroy_page(page);
+}
+
+static aper_size_info_8 intel_i460_sizes[3] =
+{
+	/* 
+	 * The 32GB aperture is only available with a 4M GART page size.
+	 * Due to the dynamic GART page size, we can't figure out page_order
+	 * or num_entries until runtime.
+	 */
+	{32768, 0, 0, 4},
+	{1024, 0, 0, 2},
+	{256, 0, 0, 1}
+};
+
+static int __init intel_i460_setup(struct pci_dev *pdev)
+{
+        agp_bridge.masks = intel_i460_masks;
+        agp_bridge.aperture_sizes = (void *) intel_i460_sizes;
+        agp_bridge.size_type = U8_APER_SIZE;
+        agp_bridge.num_aperture_sizes = 3;
+        agp_bridge.dev_private_data = NULL;
+        agp_bridge.needs_scratch_page = FALSE;
+        agp_bridge.configure = intel_i460_configure;
+        agp_bridge.fetch_size = intel_i460_fetch_size;
+        agp_bridge.cleanup = intel_i460_cleanup;
+        agp_bridge.tlb_flush = intel_i460_tlb_flush;
+        agp_bridge.mask_memory = intel_i460_mask_memory;
+        agp_bridge.agp_enable = agp_generic_agp_enable;
+        agp_bridge.cache_flush = global_cache_flush;
+        agp_bridge.create_gatt_table = intel_i460_create_gatt_table;
+        agp_bridge.free_gatt_table = intel_i460_free_gatt_table;
+        agp_bridge.insert_memory = intel_i460_insert_memory;
+        agp_bridge.remove_memory = intel_i460_remove_memory;
+        agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+        agp_bridge.free_by_type = agp_generic_free_by_type;
+        agp_bridge.agp_alloc_page = intel_i460_alloc_page;
+        agp_bridge.agp_destroy_page = intel_i460_destroy_page;
+        agp_bridge.suspend = agp_generic_suspend;
+        agp_bridge.resume = agp_generic_resume;
+        agp_bridge.cant_use_aperture = 1;
+
+        return 0;
+
+        (void) pdev; /* unused */
+}
+
+#endif		/* CONFIG_AGP_I460 */
 
 #ifdef CONFIG_AGP_INTEL
 
@@ -3068,7 +3730,6 @@
 	struct pci_dev *device = NULL;
 	u32 command, scratch; 
 	u8 cap_ptr;
-	u8 agp_v3;
 	u8 v3_devs=0;
 
 	/* FIXME: If 'mode' is x1/x2/x4 should we call the AGPv2 routines directly ?
@@ -3101,77 +3762,14 @@
 	}
 
 
-	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + 4, &command);
-
-	/*
-	 * PASS2: go through all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			printk (KERN_INFO "AGP: Setting up AGPv3 capable device at %d:%d:%d\n",
-					device->bus->number, PCI_FUNC(device->devfn), PCI_SLOT(device->devfn));
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
-			agp_v3 = (scratch & (1<<3) ) >>3;
-
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x200) && (scratch & 0x200) && (mode & 0x200)))
-				command &= ~0x200;
-
-			/* disable FW if it's not supported */
-			if (!((command & 0x10) && (scratch & 0x10) && (mode & 0x10)))
-				command &= ~0x10;
-
-			if (!((command & 2) && (scratch & 2) && (mode & 2))) {
-				command &= ~2;		/* 8x */
-				printk (KERN_INFO "AGP: Putting device into 8x mode\n");
-			}
-
-			if (!((command & 1) && (scratch & 1) && (mode & 1))) {
-				command &= ~1;		/* 4x */
-				printk (KERN_INFO "AGP: Putting device into 4x mode\n");
-			}
-		}
-	}
-	/*
-	 * PASS3: Figure out the 8X/4X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 2)
-		command &= ~5;	/* 8X */
-
-	if (command & 1)
-		command &= ~6;	/* 4X */
+	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx + PCI_AGP_STATUS, &command);
 
+	command = agp_collect_device_status(mode, command);
 	command |= 0x100;
 
-	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + 8, command);
-
-	/*
-	 * PASS4: Go through all AGP devices and update the
-	 *        command registers.
-	 */
+	pci_write_config_dword(agp_bridge.dev, agp_bridge.capndx + PCI_AGP_COMMAND, command);
 
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 1);
 }
 
 
@@ -3728,7 +4326,7 @@
 
 	/* Fill in the mode register */
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &agp_bridge.mode);
 
 	pci_read_config_byte(agp_bridge.dev,
@@ -3878,104 +4476,23 @@
 
 static void serverworks_agp_enable(u32 mode)
 {
-	struct pci_dev *device = NULL;
-	u32 command, scratch, cap_id;
-	u8 cap_ptr;
+	u32 command;
 
 	pci_read_config_dword(serverworks_private.svrwrks_dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &command);
 
-	/*
-	 * PASS1: go throu all devices that claim to be
-	 *        AGP devices and collect their data.
-	 */
-
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00) {
-			do {
-				pci_read_config_dword(device,
-						      cap_ptr, &cap_id);
-
-				if ((cap_id & 0xff) != 0x02)
-					cap_ptr = (cap_id >> 8) & 0xff;
-			}
-			while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
-		}
-		if (cap_ptr != 0x00) {
-			/*
-			 * Ok, here we have a AGP device. Disable impossible 
-			 * settings, and adjust the readqueue to the minimum.
-			 */
-
-			pci_read_config_dword(device, cap_ptr + 4, &scratch);
+	command = agp_collect_device_status(mode, command);
 
-			/* adjust RQ depth */
-			command =
-			    ((command & ~0xff000000) |
-			     min_t(u32, (mode & 0xff000000),
-				 min_t(u32, (command & 0xff000000),
-				     (scratch & 0xff000000))));
-
-			/* disable SBA if it's not supported */
-			if (!((command & 0x00000200) &&
-			      (scratch & 0x00000200) &&
-			      (mode & 0x00000200)))
-				command &= ~0x00000200;
-
-			/* disable FW */
-			command &= ~0x00000010;
-
-			command &= ~0x00000008;
-
-			if (!((command & 4) &&
-			      (scratch & 4) &&
-			      (mode & 4)))
-				command &= ~0x00000004;
-
-			if (!((command & 2) &&
-			      (scratch & 2) &&
-			      (mode & 2)))
-				command &= ~0x00000002;
-
-			if (!((command & 1) &&
-			      (scratch & 1) &&
-			      (mode & 1)))
-				command &= ~0x00000001;
-		}
-	}
-	/*
-	 * PASS2: Figure out the 4X/2X/1X setting and enable the
-	 *        target (our motherboard chipset).
-	 */
-
-	if (command & 4) {
-		command &= ~3;	/* 4X */
-	}
-	if (command & 2) {
-		command &= ~5;	/* 2X */
-	}
-	if (command & 1) {
-		command &= ~6;	/* 1X */
-	}
+	command &= ~0x00000010;	/* disable FW */
+	command &= ~0x00000008;
 	command |= 0x00000100;
 
 	pci_write_config_dword(serverworks_private.svrwrks_dev,
-			       agp_bridge.capndx + 8,
+			       agp_bridge.capndx + PCI_AGP_COMMAND,
 			       command);
 
-	/*
-	 * PASS3: Go throu all AGP devices and update the
-	 *        command registers.
-	 */
-
-	pci_for_each_dev(device) {
-		cap_ptr = pci_find_capability(device, PCI_CAP_ID_AGP);
-		if (cap_ptr != 0x00)
-			pci_write_config_dword(device, cap_ptr + 8, command);
-	}
+	agp_device_command(command, 0);
 }
 
 static int __init serverworks_setup (struct pci_dev *pdev)
@@ -4379,6 +4896,8 @@
 #define log2(x)		ffz(~(x))
 #endif
 
+#define HP_ZX1_IOC_OFFSET	0x1000  /* ACPI reports SBA, we want IOC */
+
 #define HP_ZX1_IOVA_BASE	GB(1UL)
 #define HP_ZX1_IOVA_SIZE	GB(1UL)
 #define HP_ZX1_GART_SIZE	(HP_ZX1_IOVA_SIZE / 2)
@@ -4393,14 +4912,9 @@
 	{0, 0, 0},		/* filled in by hp_zx1_fetch_size() */
 };
 
-static gatt_mask hp_zx1_masks[] =
-{
-	{HP_ZX1_PDIR_VALID_BIT, 0}
-};
-
 static struct _hp_private {
-	struct pci_dev *ioc;
-	volatile u8 *registers;
+	volatile u8 *ioc_regs;
+	volatile u8 *lba_regs;
 	u64 *io_pdir;		// PDIR for entire IOVA
 	u64 *gatt;		// PDIR just for GART (subset of above)
 	u64 gatt_entries;
@@ -4427,7 +4941,7 @@
 	 * 	- IOVA space is 1Gb in size
 	 * 	- first 512Mb is IOMMU, second 512Mb is GART
 	 */
-	hp->io_tlb_ps = INREG64(hp->registers, HP_ZX1_TCNFG);
+	hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG);
 	switch (hp->io_tlb_ps) {
 		case 0: hp->io_tlb_shift = 12; break;
 		case 1: hp->io_tlb_shift = 13; break;
@@ -4443,13 +4957,13 @@
 	hp->io_page_size = 1 << hp->io_tlb_shift;
 	hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
 
-	hp->iova_base = INREG64(hp->registers, HP_ZX1_IBASE) & ~0x1;
+	hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1;
 	hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
 
 	hp->gart_size = HP_ZX1_GART_SIZE;
 	hp->gatt_entries = hp->gart_size / hp->io_page_size;
 
-	hp->io_pdir = phys_to_virt(INREG64(hp->registers, HP_ZX1_PDIR_BASE));
+	hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
 	hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
 
 	if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
@@ -4463,7 +4977,7 @@
 	return 0;
 }
 
-static int __init hp_zx1_ioc_owner(u8 ioc_rev)
+static int __init hp_zx1_ioc_owner(void)
 {
 	struct _hp_private *hp = &hp_private;
 
@@ -4498,44 +5012,21 @@
 	return 0;
 }
 
-static int __init hp_zx1_ioc_init(void)
+static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa)
 {
 	struct _hp_private *hp = &hp_private;
-	struct pci_dev *ioc;
-	int i;
-	u8 ioc_rev;
 
-	ioc = pci_find_device(PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_ZX1_IOC, NULL);
-	if (!ioc) {
-		printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no IOC\n");
-		return -ENODEV;
-	}
-	hp->ioc = ioc;
-
-	pci_read_config_byte(ioc, PCI_REVISION_ID, &ioc_rev);
-
-	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		if (pci_resource_flags(ioc, i) == IORESOURCE_MEM) {
-			hp->registers = (u8 *) ioremap(pci_resource_start(ioc,
-									    i),
-						    pci_resource_len(ioc, i));
-			break;
-		}
-	}
-	if (!hp->registers) {
-		printk(KERN_ERR PFX "Detected HP ZX1 AGP bridge but no CSRs\n");
-
-		return -ENODEV;
-	}
+	hp->ioc_regs = ioremap(ioc_hpa, 1024);
+	hp->lba_regs = ioremap(lba_hpa, 256);
 
 	/*
 	 * If the IOTLB is currently disabled, we can take it over.
 	 * Otherwise, we have to share with sba_iommu.
 	 */
-	hp->io_pdir_owner = (INREG64(hp->registers, HP_ZX1_IBASE) & 0x1) == 0;
+	hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0;
 
 	if (hp->io_pdir_owner)
-		return hp_zx1_ioc_owner(ioc_rev);
+		return hp_zx1_ioc_owner();
 
 	return hp_zx1_ioc_shared();
 }
@@ -4555,19 +5046,17 @@
 	struct _hp_private *hp = &hp_private;
 
 	agp_bridge.gart_bus_addr = hp->gart_base;
-	agp_bridge.capndx = pci_find_capability(agp_bridge.dev, PCI_CAP_ID_AGP);
-	pci_read_config_dword(agp_bridge.dev,
-		agp_bridge.capndx + PCI_AGP_STATUS, &agp_bridge.mode);
+	agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
 
 	if (hp->io_pdir_owner) {
-		OUTREG64(hp->registers, HP_ZX1_PDIR_BASE,
+		OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE,
 			virt_to_phys(hp->io_pdir));
-		OUTREG64(hp->registers, HP_ZX1_TCNFG, hp->io_tlb_ps);
-		OUTREG64(hp->registers, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
-		OUTREG64(hp->registers, HP_ZX1_IBASE, hp->iova_base | 0x1);
-		OUTREG64(hp->registers, HP_ZX1_PCOM,
+		OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
+		OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
+		OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
+		OUTREG64(hp->ioc_regs, HP_ZX1_PCOM,
 			hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
-		INREG64(hp->registers, HP_ZX1_PCOM);
+		INREG64(hp->ioc_regs, HP_ZX1_PCOM);
 	}
 
 	return 0;
@@ -4578,17 +5067,18 @@
 	struct _hp_private *hp = &hp_private;
 
 	if (hp->io_pdir_owner)
-		OUTREG64(hp->registers, HP_ZX1_IBASE, 0);
-	iounmap((void *) hp->registers);
+		OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
+	iounmap((void *) hp->ioc_regs);
+	iounmap((void *) hp->lba_regs);
 }
 
 static void hp_zx1_tlbflush(agp_memory * mem)
 {
 	struct _hp_private *hp = &hp_private;
 
-	OUTREG64(hp->registers, HP_ZX1_PCOM, 
+	OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, 
 		hp->gart_base | log2(hp->gart_size));
-	INREG64(hp->registers, HP_ZX1_PCOM);
+	INREG64(hp->ioc_regs, HP_ZX1_PCOM);
 }
 
 static int hp_zx1_create_gatt_table(void)
@@ -4655,11 +5145,6 @@
 		j++;
 	}
 
-	if (mem->is_flushed == FALSE) {
-		CACHE_FLUSH();
-		mem->is_flushed = TRUE;
-	}
-
 	for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
 		unsigned long paddr;
 
@@ -4699,14 +5184,23 @@
 	return HP_ZX1_PDIR_VALID_BIT | addr;
 }
 
-static unsigned long hp_zx1_unmask_memory(unsigned long addr)
+static void hp_zx1_agp_enable(u32 mode)
 {
-	return addr & ~(HP_ZX1_PDIR_VALID_BIT);
+	struct _hp_private *hp = &hp_private;
+	u32 command;
+
+	command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
+
+	command = agp_collect_device_status(mode, command);
+	command |= 0x00000100;
+
+	OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command);
+
+	agp_device_command(command, 0);
 }
 
-static int __init hp_zx1_setup (struct pci_dev *pdev)
+static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa)
 {
-	agp_bridge.masks = hp_zx1_masks;
 	agp_bridge.dev_private_data = NULL;
 	agp_bridge.size_type = FIXED_APER_SIZE;
 	agp_bridge.needs_scratch_page = FALSE;
@@ -4715,8 +5209,7 @@
 	agp_bridge.cleanup = hp_zx1_cleanup;
 	agp_bridge.tlb_flush = hp_zx1_tlbflush;
 	agp_bridge.mask_memory = hp_zx1_mask_memory;
-	agp_bridge.unmask_memory = hp_zx1_unmask_memory;
-	agp_bridge.agp_enable = agp_generic_agp_enable;
+	agp_bridge.agp_enable = hp_zx1_agp_enable;
 	agp_bridge.cache_flush = global_cache_flush;
 	agp_bridge.create_gatt_table = hp_zx1_create_gatt_table;
 	agp_bridge.free_gatt_table = hp_zx1_free_gatt_table;
@@ -4727,12 +5220,65 @@
 	agp_bridge.agp_alloc_page = agp_generic_alloc_page;
 	agp_bridge.agp_destroy_page = agp_generic_destroy_page;
 	agp_bridge.cant_use_aperture = 1;
+	agp_bridge.type = HP_ZX1;
 
-	return hp_zx1_ioc_init();
+	fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
+	fake_bridge_dev.device = PCI_DEVICE_ID_HP_ZX1_LBA;
 
-	(void) pdev; /* unused */
+	return hp_zx1_ioc_init(ioc_hpa, lba_hpa);
 }
 
+static int __init acpi_hp_zx1_gart_add(struct acpi_device *device)
+{
+	acpi_handle handle, parent;
+	acpi_status status;
+	struct acpi_buffer buffer;
+	struct acpi_device_info *info;
+	u64 lba_hpa, sba_hpa, length;
+
+	status = acpi_hp_csr_space(device->handle, &lba_hpa, &length);
+	if (ACPI_FAILURE(status))
+		return 1;
+
+	/* Look for an enclosing IOC scope and find its CSR space */
+	handle = device->handle;
+	do {
+		buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+		status = acpi_get_object_info(handle, &info);
+		if (ACPI_SUCCESS(status)) {
+			/* TBD check _CID also */
+			info = buffer.pointer;
+			info->hardware_id.value[sizeof(info->hardware_id.value)-1] = '\0';
+			if (!strcmp(info->hardware_id.value, "HWP0001")) {
+				status = acpi_hp_csr_space(handle, &sba_hpa,
+						&length);
+				if (ACPI_SUCCESS(status))
+					break;
+				else {
+					printk(KERN_ERR PFX "Detected HP ZX1 "
+						"AGP LBA but no IOC.\n");
+					return 1;
+				}
+			}
+			ACPI_MEM_FREE(info);
+		}
+
+		status = acpi_get_parent(handle, &parent);
+		handle = parent;
+	} while (ACPI_SUCCESS(status));
+
+	if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
+		return 1;
+
+	return 0;
+}
+
+static struct acpi_driver acpi_hp_zx1_gart_driver = {
+	.name = "HP ZX1 GART Driver",
+	.ids  = "HWP0003",
+	.ops  = { .add = acpi_hp_zx1_gart_add },
+};
+
 #endif /* CONFIG_AGP_HP_ZX1 */
 
 /* per-chipset initialization data.
@@ -4951,6 +5497,15 @@
 
 #endif /* CONFIG_AGP_INTEL */
 
+#ifdef CONFIG_AGP_I460
+	{ PCI_DEVICE_ID_INTEL_460GX,
+		PCI_VENDOR_ID_INTEL,
+		INTEL_460GX,
+		"Intel",
+		"460GX",
+		intel_i460_setup },
+#endif
+
 #ifdef CONFIG_AGP_SIS
 	{ PCI_DEVICE_ID_SI_740,
 		PCI_VENDOR_ID_SI,
@@ -5158,15 +5713,6 @@
 		nvidia_generic_setup },
 #endif /* CONFIG_AGP_NVIDIA */
 
-#ifdef CONFIG_AGP_HP_ZX1
-	{ PCI_DEVICE_ID_HP_ZX1_LBA,
-		PCI_VENDOR_ID_HP,
-		HP_ZX1,
-		"HP",
-		"ZX1",
-		hp_zx1_setup },
-#endif
-
 	{ 0, }, /* dummy final entry, always present */
 };
 
@@ -5245,6 +5791,18 @@
 	return -ENODEV;
 }
 
+static int agp_check_supported_device(struct pci_dev *dev) {
+
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE (agp_bridge_info); i++) {
+		if (dev->vendor == agp_bridge_info[i].vendor_id &&
+		    dev->device == agp_bridge_info[i].device_id)
+			return 1;
+	}
+
+	return 0;
+}
 
 /* Supported Device Scanning routine */
 
@@ -5253,8 +5811,24 @@
 	struct pci_dev *dev = NULL;
 	u8 cap_ptr = 0x00;
 
-	if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) == NULL)
-		return -ENODEV;
+#ifdef CONFIG_AGP_HP_ZX1
+	int rc;
+
+	rc = acpi_bus_register_driver(&acpi_hp_zx1_gart_driver);
+	if (rc > 0) {
+		printk(KERN_INFO PFX "Detected an HP ZX1 Chipset.\n");
+		return 0;
+	}
+#endif
+
+	/* 
+	 * Some systems have multiple host bridges, so
+	 * we can't just use the first one we find.
+	 */
+	do {
+		if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, dev)) == NULL)
+			return -ENODEV;
+	} while (!agp_check_supported_device(dev));
 
 	agp_bridge.dev = dev;
 
@@ -5526,23 +6100,6 @@
 
 #endif	/* CONFIG_AGP_SWORKS */
 
-#ifdef CONFIG_AGP_HP_ZX1
-	if (dev->vendor == PCI_VENDOR_ID_HP) {
-		do {
-			/* ZX1 LBAs can be either PCI or AGP bridges */
-			if (pci_find_capability(dev, PCI_CAP_ID_AGP)) {
-				printk(KERN_INFO PFX "Detected HP ZX1 AGP "
-				       "chipset at %s\n", dev->slot_name);
-				agp_bridge.type = HP_ZX1;
-				agp_bridge.dev = dev;
-				return hp_zx1_setup(dev);
-			}
-			dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, dev);
-		} while (dev);
-		return -ENODEV;
-	}
-#endif	/* CONFIG_AGP_HP_ZX1 */
-
 	/* find capndx */
 	cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP);
 	if (cap_ptr == 0x00)
@@ -5551,7 +6108,7 @@
 
 	/* Fill in the mode register */
 	pci_read_config_dword(agp_bridge.dev,
-			      agp_bridge.capndx + 4,
+			      agp_bridge.capndx + PCI_AGP_STATUS,
 			      &agp_bridge.mode);
 
 	/* probe for known chipsets */
@@ -5753,7 +6310,8 @@
 
 	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
 	
-	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
+	if (agp_bridge.dev)
+		pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
 	return 0;
 }
 
diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile
--- a/drivers/net/Makefile	Wed Oct  8 09:06:06 2003
+++ b/drivers/net/Makefile	Wed Oct  8 09:06:06 2003
@@ -152,6 +152,7 @@
 obj-$(CONFIG_NE3210) += ne3210.o 8390.o
 obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
 obj-$(CONFIG_B44) += b44.o
+obj-$(CONFIG_HP_SIMETH) += simeth.o
 
 obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
 obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
diff -Nru a/fs/proc/base.c b/fs/proc/base.c
--- a/fs/proc/base.c	Wed Oct  8 09:06:06 2003
+++ b/fs/proc/base.c	Wed Oct  8 09:06:06 2003
@@ -473,7 +473,24 @@
 }
 #endif
 
+static loff_t mem_lseek(struct file * file, loff_t offset, int orig)
+{
+	switch (orig) {
+	      case 0:
+		file->f_pos = offset;
+		break;
+	      case 1:
+		file->f_pos += offset;
+		break;
+	      default:
+		return -EINVAL;
+	}
+	force_successful_syscall_return();
+	return file->f_pos;
+}
+
 static struct file_operations proc_mem_operations = {
+	llseek:		mem_lseek,
 	read:		mem_read,
 	write:		mem_write,
 	open:		mem_open,
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Wed Oct  8 09:06:06 2003
+++ b/fs/proc/proc_misc.c	Wed Oct  8 09:06:06 2003
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/seq_file.h>
+#include <linux/hugetlb.h>
 #include <linux/sysrq.h>
 
 #include <asm/uaccess.h>
@@ -207,6 +208,8 @@
 		K(i.freeram-i.freehigh),
 		K(i.totalswap),
 		K(i.freeswap));
+
+	len += hugetlb_report_meminfo(page + len);
 
 	return proc_calc_metrics(page, start, off, count, eof, len);
 #undef B
diff -Nru a/include/asm-i386/hw_irq.h b/include/asm-i386/hw_irq.h
--- a/include/asm-i386/hw_irq.h	Wed Oct  8 09:06:06 2003
+++ b/include/asm-i386/hw_irq.h	Wed Oct  8 09:06:06 2003
@@ -222,4 +222,6 @@
 static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {}
 #endif
 
+extern irq_desc_t irq_desc [NR_IRQS];
+
 #endif /* _ASM_HW_IRQ_H */
diff -Nru a/include/linux/pci_ids.h b/include/linux/pci_ids.h
--- a/include/linux/pci_ids.h	Wed Oct  8 09:06:06 2003
+++ b/include/linux/pci_ids.h	Wed Oct  8 09:06:06 2003
@@ -594,6 +594,7 @@
 #define PCI_DEVICE_ID_HP_ZX1_SBA	0x1229
 #define PCI_DEVICE_ID_HP_ZX1_IOC	0x122a
 #define PCI_DEVICE_ID_HP_ZX1_LBA	0x122e
+#define PCI_DEVICE_ID_HP_SX1000_IOC	0x127c
 
 #define PCI_VENDOR_ID_PCTECH		0x1042
 #define PCI_DEVICE_ID_PCTECH_RZ1000	0x1000
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c	Wed Oct  8 09:06:06 2003
+++ b/kernel/sysctl.c	Wed Oct  8 09:06:06 2003
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/sysrq.h>
 #include <linux/highuid.h>
+#include <linux/hugetlb.h>
 
 #include <asm/uaccess.h>
 
@@ -290,6 +291,10 @@
 	&vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MAX_MAP_COUNT, "max_map_count",
 	 &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
+#ifdef CONFIG_HUGETLB_PAGE
+	{VM_HUGETLB_PAGES, "nr_hugepages", &htlbpage_max, sizeof(int), 0644, NULL,
+	&hugetlb_sysctl_handler},
+#endif
 	{0}
 };