r2715 - in trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27: . debian
Dann Frazier
dannf@costa.debian.org
Tue, 15 Mar 2005 00:03:53 +0100
Author: dannf
Date: 2005-03-15 00:03:51 +0100 (Tue, 15 Mar 2005)
New Revision: 2715
Added:
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/linux-2.4.29-ia64-050312.diff
Removed:
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/ia64-unwind-fix.patch
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/nodebug.patch
Modified:
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/changelog
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/control
trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/rules
Log:
update to newer upstream arch patch
Modified: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/changelog
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/changelog 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/changelog 2005-03-14 23:03:51 UTC (rev 2715)
@@ -1,3 +1,11 @@
+kernel-patch-2.4.27-ia64 (2.4.27-3) unstable; urgency=high
+
+ * Update to a backported 2.4.29 ia64 patch
+ Supersedes: ia64-unwind-fix.patch, nodebug.patch
+ * Change maintainer to the kernel team and add me as an uploader
+
+ -- dann frazier <dannf@debian.org> Mon, 14 Mar 2005 10:49:25 -0700
+
kernel-patch-2.4.27-ia64 (2.4.27-2) unstable; urgency=high
* Add ia64-unwind-fix.patch - unw_unwind_to_user sanity check
Modified: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/control
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/control 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/control 2005-03-14 23:03:51 UTC (rev 2715)
@@ -1,8 +1,8 @@
Source: kernel-patch-2.4.27-ia64
Section: devel
Priority: extra
-Maintainer: dann frazier <dannf@debian.org>
-Uploaders: Bdale Garbee <bdale@gag.com>
+Maintainer: Debian Kernel Team <debian-kernel@lists.debian.org>
+Uploaders: dann frazier <dannf@hp.com>
Standards-Version: 3.5.10
Build-Depends-Indep: debhelper, dh-kpatches (>= 0.99.21), kernel-source-2.4.27
Modified: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/rules
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/rules 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/debian/rules 2005-03-14 23:03:51 UTC (rev 2715)
@@ -14,7 +14,7 @@
topdir=$(shell pwd)
destdir=${topdir}/debian/tmp
docdir=${destdir}/usr/share/doc/${PACKAGE}
-patches=lia64-bksnapshot-20040815.diff nodebug.patch ia64-unwind-fix.patch
+patches=linux-2.4.29-ia64-050312.diff
build: build-stamp
Deleted: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/ia64-unwind-fix.patch
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/ia64-unwind-fix.patch 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/ia64-unwind-fix.patch 2005-03-14 23:03:51 UTC (rev 2715)
@@ -1,22 +0,0 @@
-diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/unwind.c kernel-source-2.4.27/arch/ia64/kernel/unwind.c
---- kernel-source-2.4.27.orig/arch/ia64/kernel/unwind.c 2004-08-07 17:26:04.000000000 -0600
-+++ kernel-source-2.4.27/arch/ia64/kernel/unwind.c 2005-01-26 00:09:22.000000000 -0700
-@@ -1916,7 +1916,7 @@
- int
- unw_unwind_to_user (struct unw_frame_info *info)
- {
-- unsigned long ip;
-+ unsigned long ip, sp;
-
- while (unw_unwind(info) >= 0) {
- if (unw_get_rp(info, &ip) < 0) {
-@@ -1925,6 +1925,9 @@
- __FUNCTION__, ip);
- return -1;
- }
-+ unw_get_sp(info, &sp);
-+ if (sp >= (unsigned long)info->task + IA64_STK_OFFSET)
-+ break;
- /*
- * We don't have unwind info for the gate page, so we consider that part
- * of user-space for the purpose of unwinding.
Deleted: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff 2005-03-14 23:03:51 UTC (rev 2715)
@@ -1,5754 +0,0 @@
-diff -urN linux-2.4.27/Documentation/Configure.help /home/dannf/bk/linux-2.4-20040815/Documentation/Configure.help
---- linux-2.4.27/Documentation/Configure.help 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/Documentation/Configure.help 2004-08-15 05:15:06.000000000 -0600
-@@ -18773,6 +18773,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
-diff -urN linux-2.4.27/Documentation/vm/hugetlbpage.txt /home/dannf/bk/linux-2.4-20040815/Documentation/vm/hugetlbpage.txt
---- linux-2.4.27/Documentation/vm/hugetlbpage.txt 1969-12-31 17:00:00.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/Documentation/vm/hugetlbpage.txt 2004-08-15 05:06:29.000000000 -0600
-@@ -0,0 +1,217 @@
-+
-+The intent of this file is to give a brief summary of hugetlbpage support in
-+the Linux kernel. This support is built on top of multiple page size support
-+that is provided by most of modern architectures. For example, IA-32
-+architecture supports 4K and 4M (2M in PAE mode) page sizes, IA-64
-+architecture supports multiple page sizes 4K, 8K, 64K, 256K, 1M, 4M, 16M,
-+256M. A TLB is a cache of virtual-to-physical translations. Typically this
-+is a very scarce resource on processor. Operating systems try to make best
-+use of limited number of TLB resources. This optimization is more critical
-+now as bigger and bigger physical memories (several GBs) are more readily
-+available.
-+
-+Users can use the huge page support in Linux kernel by either using the mmap
-+system call or standard SYSv shared memory system calls (shmget, shmat).
-+
-+First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
-+under Processor types and feature) and CONFIG_HUGETLBFS (present under file
-+system option on config menu) config options.
-+
-+The kernel built with hugepage support should show the number of configured
-+hugepages in the system by running the "cat /proc/meminfo" command.
-+
-+/proc/meminfo also provides information about the total number of hugetlb
-+pages configured in the kernel. It also displays information about the
-+number of free hugetlb pages at any time. It also displays information about
-+the configured hugepage size - this is needed for generating the proper
-+alignment and size of the arguments to the above system calls.
-+
-+The output of "cat /proc/meminfo" will have output like:
-+
-+.....
-+HugePages_Total: xxx
-+HugePages_Free: yyy
-+Hugepagesize: zzz KB
-+
-+/proc/filesystems should also show a filesystem of type "hugetlbfs" configured
-+in the kernel.
-+
-+/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
-+pages in the kernel. Super user can dynamically request more (or free some
-+pre-configured) hugepages.
-+The allocation( or deallocation) of hugetlb pages is posible only if there are
-+enough physically contiguous free pages in system (freeing of hugepages is
-+possible only if there are enough hugetlb pages free that can be transfered
-+back to regular memory pool).
-+
-+Pages that are used as hugetlb pages are reserved inside the kernel and can
-+not be used for other purposes.
-+
-+Once the kernel with Hugetlb page support is built and running, a user can
-+use either the mmap system call or shared memory system calls to start using
-+the huge pages. It is required that the system administrator preallocate
-+enough memory for huge page purposes.
-+
-+Use the following command to dynamically allocate/deallocate hugepages:
-+
-+ echo 20 > /proc/sys/vm/nr_hugepages
-+
-+This command will try to configure 20 hugepages in the system. The success
-+or failure of allocation depends on the amount of physically contiguous
-+memory that is preset in system at this time. System administrators may want
-+to put this command in one of the local rc init file. This will enable the
-+kernel to request huge pages early in the boot process (when the possibility
-+of getting physical contiguous pages is still very high).
-+
-+If the user applications are going to request hugepages using mmap system
-+call, then it is required that system administrator mount a file system of
-+type hugetlbfs:
-+
-+ mount none /mnt/huge -t hugetlbfs <uid=value> <gid=value> <mode=value>
-+ <size=value> <nr_inodes=value>
-+
-+This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
-+/mnt/huge. Any files created on /mnt/huge use hugepages. The uid and gid
-+options set the owner and group of the root of the file system. By default
-+the uid and gid of the current process are taken. The mode option sets the
-+mode of root of file system to value & 0777. This value is given in octal.
-+By default the value 0755 is picked. The size option sets the maximum value of
-+memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
-+rounded down to HPAGE_SIZE. The option nr_inode sets the maximum number of
-+inodes that /mnt/huge can use. If the size or nr_inode options are not
-+provided on command line then no limits are set. For option size and option
-+nr_inodes, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
-+example, size=2K has the same meaning as size=2048. An example is given at
-+the end of this document.
-+
-+read and write system calls are not supported on files that reside on hugetlb
-+file systems.
-+
-+Regular chown, chgrp and chmod commands can be used to change the file
-+attributes on hugetlbfs.
-+
-+Also, it is important to note that no such mount command is required if the
-+applications are going to use only shmat/shmget system calls. It is possible
-+for same or different applications to use any combination of mmaps and shm*
-+calls. Though the mount of filesystem will be required for using mmaps.
-+
-+/* Example of using hugepage in user application using Sys V shared memory
-+ * system calls. In this example, app is requesting memory of size 256MB that
-+ * is backed by huge pages. Application uses the flag SHM_HUGETLB in shmget
-+ * system call to informt the kernel that it is requesting hugepages. For
-+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
-+ * That means the addresses starting with 0x800000....will need to be
-+ * specified.
-+ */
-+#include <sys/types.h>
-+#include <sys/shm.h>
-+#include <sys/types.h>
-+#include <sys/mman.h>
-+
-+extern int errno;
-+#define SHM_HUGETLB 04000
-+#define LPAGE_SIZE (256UL*1024UL*1024UL)
-+#define dprintf(x) printf(x)
-+#define ADDR (0x8000000000000000UL)
-+main()
-+{
-+ int shmid;
-+ int i, j, k;
-+ volatile char *shmaddr;
-+
-+ if ((shmid =shmget(2, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W ))
-+< 0) {
-+ perror("Failure:");
-+ exit(1);
-+ }
-+ printf("shmid: 0x%x\n", shmid);
-+ shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
-+ if (errno != 0) {
-+ perror("Shared Memory Attach Failure:");
-+ exit(2);
-+ }
-+ printf("shmaddr: %p\n", shmaddr);
-+
-+ dprintf("Starting the writes:\n");
-+ for (i=0;i<LPAGE_SIZE;i++) {
-+ shmaddr[i] = (char) (i);
-+ if (!(i%(1024*1024))) dprintf(".");
-+ }
-+ dprintf("\n");
-+ dprintf("Starting the Check...");
-+ for (i=0; i<LPAGE_SIZE;i++)
-+ if (shmaddr[i] != (char)i)
-+ printf("\nIndex %d mismatched.");
-+ dprintf("Done.\n");
-+ if (shmdt((const void *)shmaddr) != 0) {
-+ perror("Detached Failure:");
-+ exit (3);
-+ }
-+}
-+*******************************************************************
-+*******************************************************************
-+
-+
-+/* Example of using hugepage in user application using mmap
-+ * system call. Before running this application, make sure that
-+ * administrator has mounted the hugetlbfs (on some directory like /mnt) using
-+ * the command mount -t hugetlbfs nodev /mnt
-+ * In this example, app is requesting memory of size 256MB that
-+ * is backed by huge pages. Application uses the flag SHM_HUGETLB in shmget
-+ * system call to informt the kernel that it is requesting hugepages. For
-+ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
-+ * That means the addresses starting with 0x800000....will need to be
-+ * specified.
-+ */
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <sys/mman.h>
-+#include <fcntl.h>
-+
-+#define FILE_NAME "/mnt/hugepagefile"
-+#define LENGTH (256*1024*1024)
-+#define PROTECTION (PROT_READ | PROT_WRITE)
-+#define FLAGS MAP_SHARED |MAP_FIXED
-+#define ADDRESS (char *)(0x60000000UL + 0x8000000000000000UL)
-+
-+extern errno;
-+
-+check_bytes(char *addr)
-+{
-+ printf("First hex is %x\n", *((unsigned int *)addr));
-+}
-+
-+write_bytes(char *addr)
-+{
-+ int i;
-+ for (i=0;i<LENGTH;i++)
-+ *(addr+i)=(char)i;
-+}
-+read_bytes(char *addr)
-+{
-+ int i;
-+ check_bytes(addr);
-+ for (i=0;i<LENGTH;i++)
-+ if (*(addr+i)!=(char)i) {
-+ printf("Mismatch at %d\n", i);
-+ break;
-+ }
-+}
-+main()
-+{
-+ unsigned long addr = 0;
-+ int fd ;
-+
-+ fd = open(FILE_NAME, O_CREAT|O_RDWR, 0755);
-+ if (fd < 0) {
-+ perror("Open failed");
-+ exit(errno);
-+ }
-+ addr = (unsigned long)mmap(ADDRESS, LENGTH, PROTECTION, FLAGS, fd, 0);
-+ if (errno != 0)
-+ perror("mmap failed");
-+ printf("Returned address is %p\n", addr);
-+ check_bytes((char*)addr);
-+ write_bytes((char*)addr);
-+ read_bytes((char *)addr);
-+}
-diff -urN linux-2.4.27/Makefile /home/dannf/bk/linux-2.4-20040815/Makefile
---- linux-2.4.27/Makefile 2004-08-07 17:26:07.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/Makefile 2004-08-15 05:09:00.000000000 -0600
-@@ -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
-@@ -307,8 +308,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 -urN linux-2.4.27/arch/ia64/hp/common/sba_iommu.c /home/dannf/bk/linux-2.4-20040815/arch/ia64/hp/common/sba_iommu.c
---- linux-2.4.27/arch/ia64/hp/common/sba_iommu.c 2004-02-18 06:36:30.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/arch/ia64/hp/common/sba_iommu.c 2004-08-15 05:07:35.000000000 -0600
-@@ -447,6 +447,14 @@
-
- ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
- ASSERT(res_ptr < res_end);
-+
-+ /*
-+ * N.B. REO/Grande defect AR2305 can cause TLB fetch timeouts
-+ * if a TLB entry is purged while in use. sba_mark_invalid()
-+ * purges IOTLB entries in power-of-two sizes, so we also
-+ * allocate IOVA space in power-of-two sizes.
-+ */
-+ bits_wanted = 1UL << get_iovp_order(bits_wanted << PAGE_SHIFT);
- if (bits_wanted > (BITS_PER_LONG/2)) {
- /* Search word at a time - no mask needed */
- for(; res_ptr < res_end; ++res_ptr) {
-@@ -583,6 +591,7 @@
- unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
-
- int bits_not_wanted = size >> iovp_shift;
-+ bits_not_wanted = 1UL << get_iovp_order(bits_not_wanted << PAGE_SHIFT);
-
- /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
- unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
-diff -urN linux-2.4.27/arch/ia64/vmlinux.lds.S /home/dannf/bk/linux-2.4-20040815/arch/ia64/vmlinux.lds.S
---- linux-2.4.27/arch/ia64/vmlinux.lds.S 2003-08-25 05:44:39.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/arch/ia64/vmlinux.lds.S 2004-08-15 05:13:15.000000000 -0600
-@@ -7,6 +7,10 @@
- OUTPUT_FORMAT("elf64-ia64-little")
- OUTPUT_ARCH(ia64)
- ENTRY(phys_start)
-+PHDRS {
-+ code PT_LOAD;
-+ data PT_LOAD;
-+}
- SECTIONS
- {
- /* Sections to be discarded */
-@@ -23,6 +27,7 @@
- v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
- phys_start = _start - PAGE_OFFSET;
-
-+ code : { } :code
- . = KERNEL_START;
-
- _text = .;
-@@ -142,6 +147,7 @@
- .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET)
- { *(.kstrtab) }
-
-+ data : { } :data
- .data : AT(ADDR(.data) - PAGE_OFFSET)
- { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
-
-@@ -165,6 +171,7 @@
- . = ALIGN(64 / 8);
- _end = .;
-
-+ code : { } :code
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
-diff -urN linux-2.4.27/drivers/acpi/bus.c /home/dannf/bk/linux-2.4-20040815/drivers/acpi/bus.c
---- linux-2.4.27/drivers/acpi/bus.c 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/acpi/bus.c 2004-08-15 05:06:14.000000000 -0600
-@@ -1405,17 +1405,15 @@
- switch (type) {
- case ACPI_BUS_TYPE_DEVICE:
- result = acpi_bus_get_status(device);
-- if (result)
-- goto end;
-- break;
-+ if (!result)
-+ break;
-+ if (!device->status.present)
-+ result = -ENOENT;
-+ goto end;
- default:
- STRUCT_TO_INT(device->status) = 0x0F;
- break;
- }
-- if (!device->status.present) {
-- result = -ENOENT;
-- goto end;
-- }
-
- /*
- * Initialize Device
-diff -urN linux-2.4.27/drivers/char/Config.in /home/dannf/bk/linux-2.4-20040815/drivers/char/Config.in
---- linux-2.4.27/drivers/char/Config.in 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/Config.in 2004-08-15 04:55:24.000000000 -0600
-@@ -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
-diff -urN linux-2.4.27/drivers/char/agp/agp.h /home/dannf/bk/linux-2.4-20040815/drivers/char/agp/agp.h
---- linux-2.4.27/drivers/char/agp/agp.h 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/agp/agp.h 2004-08-15 05:01:53.000000000 -0600
-@@ -538,10 +538,6 @@
- #define HP_ZX1_TCNFG 0x318
- #define HP_ZX1_PDIR_BASE 0x320
-
--/* HP ZX1 LBA registers */
--#define HP_ZX1_AGP_STATUS 0x64
--#define HP_ZX1_AGP_COMMAND 0x68
--
- /* ATI register */
- #define ATI_APBASE 0x10
- #define ATI_GART_MMBASE_ADDR 0x14
-diff -urN linux-2.4.27/drivers/char/agp/agpgart_be.c /home/dannf/bk/linux-2.4-20040815/drivers/char/agp/agpgart_be.c
---- linux-2.4.27/drivers/char/agp/agpgart_be.c 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/agp/agpgart_be.c 2004-08-15 04:53:51.000000000 -0600
-@@ -45,6 +45,7 @@
- #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>
-@@ -217,10 +218,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);
-@@ -229,6 +234,8 @@
- MOD_DEC_USE_COUNT;
- }
-
-+#define IN_VMALLOC(_x) (((_x) >= VMALLOC_START) && ((_x) < VMALLOC_END))
-+
- #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
-
- agp_memory *agp_allocate_memory(size_t page_count, u32 type)
-@@ -263,18 +270,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;
-+ struct page *page;
-+
-+ 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) {
-+ page = vmalloc_to_page((void *) vaddr);
-+ if (!page) {
-+ MOD_DEC_USE_COUNT;
-+ return NULL;
-+ }
-+ new->memory[i] = virt_to_phys(page_address(page));
-+ }
-+
-+ 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;
- }
-
-@@ -287,26 +319,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));
-
-@@ -315,6 +339,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));
-@@ -324,7 +351,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;
-@@ -398,97 +425,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;
-+ struct pci_dev *device;
-+ u8 agp;
-+ u32 scratch;
-
-- pci_read_config_dword(agp_bridge.dev,
-- agp_bridge.capndx + 4,
-- &command);
-+ pci_for_each_dev(device) {
-+ agp = pci_find_capability(device, PCI_CAP_ID_AGP);
-+ if (!agp)
-+ continue;
-
-- /*
-- * PASS1: go throu all devices that claim to be
-- * AGP devices and collect their data.
-- */
-+ /*
-+ * 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);
-
-+ /* 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;
-
-- 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.
-- */
--
-- 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;
--
-- 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)
-@@ -3641,7 +3675,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 ?
-@@ -3674,77 +3707,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);
- }
-
-
-@@ -4457,7 +4427,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,
-@@ -4607,104 +4577,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);
--
-- /* 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).
-- */
-+ command = agp_collect_device_status(mode, command);
-
-- 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)
-@@ -5131,6 +5020,7 @@
- static struct _hp_private {
- volatile u8 *ioc_regs;
- volatile u8 *lba_regs;
-+ int lba_cap_offset;
- u64 *io_pdir; // PDIR for entire IOVA
- u64 *gatt; // PDIR just for GART (subset of above)
- u64 gatt_entries;
-@@ -5183,6 +5073,7 @@
- hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
-
- if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
-+ /* Normal case when no AGP device in system */
- hp->gatt = 0;
- hp->gatt_entries = 0;
- printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
-@@ -5228,12 +5119,13 @@
- return 0;
- }
-
--static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa)
-+static int __init hp_zx1_ioc_init(u64 hpa)
- {
- struct _hp_private *hp = &hp_private;
-
-- hp->ioc_regs = ioremap(ioc_hpa, 1024);
-- hp->lba_regs = ioremap(lba_hpa, 256);
-+ hp->ioc_regs = ioremap(hpa, 1024);
-+ if (!hp->ioc_regs)
-+ return -ENOMEM;
-
- /*
- * If the IOTLB is currently disabled, we can take it over.
-@@ -5247,6 +5139,50 @@
- return hp_zx1_ioc_shared();
- }
-
-+static int
-+hp_zx1_lba_find_capability(volatile u8 *hpa, int cap)
-+{
-+ u16 status;
-+ u8 pos, id;
-+ int ttl = 48;
-+
-+ status = INREG16(hpa, PCI_STATUS);
-+ if (!(status & PCI_STATUS_CAP_LIST))
-+ return 0;
-+ pos = INREG8(hpa, PCI_CAPABILITY_LIST);
-+ while (ttl-- && pos >= 0x40) {
-+ pos &= ~3;
-+ id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
-+ if (id == 0xff)
-+ break;
-+ if (id == cap)
-+ return pos;
-+ pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
-+ }
-+ return 0;
-+}
-+
-+static int __init hp_zx1_lba_init(u64 hpa)
-+{
-+ struct _hp_private *hp = &hp_private;
-+ int cap;
-+
-+ hp->lba_regs = ioremap(hpa, 256);
-+ if (!hp->lba_regs)
-+ return -ENOMEM;
-+
-+ hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
-+
-+ cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
-+ if (cap != PCI_CAP_ID_AGP) {
-+ printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
-+ cap, hp->lba_cap_offset);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
- static int hp_zx1_fetch_size(void)
- {
- int size;
-@@ -5262,7 +5198,7 @@
- struct _hp_private *hp = &hp_private;
-
- agp_bridge.gart_bus_addr = hp->gart_base;
-- agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
-+ agp_bridge.mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
-
- if (hp->io_pdir_owner) {
- OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE,
-@@ -5282,10 +5218,13 @@
- {
- struct _hp_private *hp = &hp_private;
-
-- if (hp->io_pdir_owner)
-- OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
-- iounmap((void *) hp->ioc_regs);
-- iounmap((void *) hp->lba_regs);
-+ if (hp->ioc_regs) {
-+ if (hp->io_pdir_owner)
-+ OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
-+ iounmap((void *) hp->ioc_regs);
-+ }
-+ if (hp->lba_regs)
-+ iounmap((void *) hp->lba_regs);
- }
-
- static void hp_zx1_tlbflush(agp_memory * mem)
-@@ -5405,18 +5344,23 @@
- struct _hp_private *hp = &hp_private;
- u32 command;
-
-- command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
-+ command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
-
- command = agp_collect_device_status(mode, command);
- command |= 0x00000100;
-
-- OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command);
-+ OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
-
- agp_device_command(command, 0);
- }
-
- static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa)
- {
-+ struct _hp_private *hp = &hp_private;
-+ int error;
-+
-+ memset(hp, 0, sizeof(*hp));
-+
- agp_bridge.dev_private_data = NULL;
- agp_bridge.size_type = FIXED_APER_SIZE;
- agp_bridge.needs_scratch_page = FALSE;
-@@ -5441,7 +5385,16 @@
- fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
- fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
-
-- return hp_zx1_ioc_init(ioc_hpa, lba_hpa);
-+ error = hp_zx1_ioc_init(ioc_hpa);
-+ if (error)
-+ goto fail;
-+
-+ error = hp_zx1_lba_init(lba_hpa);
-+
-+fail:
-+ if (error)
-+ hp_zx1_cleanup();
-+ return error;
- }
-
- static acpi_status __init hp_zx1_gart_probe(acpi_handle obj, u32 depth, void *context, void **ret)
-@@ -5455,7 +5408,7 @@
-
- status = acpi_hp_csr_space(obj, &lba_hpa, &length);
- if (ACPI_FAILURE(status))
-- return AE_OK;
-+ return AE_OK; /* keep looking for another bridge */
-
- /* Look for an enclosing IOC scope and find its CSR space */
- handle = obj;
-@@ -5491,7 +5444,7 @@
- (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
-
- hp_zx1_gart_found = 1;
-- return AE_CTRL_TERMINATE;
-+ return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
- }
-
- static int __init
-@@ -6473,7 +6426,6 @@
- "IGP9100/M",
- ati_generic_setup },
- #endif /* CONFIG_AGP_ATI */
--
- { 0, }, /* dummy final entry, always present */
- };
-
-@@ -6556,7 +6508,6 @@
- return -ENODEV;
- }
-
--
- /* Supported Device Scanning routine */
-
- static int __init agp_find_supported_device(void)
-@@ -6884,7 +6835,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 */
-@@ -7102,7 +7053,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 -urN linux-2.4.27/drivers/char/drm/drm_bufs.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_bufs.h
---- linux-2.4.27/drivers/char/drm/drm_bufs.h 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_bufs.h 2004-08-15 04:55:51.000000000 -0600
-@@ -106,7 +106,7 @@
- switch ( map->type ) {
- case _DRM_REGISTERS:
- case _DRM_FRAME_BUFFER:
--#if !defined(__sparc__) && !defined(__alpha__)
-+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
- if ( map->offset + map->size < map->offset ||
- map->offset < virt_to_phys(high_memory) ) {
- DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
-diff -urN linux-2.4.27/drivers/char/drm/drm_memory.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_memory.h
---- linux-2.4.27/drivers/char/drm/drm_memory.h 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_memory.h 2004-08-15 04:54:32.000000000 -0600
-@@ -293,6 +293,11 @@
- void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
- {
- void *pt;
-+#if __REALLY_HAVE_AGP
-+ drm_map_t *map = NULL;
-+ drm_map_list_t *r_list;
-+ struct list_head *list;
-+#endif
-
- if (!size) {
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
-@@ -300,12 +305,50 @@
- return NULL;
- }
-
-+#if __REALLY_HAVE_AGP
-+ if (!dev->agp || dev->agp->cant_use_aperture == 0)
-+ goto standard_ioremap;
-+
-+ list_for_each(list, &dev->maplist->head) {
-+ r_list = (drm_map_list_t *)list;
-+ map = r_list->map;
-+ if (!map) continue;
-+ if (map->offset <= offset &&
-+ (map->offset + map->size) >= (offset + size))
-+ break;
-+ }
-+
-+ if (map && map->type == _DRM_AGP) {
-+ struct drm_agp_mem *agpmem;
-+
-+ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
-+ if (agpmem->bound <= offset &&
-+ (agpmem->bound + (agpmem->pages
-+ << PAGE_SHIFT)) >= (offset + size))
-+ break;
-+ }
-+
-+ if (agpmem == NULL)
-+ goto ioremap_failure;
-+
-+ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
-+ goto ioremap_success;
-+ }
-+
-+standard_ioremap:
-+#endif
- if (!(pt = ioremap(offset, size))) {
-+#if __REALLY_HAVE_AGP
-+ioremap_failure:
-+#endif
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- spin_unlock(&DRM(mem_lock));
- return NULL;
- }
-+#if __REALLY_HAVE_AGP
-+ioremap_success:
-+#endif
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
-@@ -316,6 +359,11 @@
- void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
- {
- void *pt;
-+#if __REALLY_HAVE_AGP
-+ drm_map_t *map = NULL;
-+ drm_map_list_t *r_list;
-+ struct list_head *list;
-+#endif
-
- if (!size) {
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
-@@ -323,12 +371,50 @@
- return NULL;
- }
-
-+#if __REALLY_HAVE_AGP
-+ if (!dev->agp || dev->agp->cant_use_aperture == 0)
-+ goto standard_ioremap;
-+
-+ list_for_each(list, &dev->maplist->head) {
-+ r_list = (drm_map_list_t *)list;
-+ map = r_list->map;
-+ if (!map) continue;
-+ if (map->offset <= offset &&
-+ (map->offset + map->size) >= (offset + size))
-+ break;
-+ }
-+
-+ if (map && map->type == _DRM_AGP) {
-+ struct drm_agp_mem *agpmem;
-+
-+ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
-+ if (agpmem->bound <= offset &&
-+ (agpmem->bound + (agpmem->pages
-+ << PAGE_SHIFT)) >= (offset + size))
-+ break;
-+ }
-+
-+ if (agpmem == NULL)
-+ goto ioremap_failure;
-+
-+ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
-+ goto ioremap_success;
-+ }
-+
-+standard_ioremap:
-+#endif
- if (!(pt = ioremap_nocache(offset, size))) {
-+#if __REALLY_HAVE_AGP
-+ioremap_failure:
-+#endif
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
- spin_unlock(&DRM(mem_lock));
- return NULL;
- }
-+#if __REALLY_HAVE_AGP
-+ioremap_success:
-+#endif
- spin_lock(&DRM(mem_lock));
- ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
- DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
-@@ -344,7 +430,11 @@
- if (!pt)
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Attempt to free NULL pointer\n");
-+#if __REALLY_HAVE_AGP
-+ else if (!dev->agp || dev->agp->cant_use_aperture == 0)
-+#else
- else
-+#endif
- iounmap(pt);
-
- spin_lock(&DRM(mem_lock));
-diff -urN linux-2.4.27/drivers/char/drm/drm_vm.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_vm.h
---- linux-2.4.27/drivers/char/drm/drm_vm.h 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/drm_vm.h 2004-08-15 05:17:28.000000000 -0600
-@@ -368,6 +368,7 @@
- drm_map_list_t *r_list;
- unsigned long offset = 0;
- struct list_head *list;
-+ struct page *page;
-
- DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, VM_OFFSET(vma));
-@@ -414,28 +415,30 @@
-
- switch (map->type) {
- case _DRM_AGP:
--#if defined(__alpha__)
-- /*
-- * On Alpha we can't talk to bus dma address from the
-- * CPU, so for memory of type DRM_AGP, we'll deal with
-- * sorting out the real physical pages and mappings
-- * in nopage()
-- */
-- vma->vm_ops = &DRM(vm_ops);
-- break;
-+#if __REALLY_HAVE_AGP
-+ if (dev->agp->cant_use_aperture) {
-+ /*
-+ * On some systems we can't talk to bus dma address from
-+ * the CPU, so for memory of type DRM_AGP, we'll deal
-+ * with sorting out the real physical pages and mappings
-+ * in nopage()
-+ */
-+ vma->vm_ops = &DRM(vm_ops);
-+ goto mapswitch_out;
-+ }
- #endif
- /* fall through to _DRM_FRAME_BUFFER... */
- case _DRM_FRAME_BUFFER:
- case _DRM_REGISTERS:
-- if (VM_OFFSET(vma) >= __pa(high_memory)) {
-+ page = virt_to_page(__va(VM_OFFSET(vma)));
-+ if (!VALID_PAGE(page) || PageReserved(page)) {
- #if defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
- pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
- }
- #elif defined(__ia64__)
-- if (map->type != _DRM_AGP)
-- vma->vm_page_prot =
-+ vma->vm_page_prot =
- pgprot_writecombine(vma->vm_page_prot);
- #elif defined(__powerpc__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-@@ -474,6 +477,9 @@
- default:
- return -EINVAL; /* This should never happen. */
- }
-+#if __REALLY_HAVE_AGP
-+mapswitch_out:
-+#endif
- vma->vm_flags |= VM_RESERVED; /* Don't swap */
-
- vma->vm_file = filp; /* Needed for drm_vm_open() */
-diff -urN linux-2.4.27/drivers/char/drm/r128_cce.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/r128_cce.c
---- linux-2.4.27/drivers/char/drm/r128_cce.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/r128_cce.c 2004-08-15 04:54:01.000000000 -0600
-@@ -216,7 +216,22 @@
- int i;
-
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-+#ifndef CONFIG_AGP_I460
- if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) {
-+#else
-+ /*
-+ * XXX - this is (I think) a 460GX specific hack
-+ *
-+ * When doing texturing, ring.tail sometimes gets ahead of
-+ * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes
-+ * its whole quota of instructions and *ring.head is still 2
-+ * short of ring.tail. Work around this for now in lieu of
-+ * a better solution.
-+ */
-+ if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ||
-+ ( dev_priv->ring.tail -
-+ GET_RING_HEAD( &dev_priv->ring ) ) == 2 ) {
-+#endif
- int pm4stat = R128_READ( R128_PM4_STAT );
- if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
- dev_priv->cce_fifo_size ) &&
-@@ -317,7 +332,7 @@
- static void r128_cce_init_ring_buffer( drm_device_t *dev,
- drm_r128_private_t *dev_priv )
- {
-- u32 ring_start;
-+ u32 ring_start, rptr_addr;
- u32 tmp;
-
- DRM_DEBUG( "\n" );
-@@ -341,8 +356,24 @@
- SET_RING_HEAD( &dev_priv->ring, 0 );
-
- if ( !dev_priv->is_pci ) {
-- R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
-- dev_priv->ring_rptr->offset );
-+ /*
-+ * 460GX doesn't claim PCI writes from the card into
-+ * the AGP aperture, so we have to get space outside
-+ * the aperture for RPTR_ADDR.
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off;
-+
-+ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
-+ atomic_inc(&virt_to_page(alt_rh_off)->count);
-+ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+
-+ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
-+ SET_RING_HEAD( &dev_priv->ring, 0 );
-+ rptr_addr = __pa( dev_priv->ring.head );
-+ } else
-+ rptr_addr = dev_priv->ring_rptr->offset;
-+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr );
- } else {
- drm_sg_mem_t *entry = dev->sg;
- unsigned long tmp_ofs, page_ofs;
-@@ -629,7 +660,19 @@
- DRM_ERROR( "failed to cleanup PCI GART!\n" );
- }
- #endif
--
-+ /*
-+ * Free the page we grabbed for RPTR_ADDR
-+ */
-+ if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off =
-+ (unsigned long) dev_priv->ring.head;
-+ struct page *p = virt_to_page((void *)alt_rh_off);
-+
-+ put_page(p);
-+ unlock_page(p);
-+ free_page(alt_rh_off);
-+ }
-+
- DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
- DRM_MEM_DRIVER );
- dev->dev_private = NULL;
-diff -urN linux-2.4.27/drivers/char/drm/radeon_cp.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/radeon_cp.c
---- linux-2.4.27/drivers/char/drm/radeon_cp.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm/radeon_cp.c 2004-08-15 04:54:56.000000000 -0600
-@@ -854,7 +854,7 @@
- static void radeon_cp_init_ring_buffer( drm_device_t *dev,
- drm_radeon_private_t *dev_priv )
- {
-- u32 ring_start, cur_read_ptr;
-+ u32 ring_start, cur_read_ptr, rptr_addr;
- u32 tmp;
-
- /* Initialize the memory controller */
-@@ -892,8 +892,24 @@
- dev_priv->ring.tail = cur_read_ptr;
-
- if ( !dev_priv->is_pci ) {
-- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
-- dev_priv->ring_rptr->offset );
-+ /*
-+ * 460GX doesn't claim PCI writes from the card into
-+ * the AGP aperture, so we have to get space outside
-+ * the aperture for RPTR_ADDR.
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off;
-+
-+ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
-+ atomic_inc(&virt_to_page(alt_rh_off)->count);
-+ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+
-+ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
-+ *dev_priv->ring.head = cur_read_ptr;
-+ rptr_addr = __pa( dev_priv->ring.head );
-+ } else
-+ rptr_addr = dev_priv->ring_rptr->offset;
-+ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr );
- } else {
- drm_sg_mem_t *entry = dev->sg;
- unsigned long tmp_ofs, page_ofs;
-@@ -1278,6 +1294,19 @@
- #endif /* __REALLY_HAVE_SG */
- }
-
-+ /*
-+ * Free the page we grabbed for RPTR_ADDR
-+ */
-+ if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off =
-+ (unsigned long) dev_priv->ring.head;
-+ struct page *p = virt_to_page((void *)alt_rh_off);
-+
-+ put_page(p);
-+ unlock_page(p);
-+ free_page(alt_rh_off);
-+ }
-+
- DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
- DRM_MEM_DRIVER );
- dev->dev_private = NULL;
-diff -urN linux-2.4.27/drivers/char/drm-4.0/agpsupport.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/agpsupport.c
---- linux-2.4.27/drivers/char/drm-4.0/agpsupport.c 2003-11-28 11:26:20.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/agpsupport.c 2004-08-15 05:12:35.000000000 -0600
-@@ -30,6 +30,7 @@
-
- #define __NO_VERSION__
- #include "drmP.h"
-+#include <linux/config.h>
- #include <linux/module.h>
- #if LINUX_VERSION_CODE < 0x020400
- #include "agpsupport-pre24.h"
-@@ -305,6 +306,13 @@
-
- default: head->chipset = "Unknown"; break;
- }
-+#if LINUX_VERSION_CODE <= 0x020408
-+ head->cant_use_aperture = 0;
-+ head->page_mask = ~(0xfff);
-+#else
-+ head->cant_use_aperture = head->agp_info.cant_use_aperture;
-+ head->page_mask = head->agp_info.page_mask;
-+#endif
- DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
- head->agp_info.version.major,
- head->agp_info.version.minor,
-diff -urN linux-2.4.27/drivers/char/drm-4.0/bufs.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/bufs.c
---- linux-2.4.27/drivers/char/drm-4.0/bufs.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/bufs.c 2004-08-15 04:50:46.000000000 -0600
-@@ -73,7 +73,7 @@
- switch (map->type) {
- case _DRM_REGISTERS:
- case _DRM_FRAME_BUFFER:
--#ifndef __sparc__
-+#if !defined(__sparc__) && !defined(__ia64__)
- if (map->offset + map->size < map->offset
- || map->offset < virt_to_phys(high_memory)) {
- drm_free(map, sizeof(*map), DRM_MEM_MAPS);
-diff -urN linux-2.4.27/drivers/char/drm-4.0/drmP.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/drmP.h
---- linux-2.4.27/drivers/char/drm-4.0/drmP.h 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/drmP.h 2004-08-15 05:02:39.000000000 -0600
-@@ -510,6 +510,8 @@
- int acquired;
- unsigned long base;
- int agp_mtrr;
-+ int cant_use_aperture;
-+ unsigned long page_mask;
- } drm_agp_head_t;
- #endif
-
-diff -urN linux-2.4.27/drivers/char/drm-4.0/memory.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/memory.c
---- linux-2.4.27/drivers/char/drm-4.0/memory.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/memory.c 2004-08-15 05:14:15.000000000 -0600
-@@ -306,12 +306,44 @@
- return NULL;
- }
-
-+ if (dev->agp->cant_use_aperture) {
-+ drm_map_t *map = NULL;
-+ int i;
-+
-+ for (i = 0; i < dev->map_count; i++) {
-+ map = dev->maplist[i];
-+ if (!map) continue;
-+ if (map->offset <= offset &&
-+ (map->offset + map->size) >= (offset + size))
-+ break;
-+ }
-+
-+ if (map && map->type == _DRM_AGP) {
-+ struct drm_agp_mem *agpmem;
-+
-+ for (agpmem = dev->agp->memory; agpmem;
-+ agpmem = agpmem->next) {
-+ if(agpmem->bound <= offset &&
-+ (agpmem->bound + (agpmem->pages
-+ << PAGE_SHIFT)) >= (offset + size))
-+ break;
-+ }
-+
-+ if (agpmem) {
-+ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
-+ goto ioremap_success;
-+ }
-+ }
-+ }
-+
- if (!(pt = ioremap(offset, size))) {
- spin_lock(&drm_mem_lock);
- ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
- spin_unlock(&drm_mem_lock);
- return NULL;
- }
-+
-+ioremap_success:
- spin_lock(&drm_mem_lock);
- ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
- drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
-@@ -327,7 +359,7 @@
- if (!pt)
- DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
- "Attempt to free NULL pointer\n");
-- else
-+ else if (dev->agp->cant_use_aperture == 0)
- iounmap(pt);
-
- spin_lock(&drm_mem_lock);
-diff -urN linux-2.4.27/drivers/char/drm-4.0/mga_dma.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/mga_dma.c
---- linux-2.4.27/drivers/char/drm-4.0/mga_dma.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/mga_dma.c 2004-08-15 05:06:04.000000000 -0600
-@@ -741,10 +741,18 @@
- return -ENOMEM;
- }
-
-- /* Write status page when secend or softrap occurs */
-+ /* Write status page when secend or softrap occurs
-+ *
-+ * Disable this on ia64 on the off chance that real status page will be
-+ * above 4GB.
-+ */
-+#if defined(__ia64__)
-+ MGA_WRITE(MGAREG_PRIMPTR,
-+ virt_to_bus((void *)dev_priv->real_status_page));
-+#else
- MGA_WRITE(MGAREG_PRIMPTR,
- virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
--
-+#endif
-
- /* Private is now filled in, initialize the hardware */
- {
-diff -urN linux-2.4.27/drivers/char/drm-4.0/mga_drv.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/mga_drv.h
---- linux-2.4.27/drivers/char/drm-4.0/mga_drv.h 2002-02-25 12:37:57.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/mga_drv.h 2004-08-15 04:59:17.000000000 -0600
-@@ -295,7 +295,7 @@
- num_dwords + 1 + outcount, ADRINDEX(reg), val); \
- if( ++outcount == 4) { \
- outcount = 0; \
-- dma_ptr[0] = *(unsigned long *)tempIndex; \
-+ dma_ptr[0] = *(u32 *)tempIndex; \
- dma_ptr+=5; \
- num_dwords += 5; \
- } \
-diff -urN linux-2.4.27/drivers/char/drm-4.0/r128_cce.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/r128_cce.c
---- linux-2.4.27/drivers/char/drm-4.0/r128_cce.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/r128_cce.c 2004-08-15 05:08:11.000000000 -0600
-@@ -229,7 +229,21 @@
- int i;
-
- for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-+#ifndef CONFIG_AGP_I460
- if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
-+#else
-+ /*
-+ * XXX - this is (I think) a 460GX specific hack
-+ *
-+ * When doing texturing, ring.tail sometimes gets ahead of
-+ * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes
-+ * its whole quota of instructions and *ring.head is still 2
-+ * short of ring.tail. Work around this for now in lieu of
-+ * a better solution.
-+ */
-+ if ( (*dev_priv->ring.head == dev_priv->ring.tail) ||
-+ ((dev_priv->ring.tail - *dev_priv->ring.head) == 2) ) {
-+#endif
- int pm4stat = R128_READ( R128_PM4_STAT );
- if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
- dev_priv->cce_fifo_size ) &&
-@@ -330,7 +344,7 @@
- static void r128_cce_init_ring_buffer( drm_device_t *dev )
- {
- drm_r128_private_t *dev_priv = dev->dev_private;
-- u32 ring_start;
-+ u32 ring_start, rptr_addr;
- u32 tmp;
-
- /* The manual (p. 2) says this address is in "VM space". This
-@@ -342,10 +356,27 @@
- R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
- R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
-
-+ /*
-+ * 460GX doesn't claim PCI writes from the card into the AGP
-+ * aperture, so we have to get space outside the aperture for
-+ * RPTR_ADDR.
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off;
-+
-+ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
-+ atomic_inc(&virt_to_page(alt_rh_off)->count);
-+ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+
-+ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
-+ rptr_addr = __pa( dev_priv->ring.head );
-+ } else {
-+ rptr_addr = dev_priv->ring_rptr->offset;
-+ }
-+
- /* DL_RPTR_ADDR is a physical address in AGP space. */
- *dev_priv->ring.head = 0;
-- R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
-- dev_priv->ring_rptr->offset );
-+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr );
-
- /* Set watermark control */
- R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
-@@ -530,6 +561,19 @@
- }
- #endif
-
-+ /*
-+ * Free the page we grabbed for RPTR_ADDR
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off =
-+ (unsigned long) dev_priv->ring.head;
-+
-+ atomic_dec(&virt_to_page(alt_rh_off)->count);
-+ clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+ wake_up(&virt_to_page(alt_rh_off)->wait);
-+ free_page(alt_rh_off);
-+ }
-+
- drm_free( dev->dev_private, sizeof(drm_r128_private_t),
- DRM_MEM_DRIVER );
- dev->dev_private = NULL;
-diff -urN linux-2.4.27/drivers/char/drm-4.0/radeon_cp.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/radeon_cp.c
---- linux-2.4.27/drivers/char/drm-4.0/radeon_cp.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/radeon_cp.c 2004-08-15 05:11:10.000000000 -0600
-@@ -569,7 +569,7 @@
- static void radeon_cp_init_ring_buffer( drm_device_t *dev )
- {
- drm_radeon_private_t *dev_priv = dev->dev_private;
-- u32 ring_start, cur_read_ptr;
-+ u32 ring_start, cur_read_ptr, rptr_addr;
- u32 tmp;
-
- /* Initialize the memory controller */
-@@ -592,10 +592,29 @@
- /* Initialize the ring buffer's read and write pointers */
- cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
- RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
-+
- *dev_priv->ring.head = cur_read_ptr;
- dev_priv->ring.tail = cur_read_ptr;
-
-- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
-+ /*
-+ * 460GX doesn't claim PCI writes from the card into the AGP
-+ * aperture, so we have to get space outside the aperture for
-+ * RPTR_ADDR.
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off;
-+
-+ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
-+ atomic_inc(&virt_to_page(alt_rh_off)->count);
-+ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+
-+ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
-+ *dev_priv->ring.head = cur_read_ptr;
-+ rptr_addr = __pa( dev_priv->ring.head );
-+ } else
-+ rptr_addr = dev_priv->ring_rptr->offset;
-+
-+ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr);
-
- /* Set ring buffer size */
- RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
-@@ -837,6 +856,19 @@
- }
- #endif
-
-+ /*
-+ * Free the page we grabbed for RPTR_ADDR.
-+ */
-+ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
-+ unsigned long alt_rh_off =
-+ (unsigned long) dev_priv->ring.head;
-+
-+ atomic_dec(&virt_to_page(alt_rh_off)->count);
-+ clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
-+ wake_up(&virt_to_page(alt_rh_off)->wait);
-+ free_page(alt_rh_off);
-+ }
-+
- drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
- DRM_MEM_DRIVER );
- dev->dev_private = NULL;
-diff -urN linux-2.4.27/drivers/char/drm-4.0/radeon_drv.h /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/radeon_drv.h
---- linux-2.4.27/drivers/char/drm-4.0/radeon_drv.h 2002-02-25 12:37:57.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/radeon_drv.h 2004-08-15 05:08:35.000000000 -0600
-@@ -535,7 +535,7 @@
- #define RADEON_MAX_VB_VERTS (0xffff)
-
-
--#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
-+#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
- #define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg)
-
- #define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg)
-diff -urN linux-2.4.27/drivers/char/drm-4.0/vm.c /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/vm.c
---- linux-2.4.27/drivers/char/drm-4.0/vm.c 2002-02-25 12:37:57.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/drm-4.0/vm.c 2004-08-15 05:01:37.000000000 -0600
-@@ -30,6 +30,7 @@
- */
-
- #define __NO_VERSION__
-+#include <linux/config.h>
- #include "drmP.h"
-
- struct vm_operations_struct drm_vm_ops = {
-@@ -67,7 +68,56 @@
- int write_access)
- #endif
- {
-- return NOPAGE_SIGBUS; /* Disallow mremap */
-+ drm_file_t *priv = vma->vm_file->private_data;
-+ drm_device_t *dev = priv->dev;
-+ drm_map_t *map = NULL;
-+ int i;
-+
-+ if (!dev->agp->cant_use_aperture)
-+ return NOPAGE_SIGBUS; /* Disallow mremap */
-+
-+ /*
-+ * Find the right map
-+ */
-+ for (i = 0; i < dev->map_count; i++) {
-+ map = dev->maplist[i];
-+ if (!map) continue;
-+ if (map->offset == VM_OFFSET(vma)) break;
-+ }
-+
-+ if (map && map->type == _DRM_AGP) {
-+ unsigned long offset = address - vma->vm_start;
-+ unsigned long baddr = VM_OFFSET(vma) + offset, paddr;
-+ struct drm_agp_mem *agpmem;
-+ struct page *page;
-+
-+ /*
-+ * It's AGP memory - find the real physical page to map
-+ */
-+ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
-+ if (agpmem->bound <= baddr &&
-+ agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
-+ break;
-+ }
-+
-+ if (!agpmem)
-+ return NOPAGE_SIGBUS;
-+
-+ /*
-+ * Get the page, inc the use count, and return it
-+ */
-+ offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
-+ paddr = agpmem->memory->memory[offset];
-+ page = virt_to_page(__va(paddr));
-+ get_page(page);
-+
-+#if LINUX_VERSION_CODE < 0x020317
-+ return page_address(page);
-+#else
-+ return page;
-+#endif
-+ }
-+ return NOPAGE_SIGBUS;
- }
-
- #if LINUX_VERSION_CODE < 0x020317
-@@ -272,6 +322,7 @@
- drm_file_t *priv = filp->private_data;
- drm_device_t *dev = priv->dev;
- drm_map_t *map = NULL;
-+ unsigned long off;
- int i;
-
- DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-@@ -288,7 +339,16 @@
- bit longer. */
- for (i = 0; i < dev->map_count; i++) {
- map = dev->maplist[i];
-- if (map->offset == VM_OFFSET(vma)) break;
-+ off = map->offset ^ VM_OFFSET(vma);
-+#ifdef __ia64__
-+ /*
-+ * Ignore region bits, makes IA32 processes happier
-+ * XXX This is a hack...
-+ */
-+ off &= ~0xe000000000000000;
-+#endif
-+ if (off == 0)
-+ break;
- }
-
- if (i >= dev->map_count) return -EINVAL;
-@@ -312,9 +372,19 @@
- }
-
- switch (map->type) {
-+ case _DRM_AGP:
-+ if (dev->agp->cant_use_aperture) {
-+ /*
-+ * On some systems we can't talk to bus dma address from
-+ * the CPU, so for memory of type DRM_AGP, we'll deal
-+ * with sorting out the real physical pages and mappings
-+ * in nopage()
-+ */
-+ vma->vm_ops = &drm_vm_ops;
-+ break;
-+ }
- case _DRM_FRAME_BUFFER:
- case _DRM_REGISTERS:
-- case _DRM_AGP:
- if (VM_OFFSET(vma) >= __pa(high_memory)) {
- #if defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
-diff -urN linux-2.4.27/drivers/char/mem.c /home/dannf/bk/linux-2.4-20040815/drivers/char/mem.c
---- linux-2.4.27/drivers/char/mem.c 2004-08-07 17:26:04.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/mem.c 2004-08-15 05:04:58.000000000 -0600
-@@ -27,6 +27,10 @@
- #include <asm/io.h>
- #include <asm/pgalloc.h>
-
-+#ifdef CONFIG_IA64
-+# include <linux/efi.h>
-+#endif
-+
- #ifdef CONFIG_I2C
- extern int i2c_init_all(void);
- #endif
-@@ -42,7 +46,46 @@
- #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
- extern void tapechar_init(void);
- #endif
--
-+
-+/*
-+ * Architectures vary in how they handle caching for addresses
-+ * outside of main memory.
-+ *
-+ */
-+static inline int uncached_access(struct file *file, unsigned long addr)
-+{
-+#if defined(__i386__)
-+ /*
-+ * On the PPro and successors, the MTRRs are used to set
-+ * memory types for physical addresses outside main memory,
-+ * so blindly setting PCD or PWT on those pages is wrong.
-+ * For Pentiums and earlier, the surround logic should disable
-+ * caching for the high addresses through the KEN pin, but
-+ * we maintain the tradition of paranoia in this code.
-+ */
-+ if (file->f_flags & O_SYNC)
-+ return 1;
-+ return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) ||
-+ test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) ||
-+ test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
-+ test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) )
-+ && addr >= __pa(high_memory);
-+#elif defined(CONFIG_IA64)
-+ /*
-+ * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
-+ */
-+ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
-+#else
-+ /*
-+ * Accessing memory above the top the kernel knows about or through a file pointer
-+ * that was marked O_SYNC will be done non-cached.
-+ */
-+ if (file->f_flags & O_SYNC)
-+ return 1;
-+ return addr >= __pa(high_memory);
-+#endif
-+}
-+
- static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
- const char * buf, size_t count, loff_t *ppos)
- {
-@@ -79,7 +122,7 @@
- unsigned long p = *ppos;
- unsigned long end_mem;
- ssize_t read;
--
-+
- end_mem = __pa(high_memory);
- if (p >= end_mem)
- return 0;
-@@ -123,77 +166,16 @@
- return do_write_mem(file, __va(p), p, buf, count, ppos);
- }
-
--#ifndef pgprot_noncached
--
--/*
-- * This should probably be per-architecture in <asm/pgtable.h>
-- */
--static inline pgprot_t pgprot_noncached(pgprot_t _prot)
--{
-- unsigned long prot = pgprot_val(_prot);
--
--#if defined(__i386__) || defined(__x86_64__)
-- /* On PPro and successors, PCD alone doesn't always mean
-- uncached because of interactions with the MTRRs. PCD | PWT
-- means definitely uncached. */
-- if (boot_cpu_data.x86 > 3)
-- prot |= _PAGE_PCD | _PAGE_PWT;
--#elif defined(__powerpc__)
-- prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
--#elif defined(__mc68000__)
--#ifdef SUN3_PAGE_NOCACHE
-- if (MMU_IS_SUN3)
-- prot |= SUN3_PAGE_NOCACHE;
-- else
--#endif
-- if (MMU_IS_851 || MMU_IS_030)
-- prot |= _PAGE_NOCACHE030;
-- /* Use no-cache mode, serialized */
-- else if (MMU_IS_040 || MMU_IS_060)
-- prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
--#endif
--
-- return __pgprot(prot);
--}
--
--#endif /* !pgprot_noncached */
--
--/*
-- * Architectures vary in how they handle caching for addresses
-- * outside of main memory.
-- */
--static inline int noncached_address(unsigned long addr)
--{
--#if defined(__i386__)
-- /*
-- * On the PPro and successors, the MTRRs are used to set
-- * memory types for physical addresses outside main memory,
-- * so blindly setting PCD or PWT on those pages is wrong.
-- * For Pentiums and earlier, the surround logic should disable
-- * caching for the high addresses through the KEN pin, but
-- * we maintain the tradition of paranoia in this code.
-- */
-- return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
-- test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
-- test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
-- test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
-- && addr >= __pa(high_memory);
--#else
-- return addr >= __pa(high_memory);
--#endif
--}
--
- static int mmap_mem(struct file * file, struct vm_area_struct * vma)
- {
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
-+ int uncached;
-
-- /*
-- * Accessing memory above the top the kernel knows about or
-- * through a file pointer that was marked O_SYNC will be
-- * done non-cached.
-- */
-- if (noncached_address(offset) || (file->f_flags & O_SYNC))
-+ uncached = uncached_access(file, offset);
-+#ifdef pgprot_noncached
-+ if (uncached)
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+#endif
-
- /* Don't try to swap out physical pages.. */
- vma->vm_flags |= VM_RESERVED;
-@@ -201,7 +183,7 @@
- /*
- * Don't dump addresses that are not real memory to a core file.
- */
-- if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
-+ if (uncached)
- vma->vm_flags |= VM_IO;
-
- if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
-@@ -512,11 +494,13 @@
- ret = file->f_pos;
- force_successful_syscall_return();
- break;
-+
- case 1:
- file->f_pos += offset;
- ret = file->f_pos;
- force_successful_syscall_return();
- break;
-+
- default:
- ret = -EINVAL;
- }
-@@ -581,6 +565,7 @@
- {
- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
- unsigned long size = vma->vm_end - vma->vm_start;
-+ int uncached;
-
- /*
- * If the user is not attempting to mmap a high memory address then
-@@ -591,13 +576,11 @@
- if ((offset + size) < (unsigned long) high_memory)
- return mmap_mem(file, vma);
-
-- /*
-- * Accessing memory above the top the kernel knows about or
-- * through a file pointer that was marked O_SYNC will be
-- * done non-cached.
-- */
-- if (noncached_address(offset) || (file->f_flags & O_SYNC))
-+ uncached = uncached_access(file, offset);
-+#ifdef pgprot_noncached
-+ if (uncached)
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+#endif
-
- /* Don't do anything here; "nopage" will fill the holes */
- vma->vm_ops = &kmem_vm_ops;
-@@ -608,7 +591,8 @@
- /*
- * Don't dump addresses that are not real memory to a core file.
- */
-- vma->vm_flags |= VM_IO;
-+ if (uncached)
-+ vma->vm_flags |= VM_IO;
-
- return 0;
- }
-diff -urN linux-2.4.27/drivers/char/serial.c /home/dannf/bk/linux-2.4-20040815/drivers/char/serial.c
---- linux-2.4.27/drivers/char/serial.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/char/serial.c 2004-08-15 04:58:15.000000000 -0600
-@@ -92,9 +92,8 @@
- * ever possible.
- *
- * CONFIG_SERIAL_ACPI
-- * Enable support for serial console port and serial
-- * debug port as defined by the SPCR and DBGP tables in
-- * ACPI 2.0.
-+ * Enable support for serial ports found in the ACPI
-+ * namespace.
- */
-
- #include <linux/config.h>
-@@ -222,6 +221,10 @@
- #ifdef CONFIG_MAGIC_SYSRQ
- #include <linux/sysrq.h>
- #endif
-+#ifdef ENABLE_SERIAL_ACPI
-+#include <linux/acpi.h>
-+#include <acpi/acpi_bus.h>
-+#endif
-
- /*
- * All of the compatibilty code so we can compile serial.c against
-@@ -257,6 +260,10 @@
-
- static struct timer_list serial_timer;
-
-+#define HP_DIVA_CHECKTIME (1*HZ)
-+static struct timer_list hp_diva_timer;
-+static int hp_diva_count = 0;
-+
- /* serial subtype definitions */
- #ifndef SERIAL_TYPE_NORMAL
- #define SERIAL_TYPE_NORMAL 1
-@@ -793,6 +800,41 @@
- }
-
- #ifdef CONFIG_SERIAL_SHARE_IRQ
-+static inline int is_hp_diva_info(struct async_struct *info)
-+{
-+ struct pci_dev *dev = info->state->dev;
-+ return (dev && dev->vendor == PCI_VENDOR_ID_HP &&
-+ dev->device == PCI_DEVICE_ID_HP_SAS);
-+}
-+
-+static inline int is_hp_diva_irq(int irq)
-+{
-+ struct async_struct *info = IRQ_ports[irq];
-+ return (info && is_hp_diva_info(info));
-+}
-+
-+/*
-+ * It is possible to "use up" transmit empty interrupts in some
-+ * cases with HP Diva cards. Figure out if there _should_ be a
-+ * transmit interrupt and if so, return a suitable iir value so
-+ * that we can recover when called from rs_timer().
-+ */
-+static inline int hp_diva_iir(int irq, struct async_struct *info)
-+{
-+ int iir = serial_in(info, UART_IIR);
-+
-+ if (is_hp_diva_info(info) &&
-+ (iir & UART_IIR_NO_INT) != 0 &&
-+ (info->IER & UART_IER_THRI) != 0 &&
-+ (info->xmit.head != info->xmit.tail || info->x_char) &&
-+ (serial_in(info, UART_LSR) & UART_LSR_THRE) != 0) {
-+ iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
-+ iir |= UART_IIR_THRI;
-+ }
-+
-+ return iir;
-+}
-+
- /*
- * This is the serial driver's generic interrupt routine
- */
-@@ -823,7 +865,7 @@
-
- do {
- if (!info->tty ||
-- ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
-+ ((iir=hp_diva_iir(irq, info)) & UART_IIR_NO_INT)) {
- if (!end_mark)
- end_mark = info;
- goto next;
-@@ -1097,9 +1139,11 @@
- #ifdef CONFIG_SERIAL_SHARE_IRQ
- if (info->next_port) {
- do {
-- serial_out(info, UART_IER, 0);
-- info->IER |= UART_IER_THRI;
-- serial_out(info, UART_IER, info->IER);
-+ if (!is_hp_diva_info(info)) {
-+ serial_out(info, UART_IER, 0);
-+ info->IER |= UART_IER_THRI;
-+ serial_out(info, UART_IER, info->IER);
-+ }
- info = info->next_port;
- } while (info);
- #ifdef CONFIG_SERIAL_MULTIPORT
-@@ -1131,6 +1175,35 @@
- }
-
- /*
-+ * This subroutine is called when the hp_diva_timer goes off. In
-+ * certain cases (multiple gettys in particular) Diva seems to issue
-+ * only a single transmit empty interrupt instead of one each time
-+ * THRI is enabled, causing interrupts to be "used up". This serves
-+ * to poll the Diva UARTS more frequently than rs_timer() does.
-+ */
-+static void hp_diva_check(unsigned long dummy)
-+{
-+#ifdef CONFIG_SERIAL_SHARE_IRQ
-+ static unsigned long last_strobe;
-+ unsigned long flags;
-+ int i;
-+
-+ if (time_after_eq(jiffies, last_strobe + HP_DIVA_CHECKTIME)) {
-+ for (i = 0; i < NR_IRQS; i++) {
-+ if (is_hp_diva_irq(i)) {
-+ save_flags(flags); cli();
-+ rs_interrupt(i, NULL, NULL);
-+ restore_flags(flags);
-+ }
-+ }
-+ }
-+ last_strobe = jiffies;
-+ mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
-+#endif
-+}
-+
-+
-+/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver: routines to
- * figure out the appropriate timeout for an interrupt chain, routines
-@@ -4294,6 +4367,12 @@
- break;
- }
-
-+ if (hp_diva_count++ == 0) {
-+ init_timer(&hp_diva_timer);
-+ hp_diva_timer.function = hp_diva_check;
-+ mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
-+ }
-+
- return 0;
- }
-
-@@ -4597,6 +4676,129 @@
- }
- }
-
-+#ifdef ENABLE_SERIAL_ACPI
-+static acpi_status acpi_serial_address(struct serial_struct *req,
-+ struct acpi_resource_address64 *addr)
-+{
-+ unsigned long size;
-+
-+ size = addr->max_address_range - addr->min_address_range + 1;
-+ req->iomem_base = ioremap(addr->min_address_range, size);
-+ if (!req->iomem_base) {
-+ printk("%s: couldn't ioremap 0x%lx-0x%lx\n", __FUNCTION__,
-+ addr->min_address_range, addr->max_address_range);
-+ return AE_ERROR;
-+ }
-+ req->io_type = SERIAL_IO_MEM;
-+ return AE_OK;
-+}
-+
-+static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
-+ struct acpi_resource_ext_irq *ext_irq)
-+{
-+ if (ext_irq->number_of_interrupts > 0) {
-+#ifdef CONFIG_IA64
-+ req->irq = acpi_register_irq(ext_irq->interrupts[0],
-+ ext_irq->active_high_low, ext_irq->edge_level);
-+#else
-+ req->irq = ext_irq->interrupts[0];
-+#endif
-+ }
-+ return AE_OK;
-+}
-+
-+static acpi_status acpi_serial_port(struct serial_struct *req,
-+ struct acpi_resource_io *io)
-+{
-+ req->port = io->min_base_address;
-+ req->io_type = SERIAL_IO_PORT;
-+ return AE_OK;
-+}
-+
-+static acpi_status acpi_serial_irq(struct serial_struct *req,
-+ struct acpi_resource_irq *irq)
-+{
-+ if (irq->number_of_interrupts > 0) {
-+#ifdef CONFIG_IA64
-+ req->irq = acpi_register_irq(irq->interrupts[0],
-+ irq->active_high_low, irq->edge_level);
-+#else
-+ req->irq = irq->interrupts[0];
-+#endif
-+ }
-+ return AE_OK;
-+}
-+
-+static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
-+{
-+ struct serial_struct *serial_req = (struct serial_struct *) data;
-+ struct acpi_resource_address64 addr;
-+ acpi_status status;
-+
-+ status = acpi_resource_to_address64(res, &addr);
-+ if (ACPI_SUCCESS(status))
-+ return acpi_serial_address(serial_req, &addr);
-+ else if (res->id == ACPI_RSTYPE_EXT_IRQ)
-+ return acpi_serial_ext_irq(serial_req, &res->data.extended_irq);
-+ else if (res->id == ACPI_RSTYPE_IO)
-+ return acpi_serial_port(serial_req, &res->data.io);
-+ else if (res->id == ACPI_RSTYPE_IRQ)
-+ return acpi_serial_irq(serial_req, &res->data.irq);
-+ return AE_OK;
-+}
-+
-+static int acpi_serial_add(struct acpi_device *device)
-+{
-+ acpi_status status;
-+ struct serial_struct serial_req;
-+ int line;
-+
-+ memset(&serial_req, 0, sizeof(serial_req));
-+
-+ status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
-+ acpi_serial_resource, &serial_req);
-+ if (ACPI_FAILURE(status))
-+ return -ENODEV;
-+
-+ if (!serial_req.iomem_base && !serial_req.port) {
-+ printk("%s: no iomem or port address in %s _CRS\n", __FUNCTION__,
-+ device->pnp.bus_id);
-+ return -ENODEV;
-+ }
-+
-+ serial_req.baud_base = BASE_BAUD;
-+ serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ;
-+ serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
-+ serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
-+ serial_req.iomem_reg_shift = 0;
-+
-+ line = register_serial(&serial_req);
-+ if (line < 0)
-+ return -ENODEV;
-+
-+ return 0;
-+}
-+
-+static int acpi_serial_remove(struct acpi_device *device, int type)
-+{
-+ return 0;
-+}
-+
-+static struct acpi_driver acpi_serial_driver = {
-+ .name = "serial",
-+ .class = "",
-+ .ids = "PNP0501",
-+ .ops = {
-+ .add = acpi_serial_add,
-+ .remove = acpi_serial_remove,
-+ },
-+};
-+
-+static void __devinit probe_serial_acpi(void)
-+{
-+ acpi_bus_register_driver(&acpi_serial_driver);
-+}
-+#endif /* ENABLE_SERIAL_ACPI */
-
- static struct pci_device_id serial_pci_tbl[] __devinitdata = {
- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-@@ -5558,6 +5760,9 @@
- tty_register_devfs(&callout_driver, 0,
- callout_driver.minor_start + state->line);
- }
-+#ifdef ENABLE_SERIAL_ACPI
-+ probe_serial_acpi();
-+#endif
- #ifdef ENABLE_SERIAL_PCI
- probe_serial_pci();
- #endif
-@@ -5735,6 +5940,8 @@
-
- /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
- del_timer_sync(&serial_timer);
-+ if (hp_diva_count > 0)
-+ del_timer_sync(&hp_diva_timer);
- save_flags(flags); cli();
- remove_bh(SERIAL_BH);
- if ((e1 = tty_unregister_driver(&serial_driver)))
-diff -urN linux-2.4.27/drivers/net/tulip/media.c /home/dannf/bk/linux-2.4-20040815/drivers/net/tulip/media.c
---- linux-2.4.27/drivers/net/tulip/media.c 2003-06-13 08:51:35.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/net/tulip/media.c 2004-08-15 04:56:42.000000000 -0600
-@@ -284,6 +284,10 @@
- for (i = 0; i < init_length; i++)
- outl(init_sequence[i], ioaddr + CSR12);
- }
-+
-+ (void) inl(ioaddr + CSR6); /* flush CSR12 writes */
-+ udelay(500); /* Give MII time to recover */
-+
- tmp_info = get_u16(&misc_info[1]);
- if (tmp_info)
- tp->advertising[phy_num] = tmp_info | 1;
-diff -urN linux-2.4.27/drivers/pci/pci.c /home/dannf/bk/linux-2.4-20040815/drivers/pci/pci.c
---- linux-2.4.27/drivers/pci/pci.c 2004-08-07 17:26:05.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/pci/pci.c 2004-08-15 04:57:26.000000000 -0600
-@@ -1061,8 +1061,14 @@
- {
- unsigned int pos, reg, next;
- u32 l, sz;
-+ u16 cmd;
- struct resource *res;
-
-+ /* Disable I/O & memory decoding while we size the BARs. */
-+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
-+ pci_write_config_word(dev, PCI_COMMAND,
-+ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-+
- for(pos=0; pos<howmany; pos = next) {
- next = pos+1;
- res = &dev->resource[pos];
-@@ -1127,13 +1133,16 @@
- if (sz && sz != 0xffffffff) {
- sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
- if (!sz)
-- return;
-+ goto out;
- res->flags = (l & PCI_ROM_ADDRESS_ENABLE) |
- IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
- res->start = l & PCI_ROM_ADDRESS_MASK;
- res->end = res->start + (unsigned long) sz;
- }
- }
-+
-+out:
-+ pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
-
- void __devinit pci_read_bridge_bases(struct pci_bus *child)
-@@ -2066,16 +2075,16 @@
- int map, block;
-
- if ((page = pool_find_page (pool, dma)) == 0) {
-- printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
-+ printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
- pool->dev ? pool->dev->slot_name : NULL,
-- pool->name, vaddr, (int) (dma & 0xffffffff));
-+ pool->name, vaddr, (unsigned long) dma);
- return;
- }
- #ifdef CONFIG_PCIPOOL_DEBUG
- if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-- printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
-+ printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
- pool->dev ? pool->dev->slot_name : NULL,
-- pool->name, vaddr, (int) (dma & 0xffffffff));
-+ pool->name, vaddr, (unsigned long) dma);
- return;
- }
- #endif
-diff -urN linux-2.4.27/drivers/scsi/megaraid.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/megaraid.c
---- linux-2.4.27/drivers/scsi/megaraid.c 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/megaraid.c 2004-08-15 04:48:15.000000000 -0600
-@@ -2234,9 +2234,6 @@
-
-
- #if DEBUG
--static unsigned int cum_time = 0;
--static unsigned int cum_time_cnt = 0;
--
- static void showMbox (mega_scb * pScb)
- {
- mega_mailbox *mbox;
-@@ -2245,7 +2242,7 @@
- return;
-
- mbox = (mega_mailbox *) pScb->mboxData;
-- printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
-+ printk ("%lu cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
- pScb->SCpnt->pid,
- mbox->cmd, mbox->cmdid, mbox->numsectors,
- mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements);
-@@ -3569,10 +3566,14 @@
- mbox[0] = IS_BIOS_ENABLED;
- mbox[2] = GET_BIOS;
-
-- mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer);
-+ mboxpnt->xferaddr = pci_map_single(megacfg->dev,
-+ (void *) megacfg->mega_buffer, (2 * 1024L),
-+ PCI_DMA_FROMDEVICE);
-
- ret = megaIssueCmd (megacfg, mbox, NULL, 0);
-
-+ pci_unmap_single(megacfg->dev, mboxpnt->xferaddr, 2 * 1024L, PCI_DMA_FROMDEVICE);
-+
- return (*(char *) megacfg->mega_buffer);
- }
-
-diff -urN linux-2.4.27/drivers/scsi/qla1280.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/qla1280.c
---- linux-2.4.27/drivers/scsi/qla1280.c 2003-11-28 11:26:20.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/qla1280.c 2004-08-15 05:17:23.000000000 -0600
-@@ -2112,7 +2112,7 @@
- ha->flags.abort_isp_active = 0;
-
- ha->flags.ints_enabled = 0;
--#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-+#if defined(CONFIG_IA64_SGI_SN2)
- if (ia64_platform_is("sn2")) {
- int count1, count2;
- int c;
-diff -urN linux-2.4.27/drivers/scsi/scsi_dma.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_dma.c
---- linux-2.4.27/drivers/scsi/scsi_dma.c 2002-02-25 12:38:04.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_dma.c 2004-08-15 05:05:13.000000000 -0600
-@@ -30,8 +30,69 @@
- typedef unsigned char FreeSectorBitmap;
- #elif SECTORS_PER_PAGE <= 32
- typedef unsigned int FreeSectorBitmap;
--#else
--#error You lose.
-+#elif SECTORS_PER_PAGE <= 64
-+typedef u64 FreeSectorBitmap;
-+#elif SECTORS_PER_PAGE <= 128
-+
-+typedef struct {
-+ u64 hi, lo;
-+} FreeSectorBitmap;
-+
-+/* No side effects on MAP-macro-arguments, please... */
-+
-+#define MAP_MAKE_MASK(m, nbits) \
-+do { \
-+ if ((nbits) >= 64) { \
-+ (m).hi = ((u64) 1 << ((nbits) - 64)) - 1; \
-+ (m).lo = ~(u64) 0; \
-+ } else { \
-+ (m).hi = 0; \
-+ (m).lo = ((u64) 1 << (nbits)) - 1; \
-+ } \
-+} while (0)
-+
-+#define MAP_SHIFT_LEFT(m, count) \
-+do { \
-+ if ((count) >= 64) { \
-+ (m).hi = (m).lo << ((count) - 64); \
-+ (m).lo = 0; \
-+ } else { \
-+ (m).hi = ((m).hi << (count)) | ((m).lo >> (64 - (count))); \
-+ (m).lo <<= count; \
-+ } \
-+} while (0)
-+
-+#define MAP_AND(r, left, right) \
-+do { \
-+ (r).hi = (left).hi & (right).hi; \
-+ (r).lo = (left).lo & (right).lo; \
-+} while (0)
-+
-+#define MAP_SET(r, mask) \
-+do { \
-+ (r).hi |= (mask).hi; \
-+ (r).lo |= (mask).lo; \
-+} while (0)
-+
-+#define MAP_CLEAR(r, mask) \
-+do { \
-+ (r).hi &= ~(mask).hi; \
-+ (r).lo &= ~(mask).lo; \
-+} while (0)
-+
-+#define MAP_EQUAL(left, right) (((left.hi ^ right.hi) | (left.lo ^ right.lo)) == 0)
-+#define MAP_EMPTY(m) ((m.lo | m.hi) == 0)
-+
-+#endif
-+
-+#ifndef MAP_MAKE_MASK
-+# define MAP_MAKE_MASK(m,nbits) ((m) = (((u64) 1 << (nbits)) - 1))
-+# define MAP_SHIFT_LEFT(m,nbits) ((m) <<= (nbits))
-+# define MAP_AND(res,l,r) ((res) = (l) & (r))
-+# define MAP_EQUAL(l,r) ((l) == (r))
-+# define MAP_EMPTY(m) ((m) == 0)
-+# define MAP_CLEAR(m, bits) ((m) &= ~(bits))
-+# define MAP_SET(m, bits) ((m) |= (bits))
- #endif
-
- /*
-@@ -71,7 +132,8 @@
- */
- void *scsi_malloc(unsigned int len)
- {
-- unsigned int nbits, mask;
-+ FreeSectorBitmap mask, busy_sectors, result;
-+ unsigned int nbits;
- unsigned long flags;
-
- int i, j;
-@@ -79,23 +141,29 @@
- return NULL;
-
- nbits = len >> 9;
-- mask = (1 << nbits) - 1;
-
- spin_lock_irqsave(&allocator_request_lock, flags);
-
-- for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
-+ for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) {
-+ MAP_MAKE_MASK(mask, nbits);
-+ busy_sectors = dma_malloc_freelist[i];
- for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) {
-- if ((dma_malloc_freelist[i] & (mask << j)) == 0) {
-- dma_malloc_freelist[i] |= (mask << j);
-+ MAP_AND(result, busy_sectors, mask);
-+ if (MAP_EMPTY(result)) {
-+ MAP_SET(dma_malloc_freelist[i], mask);
- scsi_dma_free_sectors -= nbits;
- #ifdef DEBUG
-- SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)));
-- printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9));
-+ SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p\n",
-+ len, dma_malloc_pages[i] + (j << 9)));
-+ printk("SMalloc: %d %p\n",
-+ len, dma_malloc_pages[i] + (j << 9));
- #endif
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
- }
-+ MAP_SHIFT_LEFT(mask, 1);
- }
-+ }
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return NULL; /* Nope. No more */
- }
-@@ -121,7 +189,8 @@
- */
- int scsi_free(void *obj, unsigned int len)
- {
-- unsigned int page, sector, nbits, mask;
-+ FreeSectorBitmap mask, result;
-+ unsigned int page, sector, nbits;
- unsigned long flags;
-
- #ifdef DEBUG
-@@ -145,13 +214,14 @@
- sector = (((unsigned long) obj) - page_addr) >> 9;
-
- nbits = len >> 9;
-- mask = (1 << nbits) - 1;
-+ MAP_MAKE_MASK(mask, nbits);
-
- if (sector + nbits > SECTORS_PER_PAGE)
- panic("scsi_free:Bad memory alignment");
-
-- if ((dma_malloc_freelist[page] &
-- (mask << sector)) != (mask << sector)) {
-+ MAP_SHIFT_LEFT(mask, sector);
-+ MAP_AND(result, mask, dma_malloc_freelist[page]);
-+ if (!MAP_EQUAL(result, mask)) {
- #ifdef DEBUG
- printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
- obj, len, ret);
-@@ -159,7 +229,7 @@
- panic("scsi_free:Trying to free unused memory");
- }
- scsi_dma_free_sectors += nbits;
-- dma_malloc_freelist[page] &= ~(mask << sector);
-+ MAP_CLEAR(dma_malloc_freelist[page], mask);
- spin_unlock_irqrestore(&allocator_request_lock, flags);
- return 0;
- }
-diff -urN linux-2.4.27/drivers/scsi/scsi_ioctl.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_ioctl.c
---- linux-2.4.27/drivers/scsi/scsi_ioctl.c 2003-08-25 05:44:42.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_ioctl.c 2004-08-15 05:16:04.000000000 -0600
-@@ -198,6 +198,9 @@
- unsigned int needed, buf_needed;
- int timeout, retries, result;
- int data_direction;
-+#if __GNUC__ < 3
-+ int foo;
-+#endif
-
- if (!sic)
- return -EINVAL;
-@@ -207,12 +210,21 @@
- if (verify_area(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command)))
- return -EFAULT;
-
-- if(__get_user(inlen, &sic->inlen))
-+#if __GNUC__ < 3
-+ foo = __get_user(inlen, &sic->inlen);
-+ if(foo)
- return -EFAULT;
-
-- if(__get_user(outlen, &sic->outlen))
-+ foo = __get_user(outlen, &sic->outlen);
-+ if(foo)
-+ return -EFAULT;
-+#else
-+ if(__get_user(inlen, &sic->inlen))
- return -EFAULT;
-
-+ if(__get_user(outlen, &sic->outlen))
-+ return -EFAULT;
-+#endif
- /*
- * We do not transfer more than MAX_BUF with this interface.
- * If the user needs to transfer more data than this, they
-diff -urN linux-2.4.27/drivers/scsi/scsi_merge.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_merge.c
---- linux-2.4.27/drivers/scsi/scsi_merge.c 2002-11-28 16:53:14.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/scsi_merge.c 2004-08-15 05:15:14.000000000 -0600
-@@ -1155,7 +1155,7 @@
- {
- struct Scsi_Host *SHpnt = SDpnt->host;
- request_queue_t *q = &SDpnt->request_queue;
-- dma64_addr_t bounce_limit;
-+ u64 bounce_limit;
-
- /*
- * If this host has an unlimited tablesize, then don't bother with a
-diff -urN linux-2.4.27/drivers/scsi/sym53c8xx.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx.c
---- linux-2.4.27/drivers/scsi/sym53c8xx.c 2004-04-14 07:05:32.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx.c 2004-08-15 05:09:13.000000000 -0600
-@@ -12979,6 +12979,7 @@
- }
- if (pci_enable_device(pcidev)) /* @!*!$&*!%-*#;! */
- continue;
-+#ifdef CONFIG_X86
- /* Some HW as the HP LH4 may report twice PCI devices */
- for (i = 0; i < count ; i++) {
- if (devtbl[i].slot.bus == PciBusNumber(pcidev) &&
-@@ -12987,6 +12988,7 @@
- }
- if (i != count) /* Ignore this device if we already have it */
- continue;
-+#endif
- devp = &devtbl[count];
- devp->host_id = driver_setup.host_id;
- devp->attach_done = 0;
-diff -urN linux-2.4.27/drivers/scsi/sym53c8xx_2/sym_glue.c /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx_2/sym_glue.c
---- linux-2.4.27/drivers/scsi/sym53c8xx_2/sym_glue.c 2002-11-28 16:53:14.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx_2/sym_glue.c 2004-08-15 05:18:21.000000000 -0600
-@@ -302,12 +302,8 @@
- #ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
- typedef u_long bus_addr_t;
- #else
--#if SYM_CONF_DMA_ADDRESSING_MODE > 0
--typedef dma64_addr_t bus_addr_t;
--#else
- typedef dma_addr_t bus_addr_t;
- #endif
--#endif
-
- /*
- * Used by the eh thread to wait for command completion.
-@@ -2803,6 +2799,7 @@
- /* This one is guaranteed by AC to do nothing :-) */
- if (pci_enable_device(pcidev))
- continue;
-+#ifdef CONFIG_X86
- /* Some HW as the HP LH4 may report twice PCI devices */
- for (i = 0; i < count ; i++) {
- if (devtbl[i].s.bus == PciBusNumber(pcidev) &&
-@@ -2811,6 +2808,7 @@
- }
- if (i != count) /* Ignore this device if we already have it */
- continue;
-+#endif
- devp = &devtbl[count];
- devp->host_id = SYM_SETUP_HOST_ID;
- devp->attach_done = 0;
-diff -urN linux-2.4.27/drivers/scsi/sym53c8xx_comm.h /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx_comm.h
---- linux-2.4.27/drivers/scsi/sym53c8xx_comm.h 2002-11-28 16:53:14.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/scsi/sym53c8xx_comm.h 2004-08-15 04:49:16.000000000 -0600
-@@ -2579,6 +2579,7 @@
- }
- if (pci_enable_device(pcidev)) /* @!*!$&*!%-*#;! */
- continue;
-+#ifdef CONFIG_X86
- /* Some HW as the HP LH4 may report twice PCI devices */
- for (i = 0; i < count ; i++) {
- if (devtbl[i].slot.bus == PciBusNumber(pcidev) &&
-@@ -2587,6 +2588,7 @@
- }
- if (i != count) /* Ignore this device if we already have it */
- continue;
-+#endif
- devp = &devtbl[count];
- devp->host_id = driver_setup.host_id;
- devp->attach_done = 0;
-diff -urN linux-2.4.27/drivers/sound/.indent.pro /home/dannf/bk/linux-2.4-20040815/drivers/sound/.indent.pro
---- linux-2.4.27/drivers/sound/.indent.pro 1997-09-30 09:46:46.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/sound/.indent.pro 1969-12-31 17:00:00.000000000 -0700
-@@ -1,8 +0,0 @@
---bad
---bap
---nfca
---bl
---psl
---di16
---lp
---ip5
-diff -urN linux-2.4.27/drivers/sound/.version /home/dannf/bk/linux-2.4-20040815/drivers/sound/.version
---- linux-2.4.27/drivers/sound/.version 1997-11-10 00:01:54.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/drivers/sound/.version 1969-12-31 17:00:00.000000000 -0700
-@@ -1,2 +0,0 @@
--3.8s
--0x030804
-diff -urN linux-2.4.27/fs/Config.in /home/dannf/bk/linux-2.4-20040815/fs/Config.in
---- linux-2.4.27/fs/Config.in 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/fs/Config.in 2004-08-15 05:08:50.000000000 -0600
-@@ -54,6 +54,13 @@
- bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
- define_bool CONFIG_RAMFS y
-
-+bool 'HugeTLB file system support' CONFIG_HUGETLBFS
-+if [ "$CONFIG_HUGETLBFS" = "y" ] ; then
-+ define_bool CONFIG_HUGETLB_PAGE y
-+else
-+ define_bool CONFIG_HUGETLB_PAGE n
-+fi
-+
- tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
- dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
- dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS
-@@ -72,13 +79,17 @@
-
- bool '/proc file system support' CONFIG_PROC_FS
-
--# For some reason devfs corrupts memory badly on x86-64. Disable it
--# for now.
--if [ "$CONFIG_X86_64" != "y" ] ; then
--dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL
-+if [ "$CONFIG_IA64_SGI_SN2" = "y" ] ; then
-+ define_bool CONFIG_DEVFS_FS y
-+else
-+ # For some reason devfs corrupts memory badly on x86-64. Disable it
-+ # for now.
-+ if [ "$CONFIG_X86_64" != "y" ] ; then
-+ dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL
-+ fi
-+fi
- dep_bool ' Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS
- dep_bool ' Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS
--fi
-
- # It compiles as a module for testing only. It should not be used
- # as a module in general. If we make this "tristate", a bunch of people
-diff -urN linux-2.4.27/fs/Makefile /home/dannf/bk/linux-2.4-20040815/fs/Makefile
---- linux-2.4.27/fs/Makefile 2004-02-18 06:36:31.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/fs/Makefile 2004-08-15 05:06:37.000000000 -0600
-@@ -28,6 +28,7 @@
- subdir-$(CONFIG_EXT2_FS) += ext2
- subdir-$(CONFIG_CRAMFS) += cramfs
- subdir-$(CONFIG_RAMFS) += ramfs
-+subdir-$(CONFIG_HUGETLBFS) += hugetlbfs
- subdir-$(CONFIG_CODA_FS) += coda
- subdir-$(CONFIG_INTERMEZZO_FS) += intermezzo
- subdir-$(CONFIG_MINIX_FS) += minix
-diff -urN linux-2.4.27/fs/binfmt_misc.c /home/dannf/bk/linux-2.4-20040815/fs/binfmt_misc.c
---- linux-2.4.27/fs/binfmt_misc.c 2002-08-02 18:39:45.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/fs/binfmt_misc.c 2004-08-15 05:00:06.000000000 -0600
-@@ -35,6 +35,7 @@
- static int enabled = 1;
-
- enum {Enabled, Magic};
-+#define MISC_FMT_PRESERVE_ARGV0 (1<<31)
-
- typedef struct {
- struct list_head list;
-@@ -121,7 +122,9 @@
- bprm->file = NULL;
-
- /* Build args for interpreter */
-- remove_arg_zero(bprm);
-+ if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
-+ remove_arg_zero(bprm);
-+ }
- retval = copy_strings_kernel(1, &bprm->filename, bprm);
- if (retval < 0) goto _ret;
- bprm->argc++;
-@@ -287,6 +290,11 @@
- if (!e->interpreter[0])
- goto Einval;
-
-+ if (*p == 'P') {
-+ p++;
-+ e->flags |= MISC_FMT_PRESERVE_ARGV0;
-+ }
-+
- if (*p == '\n')
- p++;
- if (p != buf + count)
-diff -urN linux-2.4.27/fs/hugetlbfs/Makefile /home/dannf/bk/linux-2.4-20040815/fs/hugetlbfs/Makefile
---- linux-2.4.27/fs/hugetlbfs/Makefile 1969-12-31 17:00:00.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/fs/hugetlbfs/Makefile 2004-08-15 04:53:55.000000000 -0600
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the linux hugetlbfs routines.
-+#
-+
-+O_TARGET := hugetlbfs.o
-+
-+obj-y := inode.o
-+
-+obj-m := $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.27/fs/hugetlbfs/inode.c /home/dannf/bk/linux-2.4-20040815/fs/hugetlbfs/inode.c
---- linux-2.4.27/fs/hugetlbfs/inode.c 1969-12-31 17:00:00.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/fs/hugetlbfs/inode.c 2004-08-15 05:06:27.000000000 -0600
-@@ -0,0 +1,762 @@
-+/*
-+ * hugetlbpage-backed filesystem. Based on ramfs.
-+ *
-+ * William Irwin, 2002
-+ *
-+ * Copyright (C) 2002 Linus Torvalds.
-+ * Backported from 2.5.48 11/19/2002 Rohit Seth <rohit.seth@intel.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <asm/current.h>
-+#include <linux/sched.h> /* remove ASAP */
-+#include <linux/fs.h>
-+#include <linux/mount.h>
-+#include <linux/file.h>
-+#include <linux/pagemap.h>
-+#include <linux/highmem.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+#include <linux/hugetlb.h>
-+#include <linux/quotaops.h>
-+#include <linux/slab.h>
-+#include <linux/dnotify.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/statfs.h>
-+#include <asm/div64.h>
-+
-+extern struct list_head inode_unused;
-+
-+/* some random number */
-+#define HUGETLBFS_MAGIC 0x958458f6
-+
-+static struct super_operations hugetlbfs_ops;
-+static struct address_space_operations hugetlbfs_aops;
-+struct file_operations hugetlbfs_file_operations;
-+static struct inode_operations hugetlbfs_dir_inode_operations;
-+static struct inode_operations hugetlbfs_inode_operations;
-+
-+static inline int hugetlbfs_positive(struct dentry *dentry)
-+{
-+ return dentry->d_inode && ! d_unhashed(dentry);
-+}
-+
-+static int hugetlbfs_empty(struct dentry *dentry)
-+{
-+ struct list_head *list;
-+ spin_lock (&dcache_lock);
-+ list = dentry->d_subdirs.next;
-+ while (list != &dentry->d_subdirs) {
-+ struct dentry *de = list_entry(list, struct dentry, d_child);
-+ if (hugetlbfs_positive(de)) {
-+ spin_unlock(&dcache_lock);
-+ return 0;
-+ }
-+ list = list->next;
-+ }
-+ spin_unlock(&dcache_lock);
-+ return 1;
-+}
-+
-+int hugetlbfs_sync_file(struct file * file, struct dentry *dentry, int datasync)
-+{
-+ return 0;
-+}
-+static int hugetlbfs_statfs(struct super_block *sb, struct statfs *buf)
-+{
-+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
-+
-+ if (sbinfo) {
-+ spin_lock(&sbinfo->stat_lock);
-+ buf->f_blocks = sbinfo->max_blocks;
-+ buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
-+ buf->f_files = sbinfo->max_inodes;
-+ buf->f_ffree = sbinfo->free_inodes;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+ buf->f_type = HUGETLBFS_MAGIC;
-+ buf->f_bsize = HPAGE_SIZE;
-+ buf->f_namelen = NAME_MAX;
-+ return 0;
-+}
-+
-+static int hugetlbfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
-+{
-+ int error = - ENOTEMPTY;
-+
-+ if (hugetlbfs_empty(new_dentry)) {
-+ struct inode *inode = new_dentry->d_inode;
-+ if (inode) {
-+ inode->i_nlink--;
-+ dput(new_dentry);
-+ }
-+ old_dir->i_size -= PSEUDO_DIRENT_SIZE;
-+ new_dir->i_size += PSEUDO_DIRENT_SIZE;
-+ old_dir->i_ctime = old_dir->i_mtime =
-+ new_dir->i_ctime = new_dir->i_mtime =
-+ inode->i_ctime = CURRENT_TIME;
-+ error = 0;
-+ }
-+ return error;
-+}
-+static int hugetlbfs_unlink(struct inode *dir, struct dentry *dentry)
-+{
-+ struct inode *inode = dentry->d_inode;
-+
-+ if (!hugetlbfs_empty(dentry))
-+ return -ENOTEMPTY;
-+ dir->i_size -= PSEUDO_DIRENT_SIZE;
-+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-+ dentry->d_inode->i_nlink--;
-+ dput (dentry);
-+ return 0;
-+}
-+
-+#define hugetlbfs_rmdir hugetlbfs_unlink
-+
-+static int hugetlbfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
-+{
-+ struct inode *inode = old_dentry->d_inode;
-+ if (S_ISDIR(inode->i_mode))
-+ return -EPERM;
-+ dir->i_size += PSEUDO_DIRENT_SIZE;
-+ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-+ inode->i_nlink++;
-+ atomic_inc(&inode->i_count);
-+ dget(dentry);
-+ d_instantiate(dentry, inode);
-+ return 0;
-+}
-+
-+static struct dentry *hugetlbfs_lookup(struct inode *dir, struct dentry *dentry)
-+{
-+ d_add(dentry, NULL);
-+ return NULL;
-+}
-+
-+static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ struct inode *inode = file->f_dentry->d_inode;
-+ struct address_space *mapping = inode->i_mapping;
-+ loff_t len, vma_len;
-+ int ret;
-+
-+ if (vma->vm_start & ~HPAGE_MASK)
-+ return -EINVAL;
-+
-+ if (vma->vm_end & ~HPAGE_MASK)
-+ return -EINVAL;
-+
-+ if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
-+ return -EINVAL;
-+#ifdef CONFIG_IA64
-+ if (vma->vm_start < (REGION_HPAGE << REGION_SHIFT))
-+ return -EINVAL;
-+#endif
-+ vma_len = (loff_t)(vma->vm_end - vma->vm_start);
-+
-+ down(&inode->i_sem);
-+
-+ UPDATE_ATIME(inode);
-+ vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
-+ vma->vm_ops = &hugetlb_vm_ops;
-+ ret = hugetlb_prefault(mapping, vma);
-+ len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
-+ if (ret == 0 && inode->i_size < len)
-+ inode->i_size = len;
-+ up(&inode->i_sem);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Called under down_write(mmap_sem), page_table_lock is not held
-+ */
-+
-+#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
-+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-+ unsigned long len, unsigned long pgoff, unsigned long flags);
-+#else
-+static unsigned long
-+hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
-+ unsigned long len, unsigned long pgoff, unsigned long flags)
-+{
-+ struct mm_struct *mm = current->mm;
-+ struct vm_area_struct *vma;
-+
-+ if (len & ~HPAGE_MASK)
-+ return -EINVAL;
-+ if (len > TASK_SIZE)
-+ return -ENOMEM;
-+
-+ if (addr) {
-+ addr = COLOR_HALIGN(addr);
-+ vma = find_vma(mm, addr);
-+ if (TASK_SIZE - len >= addr &&
-+ (!vma || addr + len <= vma->vm_start))
-+ return addr;
-+ }
-+
-+ addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
-+
-+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
-+ /* At this point: (!vma || addr < vma->vm_end). */
-+ if (TASK_SIZE - len < addr)
-+ return -ENOMEM;
-+ if (!vma || addr + len <= vma->vm_start)
-+ return addr;
-+ addr = COLOR_HALIGN(vma->vm_end);
-+ }
-+}
-+#endif
-+
-+/*
-+ * Read a page. Again trivial. If it didn't already exist
-+ * in the page cache, it is zero-filled.
-+ */
-+static int hugetlbfs_readpage(struct file *file, struct page * page)
-+{
-+ return -EINVAL;
-+}
-+
-+static int hugetlbfs_prepare_write(struct file *file,
-+ struct page *page, unsigned offset, unsigned to)
-+{
-+ return -EINVAL;
-+}
-+
-+static int hugetlbfs_commit_write(struct file *file,
-+ struct page *page, unsigned offset, unsigned to)
-+{
-+ return -EINVAL;
-+}
-+
-+void truncate_huge_page(struct address_space *mapping, struct page *page)
-+{
-+ if (page->mapping != mapping)
-+ return;
-+
-+ ClearPageDirty(page);
-+ ClearPageUptodate(page);
-+ remove_inode_page(page);
-+ set_page_count(page, 1);
-+ huge_page_release(page);
-+}
-+
-+void truncate_hugepages(struct inode *inode, struct address_space *mapping, loff_t lstart)
-+{
-+ unsigned long start = lstart >> HPAGE_SHIFT;
-+ unsigned long next;
-+ unsigned long max_idx;
-+ struct page *page;
-+
-+ max_idx = inode->i_size >> HPAGE_SHIFT;
-+ next = start;
-+ while (next < max_idx) {
-+ page = find_lock_page(mapping, next);
-+ next++;
-+ if (page == NULL)
-+ continue;
-+ page_cache_release(page);
-+ truncate_huge_page(mapping, page);
-+ unlock_page(page);
-+ hugetlb_put_quota(mapping);
-+ }
-+}
-+
-+static void hugetlbfs_delete_inode(struct inode *inode)
-+{
-+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
-+
-+ list_del_init(&inode->i_hash);
-+ list_del_init(&inode->i_list);
-+ inode->i_state |= I_FREEING;
-+ inodes_stat.nr_inodes--;
-+
-+ if (inode->i_data.nrpages)
-+ truncate_hugepages(inode, &inode->i_data, 0);
-+ if (sbinfo->free_inodes >= 0) {
-+ spin_lock(&sbinfo->stat_lock);
-+ sbinfo->free_inodes++;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+
-+}
-+
-+static void hugetlbfs_forget_inode(struct inode *inode)
-+{
-+ struct super_block *super_block = inode->i_sb;
-+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
-+
-+ if (list_empty(&inode->i_hash))
-+ goto out_truncate;
-+
-+ if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
-+ list_del(&inode->i_list);
-+ list_add(&inode->i_list, &inode_unused);
-+ }
-+ inodes_stat.nr_unused++;
-+ if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
-+ return;
-+ }
-+
-+ /* write_inode_now() ? */
-+ inodes_stat.nr_unused--;
-+ list_del_init(&inode->i_hash);
-+out_truncate:
-+ list_del_init(&inode->i_list);
-+ inode->i_state |= I_FREEING;
-+ inodes_stat.nr_inodes--;
-+ if (inode->i_data.nrpages)
-+ truncate_hugepages(inode, &inode->i_data, 0);
-+
-+ if (sbinfo->free_inodes >= 0) {
-+ spin_lock(&sbinfo->stat_lock);
-+ sbinfo->free_inodes++;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+}
-+
-+static void hugetlbfs_drop_inode(struct inode *inode)
-+{
-+ if (!inode->i_nlink)
-+ hugetlbfs_delete_inode(inode);
-+ else
-+ hugetlbfs_forget_inode(inode);
-+}
-+
-+static void
-+hugetlb_vmtruncate_list(struct vm_area_struct *mpnt, unsigned long pgoff)
-+{
-+
-+ do {
-+ unsigned long h_vm_pgoff;
-+ unsigned long v_length;
-+ unsigned long h_length;
-+ unsigned long v_offset;
-+
-+ h_vm_pgoff = mpnt->vm_pgoff << (HPAGE_SHIFT - PAGE_SHIFT);
-+ v_length = mpnt->vm_end - mpnt->vm_start;
-+ h_length = v_length >> HPAGE_SHIFT;
-+ v_offset = (pgoff - h_vm_pgoff) << HPAGE_SHIFT;
-+
-+ /*
-+ * Is this VMA fully outside the truncation point?
-+ */
-+ if (h_vm_pgoff >= pgoff) {
-+ zap_hugepage_range(mpnt, mpnt->vm_start, v_length);
-+ continue;
-+ }
-+
-+ /*
-+ * Is this VMA fully inside the truncaton point?
-+ */
-+ if (h_vm_pgoff + (v_length >> HPAGE_SHIFT) <= pgoff)
-+ continue;
-+
-+ /*
-+ * The VMA straddles the truncation point. v_offset is the
-+ * offset (in bytes) into the VMA where the point lies.
-+ */
-+ zap_hugepage_range(mpnt,
-+ mpnt->vm_start + v_offset,
-+ v_length - v_offset);
-+ } while ((mpnt = mpnt->vm_next_share) != NULL);
-+}
-+
-+/*
-+ * Expanding truncates are not allowed.
-+ */
-+static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
-+{
-+ unsigned long pgoff;
-+ struct address_space *mapping = inode->i_mapping;
-+
-+ if (offset > inode->i_size)
-+ return -EINVAL;
-+
-+ BUG_ON(offset & ~HPAGE_MASK);
-+ pgoff = offset >> HPAGE_SHIFT;
-+
-+ spin_lock(&mapping->i_shared_lock);
-+ if (mapping->i_mmap != NULL)
-+ hugetlb_vmtruncate_list(mapping->i_mmap, pgoff);
-+ if (mapping->i_mmap_shared != NULL)
-+ hugetlb_vmtruncate_list(mapping->i_mmap_shared, pgoff);
-+
-+ spin_unlock(&mapping->i_shared_lock);
-+ truncate_hugepages(inode, mapping, offset);
-+ inode->i_size = offset;
-+ return 0;
-+}
-+
-+static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
-+{
-+ struct inode *inode = dentry->d_inode;
-+ int error;
-+ unsigned int ia_valid = attr->ia_valid;
-+
-+ BUG_ON(!inode);
-+
-+ error = inode_change_ok(inode, attr);
-+ if (error)
-+ goto out;
-+
-+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
-+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
-+ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
-+ if (error)
-+ goto out;
-+ if (ia_valid & ATTR_SIZE) {
-+ error = -EINVAL;
-+ if (!(attr->ia_size & ~HPAGE_MASK))
-+ error = hugetlb_vmtruncate(inode, attr->ia_size);
-+ if (error)
-+ goto out;
-+ attr->ia_valid &= ~ATTR_SIZE;
-+ }
-+ error = inode_setattr(inode, attr);
-+out:
-+ return error;
-+}
-+
-+static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
-+ gid_t gid, int mode, int dev)
-+{
-+ struct inode *inode;
-+ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
-+
-+ if (sbinfo->free_inodes >= 0) {
-+ spin_lock(&sbinfo->stat_lock);
-+ if (!sbinfo->free_inodes) {
-+ spin_unlock(&sbinfo->stat_lock);
-+ return NULL;
-+ }
-+ sbinfo->free_inodes--;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+
-+ inode = new_inode(sb);
-+ if (inode) {
-+ inode->i_mode = mode;
-+ inode->i_uid = uid;
-+ inode->i_gid = gid;
-+ inode->i_blksize = HPAGE_SIZE;
-+ inode->i_blocks = 0;
-+ inode->i_rdev = NODEV;
-+ inode->i_mapping->a_ops = &hugetlbfs_aops;
-+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
-+ switch (mode & S_IFMT) {
-+ default:
-+ init_special_inode(inode, mode, dev);
-+ break;
-+ case S_IFREG:
-+ inode->i_op = &hugetlbfs_inode_operations;
-+ inode->i_fop = &hugetlbfs_file_operations;
-+ break;
-+ case S_IFDIR:
-+ inode->i_op = &hugetlbfs_dir_inode_operations;
-+ inode->i_fop = &dcache_dir_ops;
-+
-+ break;
-+ case S_IFLNK:
-+ inode->i_op = &page_symlink_inode_operations;
-+ break;
-+ }
-+ }
-+ return inode;
-+}
-+
-+/*
-+ * File creation. Allocate an inode, and we're done..
-+ */
-+/* SMP-safe */
-+static int hugetlbfs_mknod(struct inode *dir,
-+ struct dentry *dentry, int mode, int dev)
-+{
-+ struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
-+ current->fsgid, mode, dev);
-+ int error = -ENOSPC;
-+
-+ if (inode) {
-+ dir->i_size += PSEUDO_DIRENT_SIZE;
-+ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
-+ d_instantiate(dentry, inode);
-+ dget(dentry); /* Extra count - pin the dentry in core */
-+ error = 0;
-+ }
-+ return error;
-+}
-+
-+static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-+{
-+ int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0);
-+// if (!retval)
-+ //dir->i_nlink++;
-+ return retval;
-+}
-+
-+static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode)
-+{
-+ return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0);
-+}
-+
-+static int hugetlbfs_symlink(struct inode *dir,
-+ struct dentry *dentry, const char *symname)
-+{
-+ int error = -ENOSPC;
-+
-+ error = hugetlbfs_mknod(dir, dentry, S_IFLNK|S_IRWXUGO, 0);
-+ if (!error) {
-+ int l = strlen(symname)+1;
-+ struct inode *inode = dentry->d_inode;
-+ error = block_symlink(inode, symname, l);
-+ }
-+ return error;
-+}
-+
-+static struct address_space_operations hugetlbfs_aops = {
-+ .readpage = hugetlbfs_readpage,
-+ .writepage = fail_writepage,
-+ .prepare_write = hugetlbfs_prepare_write,
-+ .commit_write = hugetlbfs_commit_write,
-+};
-+
-+struct file_operations hugetlbfs_file_operations = {
-+ .mmap = hugetlbfs_file_mmap,
-+ .fsync = hugetlbfs_sync_file,
-+ .get_unmapped_area = hugetlb_get_unmapped_area,
-+};
-+
-+static struct inode_operations hugetlbfs_dir_inode_operations = {
-+ .create = hugetlbfs_create,
-+ .lookup = hugetlbfs_lookup,
-+ .link = hugetlbfs_link,
-+ .unlink = hugetlbfs_unlink,
-+ .symlink = hugetlbfs_symlink,
-+ .mkdir = hugetlbfs_mkdir,
-+ .rmdir = hugetlbfs_rmdir,
-+ .mknod = hugetlbfs_mknod,
-+ .rename = hugetlbfs_rename,
-+ .setattr = hugetlbfs_setattr,
-+};
-+
-+static struct inode_operations hugetlbfs_inode_operations = {
-+ .setattr = hugetlbfs_setattr,
-+};
-+
-+static struct super_operations hugetlbfs_ops = {
-+ .statfs = hugetlbfs_statfs,
-+ .put_inode = hugetlbfs_drop_inode,
-+};
-+
-+static int hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
-+{
-+ char *opt, *value, *rest;
-+
-+ if (!options)
-+ return 0;
-+ while ((opt = strsep(&options, ",")) != NULL) {
-+ if (!*opt)
-+ continue;
-+
-+ value = strchr(opt, '=');
-+ if (!value || !*value)
-+ return -EINVAL;
-+ else
-+ *value++ = '\0';
-+
-+ if (!strcmp(opt, "uid"))
-+ pconfig->uid = simple_strtoul(value, &value, 0);
-+ else if (!strcmp(opt, "gid"))
-+ pconfig->gid = simple_strtoul(value, &value, 0);
-+ else if (!strcmp(opt, "mode"))
-+ pconfig->mode = simple_strtoul(value, &value, 0) & 0777U;
-+ else if (!strcmp(opt, "size")) {
-+ unsigned long long size = memparse(value, &rest);
-+ if (*rest == '%') {
-+ size <<= HPAGE_SHIFT;
-+ size *= htlbpage_max;
-+ do_div(size, 100);
-+ rest++;
-+ }
-+ size &= HPAGE_MASK;
-+ pconfig->nr_blocks = (size >> HPAGE_SHIFT) ;
-+ value = rest;
-+ } else if (!strcmp(opt,"nr_inodes")) {
-+ pconfig->nr_inodes = memparse(value, &rest);
-+ value = rest;
-+ } else
-+ return -EINVAL;
-+
-+ if (*value)
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static struct super_block *
-+hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
-+{
-+ struct inode * inode;
-+ struct dentry * root;
-+ struct hugetlbfs_config config;
-+ struct hugetlbfs_sb_info *sbinfo;
-+
-+ config.nr_blocks = -1; /* No limit on size by default. */
-+ config.nr_inodes = -1; /* No limit on number of inodes by default. */
-+ config.uid = current->fsuid;
-+ config.gid = current->fsgid;
-+ config.mode = 0755;
-+ if (hugetlbfs_parse_options(data, &config))
-+ return NULL;
-+
-+ sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
-+ if (!sbinfo)
-+ return NULL;
-+ sb->u.generic_sbp = sbinfo;
-+
-+ spin_lock_init(&sbinfo->stat_lock);
-+ sbinfo->max_blocks = config.nr_blocks;
-+ sbinfo->free_blocks = config.nr_blocks;
-+ sbinfo->max_inodes = config.nr_inodes;
-+ sbinfo->free_inodes = config.nr_inodes;
-+ sb->s_blocksize = HPAGE_SIZE;
-+ sb->s_blocksize_bits = HPAGE_SHIFT;
-+ sb->s_magic = HUGETLBFS_MAGIC;
-+ sb->s_op = &hugetlbfs_ops;
-+ inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
-+ S_IFDIR | config.mode, 0);
-+ if (!inode)
-+ goto out_free;
-+
-+ root = d_alloc_root(inode);
-+ if (!root) {
-+ iput(inode);
-+ goto out_free;
-+ }
-+ sb->s_root = root;
-+ return sb;
-+out_free:
-+ kfree(sbinfo);
-+ return NULL;
-+}
-+
-+static DECLARE_FSTYPE(hugetlbfs_fs_type, "hugetlbfs", hugetlbfs_fill_super, FS_LITTER);
-+
-+static struct vfsmount *hugetlbfs_vfsmount;
-+
-+static atomic_t hugetlbfs_counter = ATOMIC_INIT(0);
-+
-+struct file *hugetlb_zero_setup(size_t size)
-+{
-+ int error, n;
-+ struct file *file;
-+ struct inode *inode;
-+ struct dentry *dentry, *root;
-+ struct qstr quick_string;
-+ char buf[16];
-+
-+ if (!is_hugepage_mem_enough(size))
-+ return ERR_PTR(-ENOMEM);
-+ n = atomic_read(&hugetlbfs_counter);
-+ atomic_inc(&hugetlbfs_counter);
-+
-+ root = hugetlbfs_vfsmount->mnt_root;
-+ snprintf(buf, 16, "%d", n);
-+ quick_string.name = buf;
-+ quick_string.len = strlen(quick_string.name);
-+ quick_string.hash = 0;
-+ dentry = d_alloc(root, &quick_string);
-+ if (!dentry)
-+ return ERR_PTR(-ENOMEM);
-+
-+ error = -ENFILE;
-+ file = get_empty_filp();
-+ if (!file)
-+ goto out_dentry;
-+
-+ error = -ENOSPC;
-+ inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
-+ current->fsgid, S_IFREG | S_IRWXUGO, 0);
-+ if (!inode)
-+ goto out_file;
-+
-+ d_instantiate(dentry, inode);
-+ inode->i_size = size;
-+ inode->i_nlink = 0;
-+ file->f_vfsmnt = mntget(hugetlbfs_vfsmount);
-+ file->f_dentry = dentry;
-+ file->f_op = &hugetlbfs_file_operations;
-+ file->f_mode = FMODE_WRITE | FMODE_READ;
-+ return file;
-+
-+out_file:
-+ put_filp(file);
-+out_dentry:
-+ dput(dentry);
-+ return ERR_PTR(error);
-+}
-+
-+int hugetlb_get_quota(struct address_space * mapping)
-+{
-+ int ret = 0;
-+ struct hugetlbfs_sb_info *sbinfo =
-+ HUGETLBFS_SB(mapping->host->i_sb);
-+
-+ if (sbinfo->free_blocks > -1) {
-+ spin_lock(&sbinfo->stat_lock);
-+ if (sbinfo->free_blocks > 0)
-+ sbinfo->free_blocks--;
-+ else
-+ ret = -ENOMEM;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+
-+ return ret;
-+}
-+
-+void hugetlb_put_quota(struct address_space *mapping)
-+{
-+ struct hugetlbfs_sb_info *sbinfo =
-+ HUGETLBFS_SB(mapping->host->i_sb);
-+
-+ if (sbinfo->free_blocks > -1) {
-+ spin_lock(&sbinfo->stat_lock);
-+ sbinfo->free_blocks++;
-+ spin_unlock(&sbinfo->stat_lock);
-+ }
-+}
-+
-+static int __init init_hugetlbfs_fs(void)
-+{
-+ int error;
-+ struct vfsmount *vfsmount;
-+
-+ error = register_filesystem(&hugetlbfs_fs_type);
-+ if (error)
-+ return error;
-+
-+ vfsmount = kern_mount(&hugetlbfs_fs_type);
-+
-+ if (!IS_ERR(vfsmount)) {
-+ printk("Hugetlbfs mounted.\n");
-+ hugetlbfs_vfsmount = vfsmount;
-+ return 0;
-+ }
-+
-+ printk("Error in mounting hugetlbfs.\n");
-+ error = PTR_ERR(vfsmount);
-+ return error;
-+}
-+
-+static void __exit exit_hugetlbfs_fs(void)
-+{
-+ unregister_filesystem(&hugetlbfs_fs_type);
-+}
-+
-+module_init(init_hugetlbfs_fs)
-+module_exit(exit_hugetlbfs_fs)
-+
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.27/fs/inode.c /home/dannf/bk/linux-2.4-20040815/fs/inode.c
---- linux-2.4.27/fs/inode.c 2004-04-14 07:05:40.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/fs/inode.c 2004-08-15 05:16:41.000000000 -0600
-@@ -57,7 +57,7 @@
- */
-
- static LIST_HEAD(inode_in_use);
--static LIST_HEAD(inode_unused);
-+LIST_HEAD(inode_unused);
- static LIST_HEAD(inode_unused_pagecache);
- static struct list_head *inode_hashtable;
- static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
-diff -urN linux-2.4.27/fs/proc/array.c /home/dannf/bk/linux-2.4-20040815/fs/proc/array.c
---- linux-2.4.27/fs/proc/array.c 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/fs/proc/array.c 2004-08-15 05:07:08.000000000 -0600
-@@ -64,6 +64,7 @@
- #include <linux/proc_fs.h>
- #include <linux/ioport.h>
- #include <linux/mm.h>
-+#include <linux/hugetlb.h>
- #include <linux/pagemap.h>
- #include <linux/swap.h>
- #include <linux/slab.h>
-@@ -490,6 +491,18 @@
- pgd_t *pgd = pgd_offset(mm, vma->vm_start);
- int pages = 0, shared = 0, dirty = 0, total = 0;
-
-+ if (is_vm_hugetlb_page(vma)) {
-+ int num_pages = ((vma->vm_end - vma->vm_start)/PAGE_SIZE);
-+ resident +=num_pages;
-+ if (!(vma->vm_flags & VM_DONTCOPY))
-+ share += num_pages;
-+ if (vma->vm_flags & VM_WRITE)
-+ dt += num_pages;
-+ drs += num_pages;
-+ vma = vma->vm_next;
-+ continue;
-+
-+ }
- statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
- resident += pages;
- share += shared;
-diff -urN linux-2.4.27/fs/proc/proc_misc.c /home/dannf/bk/linux-2.4-20040815/fs/proc/proc_misc.c
---- linux-2.4.27/fs/proc/proc_misc.c 2004-08-07 17:26:06.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/fs/proc/proc_misc.c 2004-08-15 04:53:33.000000000 -0600
-@@ -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>
-@@ -210,6 +211,8 @@
- K(i.totalswap),
- K(i.freeswap));
-
-+ len += hugetlb_report_meminfo(page + len);
-+
- return proc_calc_metrics(page, start, off, count, eof, len);
- #undef B
- #undef K
-diff -urN linux-2.4.27/include/asm-generic/tlb.h /home/dannf/bk/linux-2.4-20040815/include/asm-generic/tlb.h
---- linux-2.4.27/include/asm-generic/tlb.h 2002-08-02 18:39:45.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-generic/tlb.h 2004-08-15 04:47:53.000000000 -0600
-@@ -31,15 +31,18 @@
- pte_t ptes[FREE_PTE_NR];
- } mmu_gather_t;
-
-+#ifndef local_mmu_gathers
- /* Users of the generic TLB shootdown code must declare this storage space. */
- extern mmu_gather_t mmu_gathers[NR_CPUS];
-+#define local_mmu_gathers &mmu_gathers[smp_processor_id()]
-+#endif
-
- /* tlb_gather_mmu
- * Return a pointer to an initialized mmu_gather_t.
- */
- static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm)
- {
-- mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()];
-+ mmu_gather_t *tlb = local_mmu_gathers;
-
- tlb->mm = mm;
- /* Use fast mode if there is only one user of this mm (this process) */
-diff -urN linux-2.4.27/include/asm-generic/xor.h /home/dannf/bk/linux-2.4-20040815/include/asm-generic/xor.h
---- linux-2.4.27/include/asm-generic/xor.h 2000-11-12 20:39:51.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-generic/xor.h 2004-08-15 05:13:03.000000000 -0600
-@@ -13,6 +13,8 @@
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-+#include <asm/processor.h>
-+
- static void
- xor_8regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
- {
-@@ -121,7 +123,7 @@
- d5 ^= p2[5];
- d6 ^= p2[6];
- d7 ^= p2[7];
-- p1[0] = d0; /* Store the result (in burts) */
-+ p1[0] = d0; /* Store the result (in bursts) */
- p1[1] = d1;
- p1[2] = d2;
- p1[3] = d3;
-@@ -166,7 +168,7 @@
- d5 ^= p3[5];
- d6 ^= p3[6];
- d7 ^= p3[7];
-- p1[0] = d0; /* Store the result (in burts) */
-+ p1[0] = d0; /* Store the result (in bursts) */
- p1[1] = d1;
- p1[2] = d2;
- p1[3] = d3;
-@@ -220,7 +222,7 @@
- d5 ^= p4[5];
- d6 ^= p4[6];
- d7 ^= p4[7];
-- p1[0] = d0; /* Store the result (in burts) */
-+ p1[0] = d0; /* Store the result (in bursts) */
- p1[1] = d1;
- p1[2] = d2;
- p1[3] = d3;
-@@ -283,7 +285,7 @@
- d5 ^= p5[5];
- d6 ^= p5[6];
- d7 ^= p5[7];
-- p1[0] = d0; /* Store the result (in burts) */
-+ p1[0] = d0; /* Store the result (in bursts) */
- p1[1] = d1;
- p1[2] = d2;
- p1[3] = d3;
-@@ -299,6 +301,382 @@
- } while (--lines > 0);
- }
-
-+static void
-+xor_8regs_p_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+ prefetchw(p1);
-+ prefetch(p2);
-+
-+ do {
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ once_more:
-+ p1[0] ^= p2[0];
-+ p1[1] ^= p2[1];
-+ p1[2] ^= p2[2];
-+ p1[3] ^= p2[3];
-+ p1[4] ^= p2[4];
-+ p1[5] ^= p2[5];
-+ p1[6] ^= p2[6];
-+ p1[7] ^= p2[7];
-+ p1 += 8;
-+ p2 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_8regs_p_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+
-+ do {
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ once_more:
-+ p1[0] ^= p2[0] ^ p3[0];
-+ p1[1] ^= p2[1] ^ p3[1];
-+ p1[2] ^= p2[2] ^ p3[2];
-+ p1[3] ^= p2[3] ^ p3[3];
-+ p1[4] ^= p2[4] ^ p3[4];
-+ p1[5] ^= p2[5] ^ p3[5];
-+ p1[6] ^= p2[6] ^ p3[6];
-+ p1[7] ^= p2[7] ^ p3[7];
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_8regs_p_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3, unsigned long *p4)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+ prefetch(p4);
-+
-+ do {
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ prefetch(p4+8);
-+ once_more:
-+ p1[0] ^= p2[0] ^ p3[0] ^ p4[0];
-+ p1[1] ^= p2[1] ^ p3[1] ^ p4[1];
-+ p1[2] ^= p2[2] ^ p3[2] ^ p4[2];
-+ p1[3] ^= p2[3] ^ p3[3] ^ p4[3];
-+ p1[4] ^= p2[4] ^ p3[4] ^ p4[4];
-+ p1[5] ^= p2[5] ^ p3[5] ^ p4[5];
-+ p1[6] ^= p2[6] ^ p3[6] ^ p4[6];
-+ p1[7] ^= p2[7] ^ p3[7] ^ p4[7];
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ p4 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_8regs_p_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+ prefetch(p4);
-+ prefetch(p5);
-+
-+ do {
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ prefetch(p4+8);
-+ prefetch(p5+8);
-+ once_more:
-+ p1[0] ^= p2[0] ^ p3[0] ^ p4[0] ^ p5[0];
-+ p1[1] ^= p2[1] ^ p3[1] ^ p4[1] ^ p5[1];
-+ p1[2] ^= p2[2] ^ p3[2] ^ p4[2] ^ p5[2];
-+ p1[3] ^= p2[3] ^ p3[3] ^ p4[3] ^ p5[3];
-+ p1[4] ^= p2[4] ^ p3[4] ^ p4[4] ^ p5[4];
-+ p1[5] ^= p2[5] ^ p3[5] ^ p4[5] ^ p5[5];
-+ p1[6] ^= p2[6] ^ p3[6] ^ p4[6] ^ p5[6];
-+ p1[7] ^= p2[7] ^ p3[7] ^ p4[7] ^ p5[7];
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ p4 += 8;
-+ p5 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_32regs_p_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+
-+ do {
-+ register long d0, d1, d2, d3, d4, d5, d6, d7;
-+
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ once_more:
-+ d0 = p1[0]; /* Pull the stuff into registers */
-+ d1 = p1[1]; /* ... in bursts, if possible. */
-+ d2 = p1[2];
-+ d3 = p1[3];
-+ d4 = p1[4];
-+ d5 = p1[5];
-+ d6 = p1[6];
-+ d7 = p1[7];
-+ d0 ^= p2[0];
-+ d1 ^= p2[1];
-+ d2 ^= p2[2];
-+ d3 ^= p2[3];
-+ d4 ^= p2[4];
-+ d5 ^= p2[5];
-+ d6 ^= p2[6];
-+ d7 ^= p2[7];
-+ p1[0] = d0; /* Store the result (in bursts) */
-+ p1[1] = d1;
-+ p1[2] = d2;
-+ p1[3] = d3;
-+ p1[4] = d4;
-+ p1[5] = d5;
-+ p1[6] = d6;
-+ p1[7] = d7;
-+ p1 += 8;
-+ p2 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_32regs_p_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+
-+ do {
-+ register long d0, d1, d2, d3, d4, d5, d6, d7;
-+
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ once_more:
-+ d0 = p1[0]; /* Pull the stuff into registers */
-+ d1 = p1[1]; /* ... in bursts, if possible. */
-+ d2 = p1[2];
-+ d3 = p1[3];
-+ d4 = p1[4];
-+ d5 = p1[5];
-+ d6 = p1[6];
-+ d7 = p1[7];
-+ d0 ^= p2[0];
-+ d1 ^= p2[1];
-+ d2 ^= p2[2];
-+ d3 ^= p2[3];
-+ d4 ^= p2[4];
-+ d5 ^= p2[5];
-+ d6 ^= p2[6];
-+ d7 ^= p2[7];
-+ d0 ^= p3[0];
-+ d1 ^= p3[1];
-+ d2 ^= p3[2];
-+ d3 ^= p3[3];
-+ d4 ^= p3[4];
-+ d5 ^= p3[5];
-+ d6 ^= p3[6];
-+ d7 ^= p3[7];
-+ p1[0] = d0; /* Store the result (in bursts) */
-+ p1[1] = d1;
-+ p1[2] = d2;
-+ p1[3] = d3;
-+ p1[4] = d4;
-+ p1[5] = d5;
-+ p1[6] = d6;
-+ p1[7] = d7;
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_32regs_p_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3, unsigned long *p4)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+ prefetch(p4);
-+
-+ do {
-+ register long d0, d1, d2, d3, d4, d5, d6, d7;
-+
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ prefetch(p4+8);
-+ once_more:
-+ d0 = p1[0]; /* Pull the stuff into registers */
-+ d1 = p1[1]; /* ... in bursts, if possible. */
-+ d2 = p1[2];
-+ d3 = p1[3];
-+ d4 = p1[4];
-+ d5 = p1[5];
-+ d6 = p1[6];
-+ d7 = p1[7];
-+ d0 ^= p2[0];
-+ d1 ^= p2[1];
-+ d2 ^= p2[2];
-+ d3 ^= p2[3];
-+ d4 ^= p2[4];
-+ d5 ^= p2[5];
-+ d6 ^= p2[6];
-+ d7 ^= p2[7];
-+ d0 ^= p3[0];
-+ d1 ^= p3[1];
-+ d2 ^= p3[2];
-+ d3 ^= p3[3];
-+ d4 ^= p3[4];
-+ d5 ^= p3[5];
-+ d6 ^= p3[6];
-+ d7 ^= p3[7];
-+ d0 ^= p4[0];
-+ d1 ^= p4[1];
-+ d2 ^= p4[2];
-+ d3 ^= p4[3];
-+ d4 ^= p4[4];
-+ d5 ^= p4[5];
-+ d6 ^= p4[6];
-+ d7 ^= p4[7];
-+ p1[0] = d0; /* Store the result (in bursts) */
-+ p1[1] = d1;
-+ p1[2] = d2;
-+ p1[3] = d3;
-+ p1[4] = d4;
-+ p1[5] = d5;
-+ p1[6] = d6;
-+ p1[7] = d7;
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ p4 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
-+static void
-+xor_32regs_p_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
-+ unsigned long *p3, unsigned long *p4, unsigned long *p5)
-+{
-+ long lines = bytes / (sizeof (long)) / 8 - 1;
-+
-+ prefetchw(p1);
-+ prefetch(p2);
-+ prefetch(p3);
-+ prefetch(p4);
-+ prefetch(p5);
-+
-+ do {
-+ register long d0, d1, d2, d3, d4, d5, d6, d7;
-+
-+ prefetchw(p1+8);
-+ prefetch(p2+8);
-+ prefetch(p3+8);
-+ prefetch(p4+8);
-+ prefetch(p5+8);
-+ once_more:
-+ d0 = p1[0]; /* Pull the stuff into registers */
-+ d1 = p1[1]; /* ... in bursts, if possible. */
-+ d2 = p1[2];
-+ d3 = p1[3];
-+ d4 = p1[4];
-+ d5 = p1[5];
-+ d6 = p1[6];
-+ d7 = p1[7];
-+ d0 ^= p2[0];
-+ d1 ^= p2[1];
-+ d2 ^= p2[2];
-+ d3 ^= p2[3];
-+ d4 ^= p2[4];
-+ d5 ^= p2[5];
-+ d6 ^= p2[6];
-+ d7 ^= p2[7];
-+ d0 ^= p3[0];
-+ d1 ^= p3[1];
-+ d2 ^= p3[2];
-+ d3 ^= p3[3];
-+ d4 ^= p3[4];
-+ d5 ^= p3[5];
-+ d6 ^= p3[6];
-+ d7 ^= p3[7];
-+ d0 ^= p4[0];
-+ d1 ^= p4[1];
-+ d2 ^= p4[2];
-+ d3 ^= p4[3];
-+ d4 ^= p4[4];
-+ d5 ^= p4[5];
-+ d6 ^= p4[6];
-+ d7 ^= p4[7];
-+ d0 ^= p5[0];
-+ d1 ^= p5[1];
-+ d2 ^= p5[2];
-+ d3 ^= p5[3];
-+ d4 ^= p5[4];
-+ d5 ^= p5[5];
-+ d6 ^= p5[6];
-+ d7 ^= p5[7];
-+ p1[0] = d0; /* Store the result (in bursts) */
-+ p1[1] = d1;
-+ p1[2] = d2;
-+ p1[3] = d3;
-+ p1[4] = d4;
-+ p1[5] = d5;
-+ p1[6] = d6;
-+ p1[7] = d7;
-+ p1 += 8;
-+ p2 += 8;
-+ p3 += 8;
-+ p4 += 8;
-+ p5 += 8;
-+ } while (--lines > 0);
-+ if (lines == 0)
-+ goto once_more;
-+}
-+
- static struct xor_block_template xor_block_8regs = {
- name: "8regs",
- do_2: xor_8regs_2,
-@@ -315,8 +693,26 @@
- do_5: xor_32regs_5,
- };
-
-+static struct xor_block_template xor_block_8regs_p = {
-+ name: "8regs_prefetch",
-+ do_2: xor_8regs_p_2,
-+ do_3: xor_8regs_p_3,
-+ do_4: xor_8regs_p_4,
-+ do_5: xor_8regs_p_5,
-+};
-+
-+static struct xor_block_template xor_block_32regs_p = {
-+ name: "32regs_prefetch",
-+ do_2: xor_32regs_p_2,
-+ do_3: xor_32regs_p_3,
-+ do_4: xor_32regs_p_4,
-+ do_5: xor_32regs_p_5,
-+};
-+
- #define XOR_TRY_TEMPLATES \
- do { \
- xor_speed(&xor_block_8regs); \
-+ xor_speed(&xor_block_8regs_p); \
- xor_speed(&xor_block_32regs); \
-+ xor_speed(&xor_block_32regs_p); \
- } while (0)
-diff -urN linux-2.4.27/include/asm-i386/hw_irq.h /home/dannf/bk/linux-2.4-20040815/include/asm-i386/hw_irq.h
---- linux-2.4.27/include/asm-i386/hw_irq.h 2003-08-25 05:44:43.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-i386/hw_irq.h 2004-08-15 05:16:42.000000000 -0600
-@@ -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 -urN linux-2.4.27/include/asm-i386/page.h /home/dannf/bk/linux-2.4-20040815/include/asm-i386/page.h
---- linux-2.4.27/include/asm-i386/page.h 2002-08-02 18:39:45.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-i386/page.h 2004-08-15 04:54:15.000000000 -0600
-@@ -30,8 +30,8 @@
-
- #endif
-
--#define clear_user_page(page, vaddr) clear_page(page)
--#define copy_user_page(to, from, vaddr) copy_page(to, from)
-+#define clear_user_page(page, vaddr, pg) clear_page(page)
-+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
-
- /*
- * These are used to make use of C type-checking..
-@@ -137,6 +137,8 @@
- #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
-+#define is_invalid_hugepage_range(addr, len) 0
-+
- #endif /* __KERNEL__ */
-
- #endif /* _I386_PAGE_H */
-diff -urN linux-2.4.27/include/asm-i386/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-i386/pgtable.h
---- linux-2.4.27/include/asm-i386/pgtable.h 2002-11-28 16:53:15.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-i386/pgtable.h 2004-08-15 05:11:00.000000000 -0600
-@@ -302,6 +302,13 @@
- static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }
-
- /*
-+ * Macro to mark a page protection value as "uncacheable". On processors which do not support
-+ * it, this is a no-op.
-+ */
-+#define pgprot_noncached(prot) ((boot_cpu_data.x86 > 3) \
-+ ? (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) : (prot))
-+
-+/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-diff -urN linux-2.4.27/include/asm-i386/ptrace.h /home/dannf/bk/linux-2.4-20040815/include/asm-i386/ptrace.h
---- linux-2.4.27/include/asm-i386/ptrace.h 2001-09-14 15:04:08.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-i386/ptrace.h 2004-08-15 04:51:50.000000000 -0600
-@@ -58,6 +58,7 @@
- #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
- #define instruction_pointer(regs) ((regs)->eip)
- extern void show_regs(struct pt_regs *);
-+#define force_successful_syscall_return() do { } while (0)
- #endif
-
- #endif
-diff -urN linux-2.4.27/include/asm-ia64/page.h /home/dannf/bk/linux-2.4-20040815/include/asm-ia64/page.h
---- linux-2.4.27/include/asm-ia64/page.h 2004-04-14 07:05:40.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-ia64/page.h 2004-08-15 04:53:09.000000000 -0600
-@@ -59,6 +59,7 @@
- #endif
- #define RGN_MAP_LIMIT ((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE) /* per region addr limit */
-
-+
- #ifdef __ASSEMBLY__
- # define __pa(x) ((x) - PAGE_OFFSET)
- # define __va(x) ((x) + PAGE_OFFSET)
-diff -urN linux-2.4.27/include/asm-ia64/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-ia64/pgtable.h
---- linux-2.4.27/include/asm-ia64/pgtable.h 2004-02-18 06:36:32.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-ia64/pgtable.h 2004-08-15 04:58:13.000000000 -0600
-@@ -60,7 +60,8 @@
- #define _PAGE_PROTNONE (__IA64_UL(1) << 63)
-
- #define _PFN_MASK _PAGE_PPN_MASK
--#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_A | _PAGE_D)
-+/* Mask of bits which may be changed by pte_modify(); the odd bits are there for _PAGE_PROTNONE */
-+#define _PAGE_CHG_MASK (_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
-
- #define _PAGE_SIZE_4K 12
- #define _PAGE_SIZE_8K 13
-@@ -216,7 +217,7 @@
- ({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
-
- #define pte_modify(_pte, newprot) \
-- (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
-+ (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
-
- #define page_pte_prot(page,prot) mk_pte(page, prot)
- #define page_pte(page) page_pte_prot(page, __pgprot(0))
-diff -urN linux-2.4.27/include/asm-m68k/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-m68k/pgtable.h
---- linux-2.4.27/include/asm-m68k/pgtable.h 2004-02-18 06:36:32.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-m68k/pgtable.h 2004-08-15 05:13:43.000000000 -0600
-@@ -180,6 +180,24 @@
-
- #ifndef __ASSEMBLY__
- #include <asm-generic/pgtable.h>
-+
-+/*
-+ * Macro to mark a page protection value as "uncacheable".
-+ */
-+#ifdef SUN3_PAGE_NOCACHE
-+# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE
-+#else
-+# define __SUN3_PAGE_NOCACHE 0
-+#endif
-+#define pgprot_noncached(prot) \
-+ (MMU_IS_SUN3 \
-+ ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \
-+ : ((MMU_IS_851 || MMU_IS_030) \
-+ ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \
-+ : (MMU_IS_040 || MMU_IS_060) \
-+ ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
-+ : (prot)))
-+
- #endif /* !__ASSEMBLY__ */
-
- /*
-diff -urN linux-2.4.27/include/asm-ppc/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-ppc/pgtable.h
---- linux-2.4.27/include/asm-ppc/pgtable.h 2004-02-18 06:36:32.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-ppc/pgtable.h 2004-08-15 04:55:39.000000000 -0600
-@@ -587,6 +587,11 @@
- pte_update(ptep, 0, _PAGE_DIRTY);
- }
-
-+/*
-+ * Macro to mark a page protection value as "uncacheable".
-+ */
-+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
-+
- #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
-
- #define pmd_page(pmd) (pmd_val(pmd) & PAGE_MASK)
-diff -urN linux-2.4.27/include/asm-ppc64/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-ppc64/pgtable.h
---- linux-2.4.27/include/asm-ppc64/pgtable.h 2003-08-25 05:44:44.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-ppc64/pgtable.h 2004-08-15 04:48:43.000000000 -0600
-@@ -317,6 +317,11 @@
- pte_update(ptep, 0, _PAGE_DIRTY);
- }
-
-+/*
-+ * Macro to mark a page protection value as "uncacheable".
-+ */
-+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
-+
- #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
-
- /*
-diff -urN linux-2.4.27/include/asm-x86_64/pgtable.h /home/dannf/bk/linux-2.4-20040815/include/asm-x86_64/pgtable.h
---- linux-2.4.27/include/asm-x86_64/pgtable.h 2004-04-14 07:05:40.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/asm-x86_64/pgtable.h 2004-08-15 05:02:56.000000000 -0600
-@@ -342,6 +342,11 @@
- static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }
-
- /*
-+ * Macro to mark a page protection value as "uncacheable".
-+ */
-+#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
-+
-+/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-diff -urN linux-2.4.27/include/linux/agp_backend.h /home/dannf/bk/linux-2.4-20040815/include/linux/agp_backend.h
---- linux-2.4.27/include/linux/agp_backend.h 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/agp_backend.h 2004-08-15 05:12:11.000000000 -0600
-@@ -142,6 +142,7 @@
- size_t page_count;
- int num_scratch_pages;
- unsigned long *memory;
-+ void *vmptr;
- off_t pg_start;
- u32 type;
- u32 physical;
-diff -urN linux-2.4.27/include/linux/fs.h /home/dannf/bk/linux-2.4-20040815/include/linux/fs.h
---- linux-2.4.27/include/linux/fs.h 2004-08-07 17:26:06.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/fs.h 2004-08-15 04:56:38.000000000 -0600
-@@ -247,7 +247,7 @@
- /* First cache line: */
- struct buffer_head *b_next; /* Hash queue list */
- unsigned long b_blocknr; /* block number */
-- unsigned short b_size; /* block size */
-+ unsigned int b_size; /* block size */
- unsigned short b_list; /* List that this buffer appears */
- kdev_t b_dev; /* device (B_FREE = free) */
-
-diff -urN linux-2.4.27/include/linux/highmem.h /home/dannf/bk/linux-2.4-20040815/include/linux/highmem.h
---- linux-2.4.27/include/linux/highmem.h 2003-08-25 05:44:44.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/highmem.h 2004-08-15 05:11:11.000000000 -0600
-@@ -84,7 +84,7 @@
- static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
- {
- void *addr = kmap_atomic(page, KM_USER0);
-- clear_user_page(addr, vaddr);
-+ clear_user_page(addr, vaddr, page);
- kunmap_atomic(addr, KM_USER0);
- }
-
-@@ -116,7 +116,7 @@
-
- vfrom = kmap_atomic(from, KM_USER0);
- vto = kmap_atomic(to, KM_USER1);
-- copy_user_page(vto, vfrom, vaddr);
-+ copy_user_page(vto, vfrom, vaddr, to);
- kunmap_atomic(vfrom, KM_USER0);
- kunmap_atomic(vto, KM_USER1);
- }
-diff -urN linux-2.4.27/include/linux/hugetlb.h /home/dannf/bk/linux-2.4-20040815/include/linux/hugetlb.h
---- linux-2.4.27/include/linux/hugetlb.h 1969-12-31 17:00:00.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/hugetlb.h 2004-08-15 05:00:27.000000000 -0600
-@@ -0,0 +1,102 @@
-+#ifndef _LINUX_HUGETLB_H
-+#define _LINUX_HUGETLB_H
-+
-+#ifdef CONFIG_HUGETLB_PAGE
-+
-+#define COLOR_HALIGN(addr) ((addr + HPAGE_SIZE - 1) & ~(HPAGE_SIZE - 1))
-+struct ctl_table;
-+
-+static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
-+{
-+ return vma->vm_flags & VM_HUGETLB;
-+}
-+static inline int is_hugepage_addr(unsigned long addr)
-+{
-+ return (rgn_index(addr) == REGION_HPAGE);
-+}
-+
-+int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void *, size_t *);
-+int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
-+int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
-+void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
-+void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
-+int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
-+void huge_page_release(struct page *);
-+int hugetlb_report_meminfo(char *);
-+int is_hugepage_mem_enough(size_t);
-+int is_aligned_hugepage_range(unsigned long addr, unsigned long len);
-+void hugetlb_free_pgtables(struct mm_struct * mm, struct vm_area_struct * prev,
-+ unsigned long start, unsigned long end);
-+
-+extern int htlbpage_max;
-+
-+#else /* !CONFIG_HUGETLB_PAGE */
-+static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
-+{
-+ return 0;
-+}
-+
-+#define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; })
-+#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
-+#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
-+#define zap_hugepage_range(vma, start, len) BUG()
-+#define unmap_hugepage_range(vma, start, end) BUG()
-+#define huge_page_release(page) BUG()
-+#define hugetlb_report_meminfo(buf) 0
-+#define is_hugepage_mem_enough(size) 0
-+#define is_hugepage_addr(addr) 0
-+#define is_aligned_hugepage_range(addr, len) 0
-+#define hugetlb_free_pgtables(mm, prev, start, end) do { } while (0)
-+
-+#endif /* !CONFIG_HUGETLB_PAGE */
-+
-+#ifdef CONFIG_HUGETLBFS
-+struct hugetlbfs_config {
-+ uid_t uid;
-+ gid_t gid;
-+ umode_t mode;
-+ long nr_blocks;
-+ long nr_inodes;
-+};
-+
-+struct hugetlbfs_sb_info {
-+ long max_blocks; /* How many blocks are allowed */
-+ long free_blocks; /* How many are left for allocation */
-+ long max_inodes; /* How many inodes are allowed */
-+ long free_inodes; /* How many are left for allocation */
-+ spinlock_t stat_lock;
-+};
-+
-+static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
-+{
-+ return sb->u.generic_sbp;
-+}
-+
-+#define PSEUDO_DIRENT_SIZE 20
-+
-+extern struct file_operations hugetlbfs_file_operations;
-+extern struct vm_operations_struct hugetlb_vm_ops;
-+struct file *hugetlb_zero_setup(size_t);
-+int hugetlb_get_quota(struct address_space *mapping);
-+void hugetlb_put_quota(struct address_space *mapping);
-+
-+static inline int is_file_hugepages(struct file *file)
-+{
-+ return file->f_op == &hugetlbfs_file_operations;
-+}
-+
-+static inline void set_file_hugepages(struct file *file)
-+{
-+ file->f_op = &hugetlbfs_file_operations;
-+}
-+#else /* !CONFIG_HUGETLBFS */
-+
-+#define is_file_hugepages(file) 0
-+#define set_file_hugepages(file) BUG()
-+#define hugetlb_zero_setup(size) ERR_PTR(-ENOSYS)
-+#define hugetlb_get_quota(mapping) 0
-+#define hugetlb_put_quota(mapping) 0
-+
-+#endif /* !CONFIG_HUGETLBFS */
-+
-+#endif /* _LINUX_HUGETLB_H */
-diff -urN linux-2.4.27/include/linux/irq.h /home/dannf/bk/linux-2.4-20040815/include/linux/irq.h
---- linux-2.4.27/include/linux/irq.h 2002-08-02 18:39:45.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/irq.h 2004-08-15 05:01:29.000000000 -0600
-@@ -56,7 +56,7 @@
- *
- * Pad this out to 32 bytes for cache and indexing reasons.
- */
--typedef struct {
-+typedef struct irq_desc {
- unsigned int status; /* IRQ status */
- hw_irq_controller *handler;
- struct irqaction *action; /* IRQ action list */
-@@ -64,8 +64,6 @@
- spinlock_t lock;
- } ____cacheline_aligned irq_desc_t;
-
--extern irq_desc_t irq_desc [NR_IRQS];
--
- #include <asm/hw_irq.h> /* the arch dependent stuff */
-
- extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
-diff -urN linux-2.4.27/include/linux/irq_cpustat.h /home/dannf/bk/linux-2.4-20040815/include/linux/irq_cpustat.h
---- linux-2.4.27/include/linux/irq_cpustat.h 2001-11-22 12:46:18.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/irq_cpustat.h 2004-08-15 05:00:39.000000000 -0600
-@@ -23,15 +23,31 @@
- #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
- #else
- #define __IRQ_STAT(cpu, member) ((void)(cpu), irq_stat[0].member)
--#endif
-+#endif
-
- /* arch independent irq_stat fields */
- #define softirq_pending(cpu) __IRQ_STAT((cpu), __softirq_pending)
--#define local_irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count)
--#define local_bh_count(cpu) __IRQ_STAT((cpu), __local_bh_count)
-+#define irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count)
-+#define bh_count(cpu) __IRQ_STAT((cpu), __local_bh_count)
- #define syscall_count(cpu) __IRQ_STAT((cpu), __syscall_count)
- #define ksoftirqd_task(cpu) __IRQ_STAT((cpu), __ksoftirqd_task)
- /* arch dependent irq_stat fields */
- #define nmi_count(cpu) __IRQ_STAT((cpu), __nmi_count) /* i386, ia64 */
-
-+#define local_hardirq_trylock() hardirq_trylock(smp_processor_id())
-+#define local_hardirq_endlock() hardirq_trylock(smp_processor_id())
-+#define local_irq_enter(irq) irq_enter(smp_processor_id(), (irq))
-+#define local_irq_exit(irq) irq_exit(smp_processor_id(), (irq))
-+#define local_softirq_pending() softirq_pending(smp_processor_id())
-+#define local_ksoftirqd_task() ksoftirqd_task(smp_processor_id())
-+
-+/* These will lose the "really_" prefix when the interim macros below are removed. */
-+#define really_local_irq_count()irq_count(smp_processor_id())
-+#define really_local_bh_count() bh_count(smp_processor_id())
-+
-+/* Interim macros for backward compatibility. They are deprecated. Use irq_count() and
-+ bh_count() instead. --davidm 01/11/28 */
-+#define local_irq_count(cpu) irq_count(cpu)
-+#define local_bh_count(cpu) bh_count(cpu)
-+
- #endif /* __irq_cpustat_h */
-diff -urN linux-2.4.27/include/linux/mm.h /home/dannf/bk/linux-2.4-20040815/include/linux/mm.h
---- linux-2.4.27/include/linux/mm.h 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/mm.h 2004-08-15 04:50:47.000000000 -0600
-@@ -103,6 +103,9 @@
- #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
- #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
- #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
-+#define VM_WRITECOMBINED 0x00100000 /* Write-combined */
-+#define VM_NONCACHED 0x00200000 /* Noncached access */
-+#define VM_HUGETLB 0x00400000 /* Huge tlb Page*/
-
- #ifndef VM_STACK_FLAGS
- #define VM_STACK_FLAGS 0x00000177
-diff -urN linux-2.4.27/include/linux/mmzone.h /home/dannf/bk/linux-2.4-20040815/include/linux/mmzone.h
---- linux-2.4.27/include/linux/mmzone.h 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/mmzone.h 2004-08-15 04:49:27.000000000 -0600
-@@ -8,6 +8,12 @@
- #include <linux/spinlock.h>
- #include <linux/list.h>
- #include <linux/wait.h>
-+#ifdef CONFIG_DISCONTIGMEM
-+#include <asm/numnodes.h>
-+#endif
-+#ifndef MAX_NUMNODES
-+#define MAX_NUMNODES 1
-+#endif
-
- /*
- * Free memory management - zoned buddy allocator.
-@@ -134,7 +140,7 @@
- * footprint of this construct is very small.
- */
- typedef struct zonelist_struct {
-- zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
-+ zone_t * zones [MAX_NUMNODES*MAX_NR_ZONES+1]; // NULL delimited
- } zonelist_t;
-
- #define GFP_ZONEMASK 0x0f
-@@ -236,6 +242,18 @@
- #define for_each_zone(zone) \
- for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
-
-+#ifdef CONFIG_NUMA
-+#define MAX_NR_MEMBLKS BITS_PER_LONG /* Max number of Memory Blocks */
-+#include <asm/topology.h>
-+#else /* !CONFIG_NUMA */
-+#define MAX_NR_MEMBLKS 1
-+#endif /* CONFIG_NUMA */
-+
-+/* Returns the number of the current Node. */
-+
-+#ifndef CONFIG_NUMA
-+#define numa_node_id() (__cpu_to_node(smp_processor_id()))
-+#endif
-
- #ifndef CONFIG_DISCONTIGMEM
-
-diff -urN linux-2.4.27/include/linux/shm.h /home/dannf/bk/linux-2.4-20040815/include/linux/shm.h
---- linux-2.4.27/include/linux/shm.h 2001-11-22 12:46:18.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/shm.h 2004-08-15 05:10:40.000000000 -0600
-@@ -75,6 +75,7 @@
- /* shm_mode upper byte flags */
- #define SHM_DEST 01000 /* segment will be destroyed on last detach */
- #define SHM_LOCKED 02000 /* segment will not be swapped */
-+#define SHM_HUGETLB 04000 /* segment will use HugeTLB pages */
-
- asmlinkage long sys_shmget (key_t key, size_t size, int flag);
- asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
-diff -urN linux-2.4.27/include/linux/smp.h /home/dannf/bk/linux-2.4-20040815/include/linux/smp.h
---- linux-2.4.27/include/linux/smp.h 2001-11-22 12:46:19.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/smp.h 2004-08-15 05:06:11.000000000 -0600
-@@ -35,11 +35,6 @@
- extern void smp_boot_cpus(void);
-
- /*
-- * Processor call in. Must hold processors until ..
-- */
--extern void smp_callin(void);
--
--/*
- * Multiprocessors may now schedule
- */
- extern void smp_commence(void);
-@@ -57,10 +52,6 @@
-
- extern int smp_num_cpus;
-
--extern volatile unsigned long smp_msg_data;
--extern volatile int smp_src_cpu;
--extern volatile int smp_msg_id;
--
- #define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */
- #define MSG_ALL 0x8001
-
-@@ -86,6 +77,7 @@
- #define cpu_number_map(cpu) 0
- #define smp_call_function(func,info,retry,wait) ({ 0; })
- #define cpu_online_map 1
-+#define cpu_online(cpu) (cpu == 0)
-
- #endif
- #endif
-diff -urN linux-2.4.27/include/linux/sysctl.h /home/dannf/bk/linux-2.4-20040815/include/linux/sysctl.h
---- linux-2.4.27/include/linux/sysctl.h 2004-08-07 17:26:06.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/include/linux/sysctl.h 2004-08-15 04:49:07.000000000 -0600
-@@ -157,6 +157,7 @@
- VM_MAPPED_RATIO=20, /* amount of unfreeable pages that triggers swapout */
- VM_LAPTOP_MODE=21, /* kernel in laptop flush mode */
- VM_BLOCK_DUMP=22, /* dump fs activity to log */
-+ VM_HUGETLB_PAGES=23, /* int: Number of available Huge Pages */
- };
-
-
-diff -urN linux-2.4.27/init/main.c /home/dannf/bk/linux-2.4-20040815/init/main.c
---- linux-2.4.27/init/main.c 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/init/main.c 2004-08-15 04:54:32.000000000 -0600
-@@ -291,6 +291,7 @@
-
-
- extern void setup_arch(char **);
-+extern void __init build_all_zonelists(void);
- extern void cpu_idle(void);
-
- unsigned long wait_init_idle;
-@@ -361,6 +362,7 @@
- lock_kernel();
- printk(linux_banner);
- setup_arch(&command_line);
-+ build_all_zonelists();
- printk("Kernel command line: %s\n", saved_command_line);
- parse_options(command_line);
- trap_init();
-diff -urN linux-2.4.27/ipc/shm.c /home/dannf/bk/linux-2.4-20040815/ipc/shm.c
---- linux-2.4.27/ipc/shm.c 2002-08-02 18:39:46.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/ipc/shm.c 2004-08-15 05:04:46.000000000 -0600
-@@ -18,6 +18,7 @@
- #include <linux/config.h>
- #include <linux/slab.h>
- #include <linux/shm.h>
-+#include <linux/hugetlb.h>
- #include <linux/init.h>
- #include <linux/file.h>
- #include <linux/mman.h>
-@@ -125,7 +126,8 @@
- shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
- shm_rmid (shp->id);
- shm_unlock(shp->id);
-- shmem_lock(shp->shm_file, 0);
-+ if (!is_file_hugepages(shp->shm_file))
-+ shmem_lock(shp->shm_file, 0);
- fput (shp->shm_file);
- kfree (shp);
- }
-@@ -193,8 +195,12 @@
- shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
- if (!shp)
- return -ENOMEM;
-- sprintf (name, "SYSV%08x", key);
-- file = shmem_file_setup(name, size);
-+ if (shmflg & SHM_HUGETLB)
-+ file = hugetlb_zero_setup(size);
-+ else {
-+ sprintf (name, "SYSV%08x", key);
-+ file = shmem_file_setup(name, size);
-+ }
- error = PTR_ERR(file);
- if (IS_ERR(file))
- goto no_file;
-@@ -214,7 +220,10 @@
- shp->id = shm_buildid(id,shp->shm_perm.seq);
- shp->shm_file = file;
- file->f_dentry->d_inode->i_ino = shp->id;
-- file->f_op = &shm_file_operations;
-+ if (shmflg & SHM_HUGETLB)
-+ set_file_hugepages(file);
-+ else
-+ file->f_op = &shm_file_operations;
- shm_tot += numpages;
- shm_unlock (id);
- return shp->id;
-@@ -452,7 +461,10 @@
- tbuf.shm_ctime = shp->shm_ctim;
- tbuf.shm_cpid = shp->shm_cprid;
- tbuf.shm_lpid = shp->shm_lprid;
-- tbuf.shm_nattch = shp->shm_nattch;
-+ if (!is_file_hugepages(shp->shm_file))
-+ tbuf.shm_nattch = shp->shm_nattch;
-+ else
-+ tbuf.shm_nattch = file_count(shp->shm_file)-1;
- shm_unlock(shmid);
- if(copy_shmid_to_user (buf, &tbuf, version))
- return -EFAULT;
-@@ -474,10 +486,12 @@
- if(err)
- goto out_unlock;
- if(cmd==SHM_LOCK) {
-- shmem_lock(shp->shm_file, 1);
-+ if (!is_file_hugepages(shp->shm_file))
-+ shmem_lock(shp->shm_file, 1);
- shp->shm_flags |= SHM_LOCKED;
- } else {
-- shmem_lock(shp->shm_file, 0);
-+ if (!is_file_hugepages(shp->shm_file))
-+ shmem_lock(shp->shm_file, 0);
- shp->shm_flags &= ~SHM_LOCKED;
- }
- shm_unlock(shmid);
-@@ -678,7 +692,7 @@
- down_write(&mm->mmap_sem);
- for (shmd = mm->mmap; shmd; shmd = shmdnext) {
- shmdnext = shmd->vm_next;
-- if (shmd->vm_ops == &shm_vm_ops
-+ if (((shmd->vm_ops == &shm_vm_ops) || is_vm_hugetlb_page(shmd))
- && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
- do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
- retval = 0;
-@@ -718,7 +732,7 @@
- shp->shm_segsz,
- shp->shm_cprid,
- shp->shm_lprid,
-- shp->shm_nattch,
-+ is_file_hugepages(shp->shm_file) ? (file_count(shp->shm_file)-1) : shp->shm_nattch,
- shp->shm_perm.uid,
- shp->shm_perm.gid,
- shp->shm_perm.cuid,
-diff -urN linux-2.4.27/kernel/printk.c /home/dannf/bk/linux-2.4-20040815/kernel/printk.c
---- linux-2.4.27/kernel/printk.c 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/printk.c 2004-08-15 05:17:18.000000000 -0600
-@@ -330,6 +330,12 @@
- __call_console_drivers(start, end);
- }
- }
-+#ifdef CONFIG_IA64_EARLY_PRINTK
-+ if (!console_drivers) {
-+ void early_printk (const char *str, size_t len);
-+ early_printk(&LOG_BUF(start), end - start);
-+ }
-+#endif
- }
-
- /*
-@@ -696,3 +702,101 @@
- tty->driver.write(tty, 0, msg, strlen(msg));
- return;
- }
-+
-+#ifdef CONFIG_IA64_EARLY_PRINTK
-+
-+#include <asm/io.h>
-+
-+#ifdef CONFIG_IA64_EARLY_PRINTK_UART
-+
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+
-+static void early_printk_uart(const char *str, size_t len)
-+{
-+ static char *uart = 0;
-+ unsigned long uart_base;
-+ char c;
-+
-+ if (!uart) {
-+#ifdef CONFIG_SERIAL_HCDP
-+ extern unsigned long hcdp_early_uart(void);
-+ uart_base = hcdp_early_uart();
-+#endif
-+#if CONFIG_IA64_EARLY_PRINTK_UART_BASE
-+ uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE;
-+#endif
-+ if (uart_base)
-+ uart = ioremap(uart_base, 64);
-+ }
-+
-+ if (!uart)
-+ return;
-+
-+ while (len-- > 0) {
-+ c = *str++;
-+ while (!(UART_LSR_TEMT & readb(uart + UART_LSR)))
-+ ; /* spin */
-+
-+ writeb(c, uart + UART_TX);
-+
-+ if (c == '\n')
-+ writeb('\r', uart + UART_TX);
-+ }
-+}
-+#endif /* CONFIG_IA64_EARLY_PRINTK_UART */
-+
-+#ifdef CONFIG_IA64_EARLY_PRINTK_VGA
-+
-+#define VGABASE ((char *)0xc0000000000b8000)
-+#define VGALINES 24
-+#define VGACOLS 80
-+
-+static int current_ypos = VGALINES, current_xpos = 0;
-+
-+static void early_printk_vga(const char *str, size_t len)
-+{
-+ char c;
-+ int i, k, j;
-+
-+ while (len-- > 0) {
-+ c = *str++;
-+ if (current_ypos >= VGALINES) {
-+ /* scroll 1 line up */
-+ for (k = 1, j = 0; k < VGALINES; k++, j++) {
-+ for (i = 0; i < VGACOLS; i++) {
-+ writew(readw(VGABASE + 2*(VGACOLS*k + i)),
-+ VGABASE + 2*(VGACOLS*j + i));
-+ }
-+ }
-+ for (i = 0; i < VGACOLS; i++) {
-+ writew(0x720, VGABASE + 2*(VGACOLS*j + i));
-+ }
-+ current_ypos = VGALINES-1;
-+ }
-+ if (c == '\n') {
-+ current_xpos = 0;
-+ current_ypos++;
-+ } else if (c != '\r') {
-+ writew(((0x7 << 8) | (unsigned short) c),
-+ VGABASE + 2*(VGACOLS*current_ypos + current_xpos++));
-+ if (current_xpos >= VGACOLS) {
-+ current_xpos = 0;
-+ current_ypos++;
-+ }
-+ }
-+ }
-+}
-+#endif /* CONFIG_IA64_EARLY_PRINTK_VGA */
-+
-+void early_printk(const char *str, size_t len)
-+{
-+#ifdef CONFIG_IA64_EARLY_PRINTK_UART
-+ early_printk_uart(str, len);
-+#endif
-+#ifdef CONFIG_IA64_EARLY_PRINTK_VGA
-+ early_printk_vga(str, len);
-+#endif
-+}
-+
-+#endif /* CONFIG_IA64_EARLY_PRINTK */
-diff -urN linux-2.4.27/kernel/signal.c /home/dannf/bk/linux-2.4-20040815/kernel/signal.c
---- linux-2.4.27/kernel/signal.c 2004-02-18 06:36:32.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/signal.c 2004-08-15 05:01:02.000000000 -0600
-@@ -1171,8 +1171,19 @@
- ss_sp = NULL;
- } else {
- error = -ENOMEM;
-+#ifdef __ia64__
-+ /*
-+ * XXX fix me: due to an oversight, MINSIGSTKSZ used to be defined
-+ * as 2KB, which is far too small. This was after Linux kernel
-+ * 2.4.9 but since there are a fair number of ia64 apps out there,
-+ * we continue to allow "too" small sigaltstacks for a while.
-+ */
-+ if (ss_size < 2048)
-+ goto out;
-+#else
- if (ss_size < MINSIGSTKSZ)
- goto out;
-+#endif
- }
-
- current->sas_ss_sp = (unsigned long) ss_sp;
-diff -urN linux-2.4.27/kernel/softirq.c /home/dannf/bk/linux-2.4-20040815/kernel/softirq.c
---- linux-2.4.27/kernel/softirq.c 2002-11-28 16:53:15.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/softirq.c 2004-08-15 04:56:23.000000000 -0600
-@@ -40,7 +40,10 @@
- - Bottom halves: globally serialized, grr...
- */
-
-+/* No separate irq_stat for ia64, it is part of PSA */
-+#if !defined(CONFIG_IA64)
- irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
-+#endif
-
- static struct softirq_action softirq_vec[32] __cacheline_aligned;
-
-@@ -60,7 +63,6 @@
-
- asmlinkage void do_softirq()
- {
-- int cpu = smp_processor_id();
- __u32 pending;
- unsigned long flags;
- __u32 mask;
-@@ -70,7 +72,7 @@
-
- local_irq_save(flags);
-
-- pending = softirq_pending(cpu);
-+ pending = local_softirq_pending();
-
- if (pending) {
- struct softirq_action *h;
-@@ -79,7 +81,7 @@
- local_bh_disable();
- restart:
- /* Reset the pending bitmask before enabling irqs */
-- softirq_pending(cpu) = 0;
-+ local_softirq_pending() = 0;
-
- local_irq_enable();
-
-@@ -94,7 +96,7 @@
-
- local_irq_disable();
-
-- pending = softirq_pending(cpu);
-+ pending = local_softirq_pending();
- if (pending & mask) {
- mask &= ~pending;
- goto restart;
-@@ -102,7 +104,7 @@
- __local_bh_enable();
-
- if (pending)
-- wakeup_softirqd(cpu);
-+ wakeup_softirqd(smp_processor_id());
- }
-
- local_irq_restore(flags);
-@@ -124,7 +126,7 @@
- * Otherwise we wake up ksoftirqd to make sure we
- * schedule the softirq soon.
- */
-- if (!(local_irq_count(cpu) | local_bh_count(cpu)))
-+ if (!(irq_count(cpu) | bh_count(cpu)))
- wakeup_softirqd(cpu);
- }
-
-@@ -287,18 +289,16 @@
-
- static void bh_action(unsigned long nr)
- {
-- int cpu = smp_processor_id();
--
- if (!spin_trylock(&global_bh_lock))
- goto resched;
-
-- if (!hardirq_trylock(cpu))
-+ if (!local_hardirq_trylock())
- goto resched_unlock;
-
- if (bh_base[nr])
- bh_base[nr]();
-
-- hardirq_endlock(cpu);
-+ local_hardirq_endlock();
- spin_unlock(&global_bh_lock);
- return;
-
-@@ -377,15 +377,15 @@
- __set_current_state(TASK_INTERRUPTIBLE);
- mb();
-
-- ksoftirqd_task(cpu) = current;
-+ local_ksoftirqd_task() = current;
-
- for (;;) {
-- if (!softirq_pending(cpu))
-+ if (!local_softirq_pending())
- schedule();
-
- __set_current_state(TASK_RUNNING);
-
-- while (softirq_pending(cpu)) {
-+ while (local_softirq_pending()) {
- do_softirq();
- if (current->need_resched)
- schedule();
-diff -urN linux-2.4.27/kernel/sysctl.c /home/dannf/bk/linux-2.4-20040815/kernel/sysctl.c
---- linux-2.4.27/kernel/sysctl.c 2004-08-07 17:26:06.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/sysctl.c 2004-08-15 04:52:45.000000000 -0600
-@@ -31,6 +31,7 @@
- #include <linux/sysrq.h>
- #include <linux/highuid.h>
- #include <linux/swap.h>
-+#include <linux/hugetlb.h>
-
- #include <asm/uaccess.h>
-
-@@ -315,6 +316,10 @@
- &laptop_mode, sizeof(int), 0644, NULL, &proc_dointvec},
- {VM_BLOCK_DUMP, "block_dump",
- &block_dump, 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}
- };
-
-diff -urN linux-2.4.27/kernel/time.c /home/dannf/bk/linux-2.4-20040815/kernel/time.c
---- linux-2.4.27/kernel/time.c 2002-11-28 16:53:15.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/time.c 2004-08-15 04:55:55.000000000 -0600
-@@ -39,6 +39,7 @@
- /* The xtime_lock is not only serializing the xtime read/writes but it's also
- serializing all accesses to the global NTP variables now. */
- extern rwlock_t xtime_lock;
-+extern unsigned long last_time_offset;
-
- #if !defined(__alpha__) && !defined(__ia64__)
-
-@@ -84,6 +85,7 @@
- xtime.tv_sec = value;
- xtime.tv_usec = 0;
- vxtime_unlock();
-+ last_time_offset = 0;
- time_adjust = 0; /* stop active adjtime() */
- time_status |= STA_UNSYNC;
- time_maxerror = NTP_PHASE_LIMIT;
-@@ -131,6 +133,7 @@
- vxtime_lock();
- xtime.tv_sec += sys_tz.tz_minuteswest * 60;
- vxtime_unlock();
-+ last_time_offset = 0;
- write_unlock_irq(&xtime_lock);
- }
-
-@@ -217,7 +220,7 @@
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
--
-+
- /* Now we validate the data before disabling interrupts */
-
- if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
-@@ -228,7 +231,7 @@
- if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
- /* adjustment Offset limited to +- .512 seconds */
- if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
-- return -EINVAL;
-+ return -EINVAL;
-
- /* if the quartz is off by more than 10% something is VERY wrong ! */
- if (txc->modes & ADJ_TICK)
-@@ -365,7 +368,7 @@
- && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
- /* p. 24, (d) */
- result = TIME_ERROR;
--
-+
- if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
- txc->offset = save_adjust;
- else {
-@@ -390,6 +393,7 @@
- txc->calcnt = pps_calcnt;
- txc->errcnt = pps_errcnt;
- txc->stbcnt = pps_stbcnt;
-+ last_time_offset = 0;
- write_unlock_irq(&xtime_lock);
- do_gettimeofday(&txc->time);
- return(result);
-diff -urN linux-2.4.27/kernel/timer.c /home/dannf/bk/linux-2.4-20040815/kernel/timer.c
---- linux-2.4.27/kernel/timer.c 2002-11-28 16:53:15.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/kernel/timer.c 2004-08-15 04:57:38.000000000 -0600
-@@ -615,7 +615,7 @@
- else
- kstat.per_cpu_user[cpu] += user_tick;
- kstat.per_cpu_system[cpu] += system;
-- } else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
-+ } else if (really_local_bh_count() || really_local_irq_count() > 1)
- kstat.per_cpu_system[cpu] += system;
- }
-
-@@ -667,6 +667,7 @@
- * This spinlock protect us from races in SMP while playing with xtime. -arca
- */
- rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
-+unsigned long last_time_offset;
-
- static inline void update_times(void)
- {
-@@ -686,6 +687,7 @@
- update_wall_time(ticks);
- }
- vxtime_unlock();
-+ last_time_offset = 0;
- write_unlock_irq(&xtime_lock);
- calc_load(ticks);
- }
-@@ -698,7 +700,7 @@
-
- void do_timer(struct pt_regs *regs)
- {
-- (*(unsigned long *)&jiffies)++;
-+ (*(volatile unsigned long *)&jiffies)++;
- #ifndef CONFIG_SMP
- /* SMP process accounting uses the local APIC timer */
-
-@@ -844,7 +846,7 @@
- if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
- return -EINVAL;
-
--
-+#if !defined(__ia64__)
- if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
- current->policy != SCHED_OTHER)
- {
-@@ -857,6 +859,7 @@
- udelay((t.tv_nsec + 999) / 1000);
- return 0;
- }
-+#endif
-
- expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
-
-diff -urN linux-2.4.27/mm/bootmem.c /home/dannf/bk/linux-2.4-20040815/mm/bootmem.c
---- linux-2.4.27/mm/bootmem.c 2002-11-28 16:53:15.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/mm/bootmem.c 2004-08-15 04:58:25.000000000 -0600
-@@ -49,8 +49,24 @@
- bootmem_data_t *bdata = pgdat->bdata;
- unsigned long mapsize = ((end - start)+7)/8;
-
-- pgdat->node_next = pgdat_list;
-- pgdat_list = pgdat;
-+
-+ /*
-+ * sort pgdat_list so that the lowest one comes first,
-+ * which makes alloc_bootmem_low_pages work as desired.
-+ */
-+ if (!pgdat_list || pgdat_list->node_start_paddr > pgdat->node_start_paddr) {
-+ pgdat->node_next = pgdat_list;
-+ pgdat_list = pgdat;
-+ } else {
-+ pg_data_t *tmp = pgdat_list;
-+ while (tmp->node_next) {
-+ if (tmp->node_next->node_start_paddr > pgdat->node_start_paddr)
-+ break;
-+ tmp = tmp->node_next;
-+ }
-+ pgdat->node_next = tmp->node_next;
-+ tmp->node_next = pgdat;
-+ }
-
- mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
- bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
-@@ -144,6 +160,7 @@
- static void * __init __alloc_bootmem_core (bootmem_data_t *bdata,
- unsigned long size, unsigned long align, unsigned long goal)
- {
-+ static unsigned long last_success;
- unsigned long i, start = 0;
- void *ret;
- unsigned long offset, remaining_size;
-@@ -169,6 +186,9 @@
- if (goal && (goal >= bdata->node_boot_start) &&
- ((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
- preferred = goal - bdata->node_boot_start;
-+
-+ if (last_success >= preferred)
-+ preferred = last_success;
- } else
- preferred = 0;
-
-@@ -180,6 +200,8 @@
- restart_scan:
- for (i = preferred; i < eidx; i += incr) {
- unsigned long j;
-+ i = find_next_zero_bit((char *)bdata->node_bootmem_map, eidx, i);
-+ i = (i + incr - 1) & -incr;
- if (test_bit(i, bdata->node_bootmem_map))
- continue;
- for (j = i + 1; j < i + areasize; ++j) {
-@@ -198,6 +220,7 @@
- }
- return NULL;
- found:
-+ last_success = start << PAGE_SHIFT;
- if (start >= eidx)
- BUG();
-
-@@ -244,22 +267,24 @@
-
- static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
- {
-- struct page *page = pgdat->node_mem_map;
- bootmem_data_t *bdata = pgdat->bdata;
- unsigned long i, count, total = 0;
-+ struct page *page;
- unsigned long idx;
-
- if (!bdata->node_bootmem_map) BUG();
-
- count = 0;
-+ page = virt_to_page(phys_to_virt(bdata->node_boot_start));
- idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
-- for (i = 0; i < idx; i++, page++) {
-- if (!test_bit(i, bdata->node_bootmem_map)) {
-- count++;
-- ClearPageReserved(page);
-- set_page_count(page, 1);
-- __free_page(page);
-- }
-+ for (i = find_first_zero_bit(bdata->node_bootmem_map, idx);
-+ i < idx;
-+ i = find_next_zero_bit(bdata->node_bootmem_map, idx, i + 1))
-+ {
-+ count++;
-+ ClearPageReserved(page+i);
-+ set_page_count(page+i, 1);
-+ __free_page(page+i);
- }
- total += count;
-
-diff -urN linux-2.4.27/mm/memory.c /home/dannf/bk/linux-2.4-20040815/mm/memory.c
---- linux-2.4.27/mm/memory.c 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/mm/memory.c 2004-08-15 05:03:11.000000000 -0600
-@@ -37,6 +37,7 @@
- */
-
- #include <linux/mm.h>
-+#include <linux/hugetlb.h>
- #include <linux/mman.h>
- #include <linux/swap.h>
- #include <linux/smp_lock.h>
-@@ -121,7 +122,7 @@
- pmd = pmd_offset(dir, 0);
- pgd_clear(dir);
- for (j = 0; j < PTRS_PER_PMD ; j++) {
-- prefetchw(pmd+j+(PREFETCH_STRIDE/16));
-+ prefetchw(pmd + j + PREFETCH_STRIDE/sizeof(*pmd));
- free_one_pmd(pmd+j);
- }
- pmd_free(pmd);
-@@ -181,6 +182,9 @@
- unsigned long end = vma->vm_end;
- unsigned long cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
-
-+ if (is_vm_hugetlb_page(vma))
-+ return copy_hugetlb_page_range(dst, src, vma);
-+
- src_pgd = pgd_offset(src, address)-1;
- dst_pgd = pgd_offset(dst, address)-1;
-
-@@ -473,6 +477,10 @@
- if ( !vma || (pages && vma->vm_flags & VM_IO) || !(flags & vma->vm_flags) )
- return i ? : -EFAULT;
-
-+ if (is_vm_hugetlb_page(vma)) {
-+ i = follow_hugetlb_page(mm, vma, pages, vmas, &start, &len, i);
-+ continue;
-+ }
- spin_lock(&mm->page_table_lock);
- do {
- struct page *map;
-@@ -1371,6 +1379,9 @@
- current->state = TASK_RUNNING;
- pgd = pgd_offset(mm, address);
-
-+ if (is_vm_hugetlb_page(vma))
-+ return 0; /* mapping truncation does this. */
-+
- /*
- * We need the page table lock to synchronize with kswapd
- * and the SMP-safe atomic PTE updates.
-diff -urN linux-2.4.27/mm/mmap.c /home/dannf/bk/linux-2.4-20040815/mm/mmap.c
---- linux-2.4.27/mm/mmap.c 2004-02-18 06:36:32.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/mm/mmap.c 2004-08-15 05:07:48.000000000 -0600
-@@ -15,6 +15,7 @@
- #include <linux/fs.h>
- #include <linux/personality.h>
- #include <linux/mount.h>
-+#include <linux/hugetlb.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -600,7 +601,10 @@
- fput(file);
-
- /* Undo any partial mapping done by a device driver. */
-- zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
-+ if (is_vm_hugetlb_page(vma))
-+ zap_hugepage_range(vma, vma->vm_start, vma->vm_end-vma->vm_start);
-+ else
-+ zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
- free_vma:
- kmem_cache_free(vm_area_cachep, vma);
- return error;
-@@ -650,10 +654,26 @@
- unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
- {
- if (flags & MAP_FIXED) {
-+ unsigned long ret;
-+
- if (addr > TASK_SIZE - len)
- return -ENOMEM;
- if (addr & ~PAGE_MASK)
- return -EINVAL;
-+ if (file && is_file_hugepages(file))
-+ /* If the request is for hugepages, then make sure
-+ * that addr and length is properly aligned.
-+ */
-+ ret = is_aligned_hugepage_range(addr, len);
-+ else
-+ /*
-+ * Make sure that a normal request is not falling
-+ * in reserved hugepage range. For some archs like
-+ * IA-64, there is a separate region for hugepages.
-+ */
-+ ret = is_invalid_hugepage_range(addr, len);
-+ if (ret)
-+ return ret;
- return addr;
- }
-
-@@ -947,6 +967,12 @@
- return 0;
- /* we have addr < mpnt->vm_end */
-
-+ if (is_vm_hugetlb_page(mpnt)) {
-+ int ret = is_aligned_hugepage_range(addr, len);
-+ if (ret)
-+ return ret;
-+ }
-+
- if (mpnt->vm_start >= addr+len)
- return 0;
-
-@@ -1000,7 +1026,10 @@
- remove_shared_vm_struct(mpnt);
- mm->map_count--;
-
-- zap_page_range(mm, st, size);
-+ if (is_vm_hugetlb_page(mpnt))
-+ zap_hugepage_range(mpnt, st, size);
-+ else
-+ zap_page_range(mm, st, size);
-
- /*
- * Fix the mapping, and free the old area if it wasn't reused.
-@@ -1015,7 +1044,10 @@
- if (extra)
- kmem_cache_free(vm_area_cachep, extra);
-
-- free_pgtables(mm, prev, addr, addr+len);
-+ if (is_hugepage_addr(addr))
-+ hugetlb_free_pgtables(mm, prev, addr, addr+len);
-+ else
-+ free_pgtables(mm, prev, addr, addr+len);
-
- return 0;
- }
-@@ -1160,7 +1192,10 @@
- }
- mm->map_count--;
- remove_shared_vm_struct(mpnt);
-- zap_page_range(mm, start, size);
-+ if (is_vm_hugetlb_page(mpnt))
-+ zap_hugepage_range(mpnt, start, size);
-+ else
-+ zap_page_range(mm, start, size);
- if (mpnt->vm_file)
- fput(mpnt->vm_file);
- kmem_cache_free(vm_area_cachep, mpnt);
-diff -urN linux-2.4.27/mm/mprotect.c /home/dannf/bk/linux-2.4-20040815/mm/mprotect.c
---- linux-2.4.27/mm/mprotect.c 2003-11-28 11:26:21.000000000 -0700
-+++ /home/dannf/bk/linux-2.4-20040815/mm/mprotect.c 2004-08-15 05:01:09.000000000 -0600
-@@ -7,6 +7,7 @@
- #include <linux/smp_lock.h>
- #include <linux/shm.h>
- #include <linux/mman.h>
-+#include <linux/hugetlb.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -294,6 +295,10 @@
-
- /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
-
-+ if (is_vm_hugetlb_page(vma)) {
-+ error = -EACCES;
-+ goto out;
-+ }
- newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
- if ((newflags & ~(newflags >> 4)) & 0xf) {
- error = -EACCES;
-diff -urN linux-2.4.27/mm/mremap.c /home/dannf/bk/linux-2.4-20040815/mm/mremap.c
---- linux-2.4.27/mm/mremap.c 2004-04-14 07:05:41.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/mm/mremap.c 2004-08-15 05:06:04.000000000 -0600
-@@ -9,6 +9,7 @@
- #include <linux/shm.h>
- #include <linux/mman.h>
- #include <linux/swap.h>
-+#include <linux/hugetlb.h>
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-@@ -287,6 +288,10 @@
- vma = find_vma(current->mm, addr);
- if (!vma || vma->vm_start > addr)
- goto out;
-+ if (is_vm_hugetlb_page(vma)) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
- /* We can't remap across vm area boundaries */
- if (old_len > vma->vm_end - addr)
- goto out;
-diff -urN linux-2.4.27/mm/page_alloc.c /home/dannf/bk/linux-2.4-20040815/mm/page_alloc.c
---- linux-2.4.27/mm/page_alloc.c 2004-08-07 17:26:06.000000000 -0600
-+++ /home/dannf/bk/linux-2.4-20040815/mm/page_alloc.c 2004-08-15 04:51:39.000000000 -0600
-@@ -77,11 +77,11 @@
- /*
- * Temporary debugging check.
- */
--#define BAD_RANGE(zone, page) \
--( \
-- (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
-- || (((page) - mem_map) < (zone)->zone_start_mapnr) \
-- || ((zone) != page_zone(page)) \
-+#define BAD_RANGE(zone, page) \
-+( \
-+ (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
-+ || (((page) - mem_map) < (zone)->zone_start_mapnr) \
-+ || ((zone) != page_zone(page)) \
- )
-
- /*
-@@ -631,7 +631,7 @@
- unsigned long nr, total, flags;
-
- total = 0;
-- if (zone->size) {
-+ if (zone->realsize) {
- spin_lock_irqsave(&zone->lock, flags);
- for (order = 0; order < MAX_ORDER; order++) {
- head = &(zone->free_area + order)->free_list;
-@@ -663,13 +663,44 @@
- /*
- * Builds allocation fallback zone lists.
- */
--static inline void build_zonelists(pg_data_t *pgdat)
-+static int __init build_zonelists_node(pg_data_t *pgdat, zonelist_t *zonelist, int j, int k)
- {
-- int i, j, k;
-+ zone_t *zone;
-+ switch (k) {
-+ default:
-+ BUG();
-+ /*
-+ * fallthrough:
-+ */
-+ case ZONE_HIGHMEM:
-+ zone = pgdat->node_zones + ZONE_HIGHMEM;
-+ if (zone->realsize) {
-+#ifndef CONFIG_HIGHMEM
-+ BUG();
-+#endif
-+ zonelist->zones[j++] = zone;
-+ }
-+ case ZONE_NORMAL:
-+ zone = pgdat->node_zones + ZONE_NORMAL;
-+ if (zone->realsize)
-+ zonelist->zones[j++] = zone;
-+ case ZONE_DMA:
-+ zone = pgdat->node_zones + ZONE_DMA;
-+ if (zone->realsize)
-+ zonelist->zones[j++] = zone;
-+ }
-+
-+ return j;
-+}
-+
-+static void __init build_zonelists(pg_data_t *pgdat)
-+{
-+ int i, j, k, node, local_node;
-
-+ local_node = pgdat->node_id;
-+ printk("Building zonelist for node : %d\n", local_node);
- for (i = 0; i <= GFP_ZONEMASK; i++) {
- zonelist_t *zonelist;
-- zone_t *zone;
-
- zonelist = pgdat->node_zonelists + i;
- memset(zonelist, 0, sizeof(*zonelist));
-@@ -681,33 +712,32 @@
- if (i & __GFP_DMA)
- k = ZONE_DMA;
-
-- switch (k) {
-- default:
-- BUG();
-- /*
-- * fallthrough:
-- */
-- case ZONE_HIGHMEM:
-- zone = pgdat->node_zones + ZONE_HIGHMEM;
-- if (zone->size) {
--#ifndef CONFIG_HIGHMEM
-- BUG();
--#endif
-- zonelist->zones[j++] = zone;
-- }
-- case ZONE_NORMAL:
-- zone = pgdat->node_zones + ZONE_NORMAL;
-- if (zone->size)
-- zonelist->zones[j++] = zone;
-- case ZONE_DMA:
-- zone = pgdat->node_zones + ZONE_DMA;
-- if (zone->size)
-- zonelist->zones[j++] = zone;
-- }
-+ j = build_zonelists_node(pgdat, zonelist, j, k);
-+ /*
-+ * Now we build the zonelist so that it contains the zones
-+ * of all the other nodes.
-+ * We don't want to pressure a particular node, so when
-+ * building the zones for node N, we make sure that the
-+ * zones coming right after the local ones are those from
-+ * node N+1 (modulo N)
-+ */
-+ for (node = local_node + 1; node < numnodes; node++)
-+ j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
-+ for (node = 0; node < local_node; node++)
-+ j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
-+
- zonelist->zones[j++] = NULL;
- }
- }
-
-+void __init build_all_zonelists(void)
-+{
-+ int i;
-+
-+ for(i = 0 ; i < numnodes ; i++)
-+ build_zonelists(NODE_DATA(i));
-+}
-+
- /*
- * Helper functions to size the waitqueue hash table.
- * Essentially these want to choose hash table sizes sufficiently
-@@ -750,6 +780,31 @@
- return ffz(~size);
- }
-
-+static unsigned long memmap_init(struct page *start, struct page *end,
-+ int zone, unsigned long start_paddr, int highmem)
-+{
-+ struct page *page;
-+
-+ for (page = start; page < end; page++) {
-+ set_page_zone(page, zone);
-+ set_page_count(page, 0);
-+ SetPageReserved(page);
-+ INIT_LIST_HEAD(&page->list);
-+ if (!highmem)
-+ set_page_address(page, __va(start_paddr));
-+ start_paddr += PAGE_SIZE;
-+ }
-+ return start_paddr;
-+}
-+
-+#ifdef HAVE_ARCH_MEMMAP_INIT
-+#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
-+ arch_memmap_init(memmap_init, start, end, zone, paddr, highmem)
-+#else
-+#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
-+ memmap_init(start, end, zone, paddr, highmem)
-+#endif
-+
- #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
-
- /*
-@@ -771,10 +826,8 @@
- BUG();
-
- totalpages = 0;
-- for (i = 0; i < MAX_NR_ZONES; i++) {
-- unsigned long size = zones_size[i];
-- totalpages += size;
-- }
-+ for (i = 0; i < MAX_NR_ZONES; i++)
-+ totalpages += zones_size[i];
- realtotalpages = totalpages;
- if (zholes_size)
- for (i = 0; i < MAX_NR_ZONES; i++)
-@@ -783,7 +836,7 @@
- printk("On node %d totalpages: %lu\n", nid, realtotalpages);
-
- /*
-- * Some architectures (with lots of mem and discontinous memory
-+ * Some architectures (with lots of mem and discontigous memory
- * maps) have to search for a good mem_map area:
- * For discontigmem, the conceptual mem map array starts from
- * PAGE_OFFSET, we need to align the actual array onto a mem map
-@@ -796,7 +849,7 @@
- MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
- }
- *gmap = pgdat->node_mem_map = lmem_map;
-- pgdat->node_size = totalpages;
-+ pgdat->node_size = 0;
- pgdat->node_start_paddr = zone_start_paddr;
- pgdat->node_start_mapnr = (lmem_map - mem_map);
- pgdat->nr_zones = 0;
-@@ -813,7 +866,7 @@
- if (zholes_size)
- realsize -= zholes_size[j];
-
-- printk("zone(%lu): %lu pages.\n", j, size);
-+ printk("zone(%lu): %lu pages.\n", j, realsize);
- zone->size = size;
- zone->realsize = realsize;
- zone->name = zone_names[j];
-@@ -824,6 +877,7 @@
- zone->nr_active_pages = zone->nr_inactive_pages = 0;
-
-
-+ pgdat->node_size += realsize;
- if (!size)
- continue;
-
-@@ -884,16 +938,10 @@
- * up by free_all_bootmem() once the early boot process is
- * done. Non-atomic initialization, single-pass.
- */
-- for (i = 0; i < size; i++) {
-- struct page *page = mem_map + offset + i;
-- set_page_zone(page, nid * MAX_NR_ZONES + j);
-- set_page_count(page, 0);
-- SetPageReserved(page);
-- INIT_LIST_HEAD(&page->list);
-- if (j != ZONE_HIGHMEM)
-- set_page_address(page, __va(zone_start_paddr));
-- zone_start_paddr += PAGE_SIZE;
-- }
-+ zone_start_paddr = MEMMAP_INIT(mem_map + offset,
-+ mem_map + offset + size,
-+ nid * MAX_NR_ZONES + j, zone_start_paddr,
-+ (j == ZONE_HIGHMEM ? 1 : 0));
-
- offset += size;
- for (i = 0; ; i++) {
-@@ -934,7 +982,6 @@
- (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
- }
- }
-- build_zonelists(pgdat);
- }
-
- void __init free_area_init(unsigned long *zones_size)
Copied: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/linux-2.4.29-ia64-050312.diff (from rev 2710, trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff)
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/lia64-bksnapshot-20040815.diff 2005-03-14 13:20:53 UTC (rev 2710)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/linux-2.4.29-ia64-050312.diff 2005-03-14 23:03:51 UTC (rev 2715)
@@ -0,0 +1,6294 @@
+###############################################################################
+# ia64 architecture patch
+# http://www.kernel.org/pub/linux/kernel/ports/ia64/v2.4/linux-2.4.29-ia64-050312.diff.bz2
+# backported to 2.4.27 by dann frazier <dannf@hp.com>
+###############################################################################
+diff -urN kernel-source-2.4.27.orig/Documentation/Configure.help kernel-source-2.4.27.bjorn/Documentation/Configure.help
+--- kernel-source-2.4.27.orig/Documentation/Configure.help 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/Documentation/Configure.help 2005-03-14 10:36:16.625915701 -0700
+@@ -18856,6 +18856,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
+diff -urN kernel-source-2.4.27.orig/Documentation/vm/hugetlbpage.txt kernel-source-2.4.27.bjorn/Documentation/vm/hugetlbpage.txt
+--- kernel-source-2.4.27.orig/Documentation/vm/hugetlbpage.txt 1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.4.27.bjorn/Documentation/vm/hugetlbpage.txt 2005-03-14 10:36:16.626892264 -0700
+@@ -0,0 +1,217 @@
++
++The intent of this file is to give a brief summary of hugetlbpage support in
++the Linux kernel. This support is built on top of multiple page size support
++that is provided by most of modern architectures. For example, IA-32
++architecture supports 4K and 4M (2M in PAE mode) page sizes, IA-64
++architecture supports multiple page sizes 4K, 8K, 64K, 256K, 1M, 4M, 16M,
++256M. A TLB is a cache of virtual-to-physical translations. Typically this
++is a very scarce resource on processor. Operating systems try to make best
++use of limited number of TLB resources. This optimization is more critical
++now as bigger and bigger physical memories (several GBs) are more readily
++available.
++
++Users can use the huge page support in Linux kernel by either using the mmap
++system call or standard SYSv shared memory system calls (shmget, shmat).
++
++First the Linux kernel needs to be built with CONFIG_HUGETLB_PAGE (present
++under Processor types and feature) and CONFIG_HUGETLBFS (present under file
++system option on config menu) config options.
++
++The kernel built with hugepage support should show the number of configured
++hugepages in the system by running the "cat /proc/meminfo" command.
++
++/proc/meminfo also provides information about the total number of hugetlb
++pages configured in the kernel. It also displays information about the
++number of free hugetlb pages at any time. It also displays information about
++the configured hugepage size - this is needed for generating the proper
++alignment and size of the arguments to the above system calls.
++
++The output of "cat /proc/meminfo" will have output like:
++
++.....
++HugePages_Total: xxx
++HugePages_Free: yyy
++Hugepagesize: zzz KB
++
++/proc/filesystems should also show a filesystem of type "hugetlbfs" configured
++in the kernel.
++
++/proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
++pages in the kernel. Super user can dynamically request more (or free some
++pre-configured) hugepages.
++The allocation( or deallocation) of hugetlb pages is posible only if there are
++enough physically contiguous free pages in system (freeing of hugepages is
++possible only if there are enough hugetlb pages free that can be transfered
++back to regular memory pool).
++
++Pages that are used as hugetlb pages are reserved inside the kernel and can
++not be used for other purposes.
++
++Once the kernel with Hugetlb page support is built and running, a user can
++use either the mmap system call or shared memory system calls to start using
++the huge pages. It is required that the system administrator preallocate
++enough memory for huge page purposes.
++
++Use the following command to dynamically allocate/deallocate hugepages:
++
++ echo 20 > /proc/sys/vm/nr_hugepages
++
++This command will try to configure 20 hugepages in the system. The success
++or failure of allocation depends on the amount of physically contiguous
++memory that is preset in system at this time. System administrators may want
++to put this command in one of the local rc init file. This will enable the
++kernel to request huge pages early in the boot process (when the possibility
++of getting physical contiguous pages is still very high).
++
++If the user applications are going to request hugepages using mmap system
++call, then it is required that system administrator mount a file system of
++type hugetlbfs:
++
++ mount none /mnt/huge -t hugetlbfs <uid=value> <gid=value> <mode=value>
++ <size=value> <nr_inodes=value>
++
++This command mounts a (pseudo) filesystem of type hugetlbfs on the directory
++/mnt/huge. Any files created on /mnt/huge use hugepages. The uid and gid
++options set the owner and group of the root of the file system. By default
++the uid and gid of the current process are taken. The mode option sets the
++mode of root of file system to value & 0777. This value is given in octal.
++By default the value 0755 is picked. The size option sets the maximum value of
++memory (huge pages) allowed for that filesystem (/mnt/huge). The size is
++rounded down to HPAGE_SIZE. The option nr_inode sets the maximum number of
++inodes that /mnt/huge can use. If the size or nr_inode options are not
++provided on command line then no limits are set. For option size and option
++nr_inodes, you can use [G|g]/[M|m]/[K|k] to represent giga/mega/kilo. For
++example, size=2K has the same meaning as size=2048. An example is given at
++the end of this document.
++
++read and write system calls are not supported on files that reside on hugetlb
++file systems.
++
++Regular chown, chgrp and chmod commands can be used to change the file
++attributes on hugetlbfs.
++
++Also, it is important to note that no such mount command is required if the
++applications are going to use only shmat/shmget system calls. It is possible
++for same or different applications to use any combination of mmaps and shm*
++calls. Though the mount of filesystem will be required for using mmaps.
++
++/* Example of using hugepage in user application using Sys V shared memory
++ * system calls. In this example, app is requesting memory of size 256MB that
++ * is backed by huge pages. Application uses the flag SHM_HUGETLB in shmget
++ * system call to informt the kernel that it is requesting hugepages. For
++ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
++ * That means the addresses starting with 0x800000....will need to be
++ * specified.
++ */
++#include <sys/types.h>
++#include <sys/shm.h>
++#include <sys/types.h>
++#include <sys/mman.h>
++
++extern int errno;
++#define SHM_HUGETLB 04000
++#define LPAGE_SIZE (256UL*1024UL*1024UL)
++#define dprintf(x) printf(x)
++#define ADDR (0x8000000000000000UL)
++main()
++{
++ int shmid;
++ int i, j, k;
++ volatile char *shmaddr;
++
++ if ((shmid =shmget(2, LPAGE_SIZE, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W ))
++< 0) {
++ perror("Failure:");
++ exit(1);
++ }
++ printf("shmid: 0x%x\n", shmid);
++ shmaddr = shmat(shmid, (void *)ADDR, SHM_RND) ;
++ if (errno != 0) {
++ perror("Shared Memory Attach Failure:");
++ exit(2);
++ }
++ printf("shmaddr: %p\n", shmaddr);
++
++ dprintf("Starting the writes:\n");
++ for (i=0;i<LPAGE_SIZE;i++) {
++ shmaddr[i] = (char) (i);
++ if (!(i%(1024*1024))) dprintf(".");
++ }
++ dprintf("\n");
++ dprintf("Starting the Check...");
++ for (i=0; i<LPAGE_SIZE;i++)
++ if (shmaddr[i] != (char)i)
++ printf("\nIndex %d mismatched.");
++ dprintf("Done.\n");
++ if (shmdt((const void *)shmaddr) != 0) {
++ perror("Detached Failure:");
++ exit (3);
++ }
++}
++*******************************************************************
++*******************************************************************
++
++
++/* Example of using hugepage in user application using mmap
++ * system call. Before running this application, make sure that
++ * administrator has mounted the hugetlbfs (on some directory like /mnt) using
++ * the command mount -t hugetlbfs nodev /mnt
++ * In this example, app is requesting memory of size 256MB that
++ * is backed by huge pages. Application uses the flag SHM_HUGETLB in shmget
++ * system call to informt the kernel that it is requesting hugepages. For
++ * IA-64 architecture, Linux kernel reserves Region number 4 for hugepages.
++ * That means the addresses starting with 0x800000....will need to be
++ * specified.
++ */
++#include <unistd.h>
++#include <stdio.h>
++#include <sys/mman.h>
++#include <fcntl.h>
++
++#define FILE_NAME "/mnt/hugepagefile"
++#define LENGTH (256*1024*1024)
++#define PROTECTION (PROT_READ | PROT_WRITE)
++#define FLAGS MAP_SHARED |MAP_FIXED
++#define ADDRESS (char *)(0x60000000UL + 0x8000000000000000UL)
++
++extern errno;
++
++check_bytes(char *addr)
++{
++ printf("First hex is %x\n", *((unsigned int *)addr));
++}
++
++write_bytes(char *addr)
++{
++ int i;
++ for (i=0;i<LENGTH;i++)
++ *(addr+i)=(char)i;
++}
++read_bytes(char *addr)
++{
++ int i;
++ check_bytes(addr);
++ for (i=0;i<LENGTH;i++)
++ if (*(addr+i)!=(char)i) {
++ printf("Mismatch at %d\n", i);
++ break;
++ }
++}
++main()
++{
++ unsigned long addr = 0;
++ int fd ;
++
++ fd = open(FILE_NAME, O_CREAT|O_RDWR, 0755);
++ if (fd < 0) {
++ perror("Open failed");
++ exit(errno);
++ }
++ addr = (unsigned long)mmap(ADDRESS, LENGTH, PROTECTION, FLAGS, fd, 0);
++ if (errno != 0)
++ perror("mmap failed");
++ printf("Returned address is %p\n", addr);
++ check_bytes((char*)addr);
++ write_bytes((char*)addr);
++ read_bytes((char *)addr);
++}
+diff -urN kernel-source-2.4.27.orig/Makefile kernel-source-2.4.27.bjorn/Makefile
+--- kernel-source-2.4.27.orig/Makefile 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/Makefile 2005-03-14 10:40:05.015561341 -0700
+@@ -314,8 +314,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 -urN kernel-source-2.4.27.orig/arch/ia64/configs/dig kernel-source-2.4.27.bjorn/arch/ia64/configs/dig
+--- kernel-source-2.4.27.orig/arch/ia64/configs/dig 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/configs/dig 2005-03-14 10:36:16.628845389 -0700
+@@ -125,11 +125,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -174,6 +169,7 @@
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+@@ -232,10 +228,12 @@
+ #
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ # CONFIG_IDEDISK_STROKE is not set
+ # CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+@@ -346,6 +344,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/configs/generic kernel-source-2.4.27.bjorn/arch/ia64/configs/generic
+--- kernel-source-2.4.27.orig/arch/ia64/configs/generic 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/configs/generic 2005-03-14 10:36:16.629821951 -0700
+@@ -125,11 +125,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -174,6 +169,7 @@
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+@@ -232,10 +228,12 @@
+ #
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ # CONFIG_IDEDISK_STROKE is not set
+ # CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+@@ -347,6 +345,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/configs/numa kernel-source-2.4.27.bjorn/arch/ia64/configs/numa
+--- kernel-source-2.4.27.orig/arch/ia64/configs/numa 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/configs/numa 2005-03-14 10:36:16.629821951 -0700
+@@ -127,11 +127,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -176,6 +171,7 @@
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+@@ -234,10 +230,12 @@
+ #
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ # CONFIG_IDEDISK_STROKE is not set
+ # CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+@@ -349,6 +347,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/configs/ski kernel-source-2.4.27.bjorn/arch/ia64/configs/ski
+--- kernel-source-2.4.27.orig/arch/ia64/configs/ski 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/configs/ski 2005-03-14 10:36:16.630798514 -0700
+@@ -92,11 +92,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -166,6 +161,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_DMX3191D is not set
+ # CONFIG_SCSI_DTC3280 is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/configs/zx1 kernel-source-2.4.27.bjorn/arch/ia64/configs/zx1
+--- kernel-source-2.4.27.orig/arch/ia64/configs/zx1 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/configs/zx1 2005-03-14 10:36:16.630798514 -0700
+@@ -126,11 +126,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -175,6 +170,7 @@
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+@@ -233,10 +229,12 @@
+ #
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ # CONFIG_IDEDISK_STROKE is not set
+ # CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+@@ -347,6 +345,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/defconfig kernel-source-2.4.27.bjorn/arch/ia64/defconfig
+--- kernel-source-2.4.27.orig/arch/ia64/defconfig 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/arch/ia64/defconfig 2005-03-14 10:36:16.632751639 -0700
+@@ -136,11 +136,6 @@
+ #
+ # CONFIG_IPX is not set
+ # CONFIG_ATALK is not set
+-
+-#
+-# Appletalk devices
+-#
+-# CONFIG_DEV_APPLETALK is not set
+ # CONFIG_DECNET is not set
+ # CONFIG_BRIDGE is not set
+ # CONFIG_X25 is not set
+@@ -185,6 +180,7 @@
+ # CONFIG_CISS_MONITOR_THREAD is not set
+ # CONFIG_BLK_DEV_DAC960 is not set
+ # CONFIG_BLK_DEV_UMEM is not set
++# CONFIG_BLK_DEV_SX8 is not set
+ CONFIG_BLK_DEV_LOOP=y
+ # CONFIG_BLK_DEV_NBD is not set
+ # CONFIG_BLK_DEV_RAM is not set
+@@ -243,10 +239,12 @@
+ #
+ # CONFIG_BLK_DEV_HD_IDE is not set
+ # CONFIG_BLK_DEV_HD is not set
++# CONFIG_BLK_DEV_IDE_SATA is not set
+ CONFIG_BLK_DEV_IDEDISK=y
+ CONFIG_IDEDISK_MULTI_MODE=y
+ # CONFIG_IDEDISK_STROKE is not set
+ # CONFIG_BLK_DEV_IDECS is not set
++# CONFIG_BLK_DEV_DELKIN is not set
+ CONFIG_BLK_DEV_IDECD=y
+ # CONFIG_BLK_DEV_IDETAPE is not set
+ CONFIG_BLK_DEV_IDEFLOPPY=y
+@@ -358,6 +356,18 @@
+ # CONFIG_SCSI_AM53C974 is not set
+ # CONFIG_SCSI_MEGARAID is not set
+ # CONFIG_SCSI_MEGARAID2 is not set
++# CONFIG_SCSI_SATA is not set
++# CONFIG_SCSI_SATA_AHCI is not set
++# CONFIG_SCSI_SATA_SVW is not set
++# CONFIG_SCSI_ATA_PIIX is not set
++# CONFIG_SCSI_SATA_NV is not set
++# CONFIG_SCSI_SATA_PROMISE is not set
++# CONFIG_SCSI_SATA_SX4 is not set
++# CONFIG_SCSI_SATA_SIL is not set
++# CONFIG_SCSI_SATA_SIS is not set
++# CONFIG_SCSI_SATA_ULI is not set
++# CONFIG_SCSI_SATA_VIA is not set
++# CONFIG_SCSI_SATA_VITESSE is not set
+ # CONFIG_SCSI_BUSLOGIC is not set
+ # CONFIG_SCSI_CPQFCTS is not set
+ # CONFIG_SCSI_DMX3191D is not set
+diff -urN kernel-source-2.4.27.orig/arch/ia64/hp/common/sba_iommu.c kernel-source-2.4.27.bjorn/arch/ia64/hp/common/sba_iommu.c
+--- kernel-source-2.4.27.orig/arch/ia64/hp/common/sba_iommu.c 2004-02-18 06:36:30.000000000 -0700
++++ kernel-source-2.4.27.bjorn/arch/ia64/hp/common/sba_iommu.c 2005-03-14 10:36:16.633728201 -0700
+@@ -447,6 +447,14 @@
+
+ ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0);
+ ASSERT(res_ptr < res_end);
++
++ /*
++ * N.B. REO/Grande defect AR2305 can cause TLB fetch timeouts
++ * if a TLB entry is purged while in use. sba_mark_invalid()
++ * purges IOTLB entries in power-of-two sizes, so we also
++ * allocate IOVA space in power-of-two sizes.
++ */
++ bits_wanted = 1UL << get_iovp_order(bits_wanted << PAGE_SHIFT);
+ if (bits_wanted > (BITS_PER_LONG/2)) {
+ /* Search word at a time - no mask needed */
+ for(; res_ptr < res_end; ++res_ptr) {
+@@ -583,6 +591,7 @@
+ unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]);
+
+ int bits_not_wanted = size >> iovp_shift;
++ bits_not_wanted = 1UL << get_iovp_order(bits_not_wanted << PAGE_SHIFT);
+
+ /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */
+ unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));
+diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/entry.S kernel-source-2.4.27.bjorn/arch/ia64/kernel/entry.S
+--- kernel-source-2.4.27.orig/arch/ia64/kernel/entry.S 2003-11-28 11:26:19.000000000 -0700
++++ kernel-source-2.4.27.bjorn/arch/ia64/kernel/entry.S 2005-03-14 10:36:16.633728201 -0700
+@@ -49,8 +49,11 @@
+ * setup a null register window frame.
+ */
+ ENTRY(ia64_execve)
+- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3)
+- alloc loc1=ar.pfs,3,2,4,0
++ /*
++ * Allocate 8 input registers since ptrace() may clobber them
++ */
++ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
++ alloc loc1=ar.pfs,8,2,4,0
+ /* Leave from kernel and restore all pt_regs to correspending registers. This is special
+ * because ia32 application needs scratch registers after return from execve.
+ */
+@@ -94,8 +97,11 @@
+ END(ia64_execve)
+
+ GLOBAL_ENTRY(sys_clone2)
+- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+- alloc r16=ar.pfs,3,2,4,0
++ /*
++ * Allocate 8 input registers since ptrace() may clobber them
++ */
++ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
++ alloc r16=ar.pfs,8,2,4,0
+ DO_SAVE_SWITCH_STACK
+ mov loc0=rp
+ mov loc1=r16 // save ar.pfs across do_fork
+@@ -113,8 +119,11 @@
+ END(sys_clone2)
+
+ GLOBAL_ENTRY(sys_clone)
+- .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
+- alloc r16=ar.pfs,2,2,4,0
++ /*
++ * Allocate 8 input registers since ptrace() may clobber them
++ */
++ .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
++ alloc r16=ar.pfs,8,2,4,0
+ DO_SAVE_SWITCH_STACK
+ mov loc0=rp
+ mov loc1=r16 // save ar.pfs across do_fork
+@@ -1091,7 +1100,10 @@
+
+ ENTRY(sys_rt_sigreturn)
+ PT_REGS_UNWIND_INFO(0)
+- alloc r2=ar.pfs,0,0,1,0
++ /*
++ * Allocate 8 input registers since ptrace() may clobber them
++ */
++ alloc r2=ar.pfs,8,0,1,0
+ .prologue
+ PT_REGS_SAVES(16)
+ adds sp=-16,sp
+@@ -1443,3 +1455,4 @@
+ data8 ia64_ni_syscall
+ data8 ia64_ni_syscall
+ data8 ia64_ni_syscall
++ data8 ia64_ni_syscall
+diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/ivt.S kernel-source-2.4.27.bjorn/arch/ia64/kernel/ivt.S
+--- kernel-source-2.4.27.orig/arch/ia64/kernel/ivt.S 2004-02-18 06:36:30.000000000 -0700
++++ kernel-source-2.4.27.bjorn/arch/ia64/kernel/ivt.S 2005-03-14 10:36:16.634704764 -0700
+@@ -48,6 +48,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/system.h>
+ #include <asm/unistd.h>
++#include <asm/errno.h>
+
+ #if 1
+ # define PSR_DEFAULT_BITS psr.ac
+@@ -678,15 +679,29 @@
+ mov r1=IA64_KR(CURRENT); /* r1 = current (physical) */
+ ;;
+ invala;
++
++ /* adjust return address so we skip over the break instruction: */
++
++ extr.u r8=r29,41,2 // extract ei field from cr.ipsr
+ extr.u r16=r29,32,2; /* extract psr.cpl */
+ ;;
++ cmp.eq p6,p7=2,r8 // isr.ei==2?
+ cmp.eq pKern,pUser=r0,r16; /* are we in kernel mode already? (psr.cpl==0) */
+- /* switch from user to kernel RBS: */
+ ;;
++(p6) mov r8=0 // clear ei to 0
++(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped
++(p7) adds r8=1,r8 // increment ei to next slot
++ ;;
++ dep r29=r8,r29,41,2 // insert new ei into cr.ipsr
++ ;;
++
++ /* switch from user to kernel RBS: */
+ mov r30=r0
+ MINSTATE_START_SAVE_MIN_VIRT
+ br.call.sptk.many b7=ia64_syscall_setup
+ ;;
++ // p10==true means out registers are more than 8 or r15's Nat is true
++(p10) br.cond.spnt.many ia64_ret_from_syscall
+ mov r3=255
+ adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
+ adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = ¤t->ptrace
+@@ -704,28 +719,9 @@
+ ld8 r2=[r2] // r2 = current->ptrace
+ mov b6=r16
+
+- // arrange things so we skip over break instruction when returning:
+-
+- adds r16=PT(CR_IPSR)+16,sp // get pointer to cr_ipsr
+- adds r17=PT(CR_IIP)+16,sp // get pointer to cr_iip
+ ;;
+- ld8 r18=[r16] // fetch cr_ipsr
+ tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PF_TRACESYS) == 0?
+ ;;
+- ld8 r19=[r17] // fetch cr_iip
+- extr.u r20=r18,41,2 // extract ei field
+- ;;
+- cmp.eq p6,p7=2,r20 // isr.ei==2?
+- adds r19=16,r19 // compute address of next bundle
+- ;;
+-(p6) mov r20=0 // clear ei to 0
+-(p7) adds r20=1,r20 // increment ei to next slot
+- ;;
+-(p6) st8 [r17]=r19 // store new cr.iip if cr.isr.ei wrapped around
+- dep r18=r20,r18,41,2 // insert new ei into cr.isr
+- ;;
+- st8 [r16]=r18 // store new value for cr.isr
+-
+ (p8) br.call.sptk.many b6=b6 // ignore this return addr
+
+ br.cond.sptk ia64_trace_syscall
+@@ -807,8 +803,11 @@
+ * - psr.ic enabled, interrupts restored
+ * - r1: kernel's gp
+ * - r3: preserved (same as on entry)
++ * - r8: -EINVAL if p10 is true
+ * - r12: points to kernel stack
+ * - r13: points to current task
++ * - p10: TRUE if syscall is invoked with more than 8 out
++ * registers or r15's Nat is true
+ * - p15: TRUE if interrupts need to be re-enabled
+ * - ar.fpsr: set to kernel settings
+ */
+@@ -825,12 +824,15 @@
+ st8 [r17]=r28,16; /* save cr.iip */
+ mov r28=b0;
+ (pKern) mov r18=r0; /* make sure r18 isn't NaT */
++ extr.u r11=r19,7,7 /* get sol of ar.pfs */
++ and r8=0x7f,r19 /* get sof of ar.pfs */
+ ;;
+ (p9) mov in1=-1
+ tnat.nz p10,p0=in2
+ st8 [r16]=r30,16; /* save cr.ifs */
+ st8 [r17]=r25,16; /* save ar.unat */
+ (pUser) sub r18=r18,r22; /* r18=RSE.ndirty*8 */
++ add r11=8,r11
+ ;;
+ st8 [r16]=r26,16; /* save ar.pfs */
+ st8 [r17]=r27,16; /* save ar.rsc */
+@@ -870,12 +872,13 @@
+ .mem.offset 8,0; st8.spill [r17]=r15,16;
+ adds r12=-16,r1; /* switch to kernel memory stack (with 16 bytes of scratch) */
+ ;;
++ cmp.lt p10,p9=r11,r8 /* frame size can't be more than local+8 */
+ mov r13=IA64_KR(CURRENT); /* establish `current' */
+ movl r1=__gp; /* establish kernel global pointer */
+ ;;
+ MINSTATE_END_SAVE_MIN_VIRT
+
+- tnat.nz p9,p0=r15
++(p9) tnat.nz p10,p0=r15
+ (p8) mov in7=-1
+ ssm psr.ic | PSR_DEFAULT_BITS
+ movl r17=FPSR_DEFAULT
+@@ -883,10 +886,10 @@
+ ;;
+ srlz.i // guarantee that interruption collection is on
+ cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+-(p9) mov r15=-1
+ (p15) ssm psr.i // restore psr.i
+ mov.m ar.fpsr=r17
+ stf8 [r8]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
++(p10) mov r8=-EINVAL
+ br.ret.sptk.many b7
+ END(ia64_syscall_setup)
+
+diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/palinfo.c kernel-source-2.4.27.bjorn/arch/ia64/kernel/palinfo.c
+--- kernel-source-2.4.27.orig/arch/ia64/kernel/palinfo.c 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/kernel/palinfo.c 2005-03-14 10:36:16.635681326 -0700
+@@ -473,7 +473,7 @@
+ "Enable CMCI promotion",
+ "Enable MCA to BINIT promotion",
+ "Enable MCA promotion",
+- "Enable BEER promotion"
++ "Enable BERR promotion"
+ };
+
+
+diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/process.c kernel-source-2.4.27.bjorn/arch/ia64/kernel/process.c
+--- kernel-source-2.4.27.orig/arch/ia64/kernel/process.c 2003-11-28 11:26:19.000000000 -0700
++++ kernel-source-2.4.27.bjorn/arch/ia64/kernel/process.c 2005-03-14 10:36:16.635681326 -0700
+@@ -485,7 +485,7 @@
+ return 1; /* f0-f31 are always valid so we always return 1 */
+ }
+
+-asmlinkage long
++long
+ sys_execve (char *filename, char **argv, char **envp, struct pt_regs *regs)
+ {
+ int error;
+diff -urN kernel-source-2.4.27.orig/arch/ia64/kernel/unwind.c kernel-source-2.4.27.bjorn/arch/ia64/kernel/unwind.c
+--- kernel-source-2.4.27.orig/arch/ia64/kernel/unwind.c 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/kernel/unwind.c 2005-03-14 10:36:16.636657889 -0700
+@@ -1916,7 +1916,7 @@
+ int
+ unw_unwind_to_user (struct unw_frame_info *info)
+ {
+- unsigned long ip;
++ unsigned long ip, sp;
+
+ while (unw_unwind(info) >= 0) {
+ if (unw_get_rp(info, &ip) < 0) {
+@@ -1925,6 +1925,9 @@
+ __FUNCTION__, ip);
+ return -1;
+ }
++ unw_get_sp(info, &sp);
++ if (sp >= (unsigned long)info->task + IA64_STK_OFFSET)
++ break;
+ /*
+ * We don't have unwind info for the gate page, so we consider that part
+ * of user-space for the purpose of unwinding.
+diff -urN kernel-source-2.4.27.orig/arch/ia64/vmlinux.lds.S kernel-source-2.4.27.bjorn/arch/ia64/vmlinux.lds.S
+--- kernel-source-2.4.27.orig/arch/ia64/vmlinux.lds.S 2003-08-25 05:44:39.000000000 -0600
++++ kernel-source-2.4.27.bjorn/arch/ia64/vmlinux.lds.S 2005-03-14 10:36:16.637634451 -0700
+@@ -7,6 +7,10 @@
+ OUTPUT_FORMAT("elf64-ia64-little")
+ OUTPUT_ARCH(ia64)
+ ENTRY(phys_start)
++PHDRS {
++ code PT_LOAD;
++ data PT_LOAD;
++}
+ SECTIONS
+ {
+ /* Sections to be discarded */
+@@ -23,6 +27,7 @@
+ v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
+ phys_start = _start - PAGE_OFFSET;
+
++ code : { } :code
+ . = KERNEL_START;
+
+ _text = .;
+@@ -142,6 +147,7 @@
+ .kstrtab : AT(ADDR(.kstrtab) - PAGE_OFFSET)
+ { *(.kstrtab) }
+
++ data : { } :data
+ .data : AT(ADDR(.data) - PAGE_OFFSET)
+ { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
+
+@@ -165,6 +171,7 @@
+ . = ALIGN(64 / 8);
+ _end = .;
+
++ code : { } :code
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+diff -urN kernel-source-2.4.27.orig/drivers/acpi/bus.c kernel-source-2.4.27.bjorn/drivers/acpi/bus.c
+--- kernel-source-2.4.27.orig/drivers/acpi/bus.c 2005-01-19 02:57:58.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/acpi/bus.c 2005-03-14 10:36:16.638611014 -0700
+@@ -1405,17 +1405,15 @@
+ switch (type) {
+ case ACPI_BUS_TYPE_DEVICE:
+ result = acpi_bus_get_status(device);
+- if (result)
+- goto end;
+- break;
++ if (!result)
++ break;
++ if (!device->status.present)
++ result = -ENOENT;
++ goto end;
+ default:
+ STRUCT_TO_INT(device->status) = 0x0F;
+ break;
+ }
+- if (!device->status.present) {
+- result = -ENOENT;
+- goto end;
+- }
+
+ /*
+ * Initialize Device
+diff -urN kernel-source-2.4.27.orig/drivers/char/Config.in kernel-source-2.4.27.bjorn/drivers/char/Config.in
+--- kernel-source-2.4.27.orig/drivers/char/Config.in 2005-01-19 02:57:41.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/Config.in 2005-03-14 10:36:16.638611014 -0700
+@@ -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
+diff -urN kernel-source-2.4.27.orig/drivers/char/agp/agp.h kernel-source-2.4.27.bjorn/drivers/char/agp/agp.h
+--- kernel-source-2.4.27.orig/drivers/char/agp/agp.h 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/char/agp/agp.h 2005-03-14 10:36:16.639587576 -0700
+@@ -538,10 +538,6 @@
+ #define HP_ZX1_TCNFG 0x318
+ #define HP_ZX1_PDIR_BASE 0x320
+
+-/* HP ZX1 LBA registers */
+-#define HP_ZX1_AGP_STATUS 0x64
+-#define HP_ZX1_AGP_COMMAND 0x68
+-
+ /* ATI register */
+ #define ATI_APBASE 0x10
+ #define ATI_GART_MMBASE_ADDR 0x14
+diff -urN kernel-source-2.4.27.orig/drivers/char/agp/agpgart_be.c kernel-source-2.4.27.bjorn/drivers/char/agp/agpgart_be.c
+--- kernel-source-2.4.27.orig/drivers/char/agp/agpgart_be.c 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/char/agp/agpgart_be.c 2005-03-14 10:36:16.645446951 -0700
+@@ -45,6 +45,7 @@
+ #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>
+@@ -217,10 +218,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);
+@@ -229,6 +234,8 @@
+ MOD_DEC_USE_COUNT;
+ }
+
++#define IN_VMALLOC(_x) (((_x) >= VMALLOC_START) && ((_x) < VMALLOC_END))
++
+ #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(unsigned long))
+
+ agp_memory *agp_allocate_memory(size_t page_count, u32 type)
+@@ -263,18 +270,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;
++ struct page *page;
++
++ 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) {
++ page = vmalloc_to_page((void *) vaddr);
++ if (!page) {
++ MOD_DEC_USE_COUNT;
++ return NULL;
++ }
++ new->memory[i] = virt_to_phys(page_address(page));
++ }
++
++ 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;
+ }
+
+@@ -287,26 +319,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));
+
+@@ -315,6 +339,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));
+@@ -324,7 +351,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;
+@@ -398,97 +425,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;
++ struct pci_dev *device;
++ u8 agp;
++ u32 scratch;
+
+- pci_read_config_dword(agp_bridge.dev,
+- agp_bridge.capndx + 4,
+- &command);
++ pci_for_each_dev(device) {
++ agp = pci_find_capability(device, PCI_CAP_ID_AGP);
++ if (!agp)
++ continue;
+
+- /*
+- * PASS1: go throu all devices that claim to be
+- * AGP devices and collect their data.
+- */
++ /*
++ * 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);
+
++ /* 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;
+
+- 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.
+- */
+-
+- 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;
+-
+- 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)
+@@ -3641,7 +3675,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 ?
+@@ -3674,77 +3707,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);
+ }
+
+
+@@ -4457,7 +4427,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,
+@@ -4607,104 +4577,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);
+-
+- /* 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).
+- */
++ command = agp_collect_device_status(mode, command);
+
+- 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)
+@@ -5131,6 +5020,7 @@
+ static struct _hp_private {
+ volatile u8 *ioc_regs;
+ volatile u8 *lba_regs;
++ int lba_cap_offset;
+ u64 *io_pdir; // PDIR for entire IOVA
+ u64 *gatt; // PDIR just for GART (subset of above)
+ u64 gatt_entries;
+@@ -5183,6 +5073,7 @@
+ hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
+
+ if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
++ /* Normal case when no AGP device in system */
+ hp->gatt = 0;
+ hp->gatt_entries = 0;
+ printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
+@@ -5228,12 +5119,13 @@
+ return 0;
+ }
+
+-static int __init hp_zx1_ioc_init(u64 ioc_hpa, u64 lba_hpa)
++static int __init hp_zx1_ioc_init(u64 hpa)
+ {
+ struct _hp_private *hp = &hp_private;
+
+- hp->ioc_regs = ioremap(ioc_hpa, 1024);
+- hp->lba_regs = ioremap(lba_hpa, 256);
++ hp->ioc_regs = ioremap(hpa, 1024);
++ if (!hp->ioc_regs)
++ return -ENOMEM;
+
+ /*
+ * If the IOTLB is currently disabled, we can take it over.
+@@ -5247,6 +5139,50 @@
+ return hp_zx1_ioc_shared();
+ }
+
++static int
++hp_zx1_lba_find_capability(volatile u8 *hpa, int cap)
++{
++ u16 status;
++ u8 pos, id;
++ int ttl = 48;
++
++ status = INREG16(hpa, PCI_STATUS);
++ if (!(status & PCI_STATUS_CAP_LIST))
++ return 0;
++ pos = INREG8(hpa, PCI_CAPABILITY_LIST);
++ while (ttl-- && pos >= 0x40) {
++ pos &= ~3;
++ id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
++ if (id == 0xff)
++ break;
++ if (id == cap)
++ return pos;
++ pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
++ }
++ return 0;
++}
++
++static int __init hp_zx1_lba_init(u64 hpa)
++{
++ struct _hp_private *hp = &hp_private;
++ int cap;
++
++ hp->lba_regs = ioremap(hpa, 256);
++ if (!hp->lba_regs)
++ return -ENOMEM;
++
++ hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
++
++ cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
++ if (cap != PCI_CAP_ID_AGP) {
++ printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
++ cap, hp->lba_cap_offset);
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
+ static int hp_zx1_fetch_size(void)
+ {
+ int size;
+@@ -5262,7 +5198,7 @@
+ struct _hp_private *hp = &hp_private;
+
+ agp_bridge.gart_bus_addr = hp->gart_base;
+- agp_bridge.mode = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
++ agp_bridge.mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
+
+ if (hp->io_pdir_owner) {
+ OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE,
+@@ -5282,10 +5218,13 @@
+ {
+ struct _hp_private *hp = &hp_private;
+
+- if (hp->io_pdir_owner)
+- OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
+- iounmap((void *) hp->ioc_regs);
+- iounmap((void *) hp->lba_regs);
++ if (hp->ioc_regs) {
++ if (hp->io_pdir_owner)
++ OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
++ iounmap((void *) hp->ioc_regs);
++ }
++ if (hp->lba_regs)
++ iounmap((void *) hp->lba_regs);
+ }
+
+ static void hp_zx1_tlbflush(agp_memory * mem)
+@@ -5405,18 +5344,23 @@
+ struct _hp_private *hp = &hp_private;
+ u32 command;
+
+- command = INREG32(hp->lba_regs, HP_ZX1_AGP_STATUS);
++ command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
+
+ command = agp_collect_device_status(mode, command);
+ command |= 0x00000100;
+
+- OUTREG32(hp->lba_regs, HP_ZX1_AGP_COMMAND, command);
++ OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
+
+ agp_device_command(command, 0);
+ }
+
+ static int __init hp_zx1_setup(u64 ioc_hpa, u64 lba_hpa)
+ {
++ struct _hp_private *hp = &hp_private;
++ int error;
++
++ memset(hp, 0, sizeof(*hp));
++
+ agp_bridge.dev_private_data = NULL;
+ agp_bridge.size_type = FIXED_APER_SIZE;
+ agp_bridge.needs_scratch_page = FALSE;
+@@ -5441,7 +5385,16 @@
+ fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
+ fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
+
+- return hp_zx1_ioc_init(ioc_hpa, lba_hpa);
++ error = hp_zx1_ioc_init(ioc_hpa);
++ if (error)
++ goto fail;
++
++ error = hp_zx1_lba_init(lba_hpa);
++
++fail:
++ if (error)
++ hp_zx1_cleanup();
++ return error;
+ }
+
+ static acpi_status __init hp_zx1_gart_probe(acpi_handle obj, u32 depth, void *context, void **ret)
+@@ -5455,7 +5408,7 @@
+
+ status = acpi_hp_csr_space(obj, &lba_hpa, &length);
+ if (ACPI_FAILURE(status))
+- return AE_OK;
++ return AE_OK; /* keep looking for another bridge */
+
+ /* Look for an enclosing IOC scope and find its CSR space */
+ handle = obj;
+@@ -5491,7 +5444,7 @@
+ (char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
+
+ hp_zx1_gart_found = 1;
+- return AE_CTRL_TERMINATE;
++ return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
+ }
+
+ static int __init
+@@ -6473,7 +6426,6 @@
+ "IGP9100/M",
+ ati_generic_setup },
+ #endif /* CONFIG_AGP_ATI */
+-
+ { 0, }, /* dummy final entry, always present */
+ };
+
+@@ -6556,7 +6508,6 @@
+ return -ENODEV;
+ }
+
+-
+ /* Supported Device Scanning routine */
+
+ static int __init agp_find_supported_device(void)
+@@ -6884,7 +6835,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 */
+@@ -7102,7 +7053,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 -urN kernel-source-2.4.27.orig/drivers/char/drm/drm_bufs.h kernel-source-2.4.27.bjorn/drivers/char/drm/drm_bufs.h
+--- kernel-source-2.4.27.orig/drivers/char/drm/drm_bufs.h 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm/drm_bufs.h 2005-03-14 10:36:16.645446951 -0700
+@@ -106,7 +106,7 @@
+ switch ( map->type ) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+-#if !defined(__sparc__) && !defined(__alpha__)
++#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__)
+ if ( map->offset + map->size < map->offset ||
+ map->offset < virt_to_phys(high_memory) ) {
+ DRM(free)( map, sizeof(*map), DRM_MEM_MAPS );
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm/drm_memory.h kernel-source-2.4.27.bjorn/drivers/char/drm/drm_memory.h
+--- kernel-source-2.4.27.orig/drivers/char/drm/drm_memory.h 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm/drm_memory.h 2005-03-14 10:36:16.646423514 -0700
+@@ -293,6 +293,11 @@
+ void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
+ {
+ void *pt;
++#if __REALLY_HAVE_AGP
++ drm_map_t *map = NULL;
++ drm_map_list_t *r_list;
++ struct list_head *list;
++#endif
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+@@ -300,12 +305,50 @@
+ return NULL;
+ }
+
++#if __REALLY_HAVE_AGP
++ if (!dev->agp || dev->agp->cant_use_aperture == 0)
++ goto standard_ioremap;
++
++ list_for_each(list, &dev->maplist->head) {
++ r_list = (drm_map_list_t *)list;
++ map = r_list->map;
++ if (!map) continue;
++ if (map->offset <= offset &&
++ (map->offset + map->size) >= (offset + size))
++ break;
++ }
++
++ if (map && map->type == _DRM_AGP) {
++ struct drm_agp_mem *agpmem;
++
++ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
++ if (agpmem->bound <= offset &&
++ (agpmem->bound + (agpmem->pages
++ << PAGE_SHIFT)) >= (offset + size))
++ break;
++ }
++
++ if (agpmem == NULL)
++ goto ioremap_failure;
++
++ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
++ goto ioremap_success;
++ }
++
++standard_ioremap:
++#endif
+ if (!(pt = ioremap(offset, size))) {
++#if __REALLY_HAVE_AGP
++ioremap_failure:
++#endif
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+ }
++#if __REALLY_HAVE_AGP
++ioremap_success:
++#endif
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+@@ -316,6 +359,11 @@
+ void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
+ {
+ void *pt;
++#if __REALLY_HAVE_AGP
++ drm_map_t *map = NULL;
++ drm_map_list_t *r_list;
++ struct list_head *list;
++#endif
+
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+@@ -323,12 +371,50 @@
+ return NULL;
+ }
+
++#if __REALLY_HAVE_AGP
++ if (!dev->agp || dev->agp->cant_use_aperture == 0)
++ goto standard_ioremap;
++
++ list_for_each(list, &dev->maplist->head) {
++ r_list = (drm_map_list_t *)list;
++ map = r_list->map;
++ if (!map) continue;
++ if (map->offset <= offset &&
++ (map->offset + map->size) >= (offset + size))
++ break;
++ }
++
++ if (map && map->type == _DRM_AGP) {
++ struct drm_agp_mem *agpmem;
++
++ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
++ if (agpmem->bound <= offset &&
++ (agpmem->bound + (agpmem->pages
++ << PAGE_SHIFT)) >= (offset + size))
++ break;
++ }
++
++ if (agpmem == NULL)
++ goto ioremap_failure;
++
++ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
++ goto ioremap_success;
++ }
++
++standard_ioremap:
++#endif
+ if (!(pt = ioremap_nocache(offset, size))) {
++#if __REALLY_HAVE_AGP
++ioremap_failure:
++#endif
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ return NULL;
+ }
++#if __REALLY_HAVE_AGP
++ioremap_success:
++#endif
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+@@ -344,7 +430,11 @@
+ if (!pt)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
++#if __REALLY_HAVE_AGP
++ else if (!dev->agp || dev->agp->cant_use_aperture == 0)
++#else
+ else
++#endif
+ iounmap(pt);
+
+ spin_lock(&DRM(mem_lock));
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm/drm_vm.h kernel-source-2.4.27.bjorn/drivers/char/drm/drm_vm.h
+--- kernel-source-2.4.27.orig/drivers/char/drm/drm_vm.h 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm/drm_vm.h 2005-03-14 10:36:16.647400076 -0700
+@@ -368,6 +368,7 @@
+ drm_map_list_t *r_list;
+ unsigned long offset = 0;
+ struct list_head *list;
++ struct page *page;
+
+ DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+ vma->vm_start, vma->vm_end, VM_OFFSET(vma));
+@@ -414,28 +415,30 @@
+
+ switch (map->type) {
+ case _DRM_AGP:
+-#if defined(__alpha__)
+- /*
+- * On Alpha we can't talk to bus dma address from the
+- * CPU, so for memory of type DRM_AGP, we'll deal with
+- * sorting out the real physical pages and mappings
+- * in nopage()
+- */
+- vma->vm_ops = &DRM(vm_ops);
+- break;
++#if __REALLY_HAVE_AGP
++ if (dev->agp->cant_use_aperture) {
++ /*
++ * On some systems we can't talk to bus dma address from
++ * the CPU, so for memory of type DRM_AGP, we'll deal
++ * with sorting out the real physical pages and mappings
++ * in nopage()
++ */
++ vma->vm_ops = &DRM(vm_ops);
++ goto mapswitch_out;
++ }
+ #endif
+ /* fall through to _DRM_FRAME_BUFFER... */
+ case _DRM_FRAME_BUFFER:
+ case _DRM_REGISTERS:
+- if (VM_OFFSET(vma) >= __pa(high_memory)) {
++ page = virt_to_page(__va(VM_OFFSET(vma)));
++ if (!VALID_PAGE(page) || PageReserved(page)) {
+ #if defined(__i386__) || defined(__x86_64__)
+ if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+ pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
+ pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
+ }
+ #elif defined(__ia64__)
+- if (map->type != _DRM_AGP)
+- vma->vm_page_prot =
++ vma->vm_page_prot =
+ pgprot_writecombine(vma->vm_page_prot);
+ #elif defined(__powerpc__)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+@@ -474,6 +477,9 @@
+ default:
+ return -EINVAL; /* This should never happen. */
+ }
++#if __REALLY_HAVE_AGP
++mapswitch_out:
++#endif
+ vma->vm_flags |= VM_RESERVED; /* Don't swap */
+
+ vma->vm_file = filp; /* Needed for drm_vm_open() */
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm/r128_cce.c kernel-source-2.4.27.bjorn/drivers/char/drm/r128_cce.c
+--- kernel-source-2.4.27.orig/drivers/char/drm/r128_cce.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm/r128_cce.c 2005-03-14 10:36:16.647400076 -0700
+@@ -216,7 +216,22 @@
+ int i;
+
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
++#ifndef CONFIG_AGP_I460
+ if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ) {
++#else
++ /*
++ * XXX - this is (I think) a 460GX specific hack
++ *
++ * When doing texturing, ring.tail sometimes gets ahead of
++ * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes
++ * its whole quota of instructions and *ring.head is still 2
++ * short of ring.tail. Work around this for now in lieu of
++ * a better solution.
++ */
++ if ( GET_RING_HEAD( &dev_priv->ring ) == dev_priv->ring.tail ||
++ ( dev_priv->ring.tail -
++ GET_RING_HEAD( &dev_priv->ring ) ) == 2 ) {
++#endif
+ int pm4stat = R128_READ( R128_PM4_STAT );
+ if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
+ dev_priv->cce_fifo_size ) &&
+@@ -317,7 +332,7 @@
+ static void r128_cce_init_ring_buffer( drm_device_t *dev,
+ drm_r128_private_t *dev_priv )
+ {
+- u32 ring_start;
++ u32 ring_start, rptr_addr;
+ u32 tmp;
+
+ DRM_DEBUG( "\n" );
+@@ -341,8 +356,24 @@
+ SET_RING_HEAD( &dev_priv->ring, 0 );
+
+ if ( !dev_priv->is_pci ) {
+- R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+- dev_priv->ring_rptr->offset );
++ /*
++ * 460GX doesn't claim PCI writes from the card into
++ * the AGP aperture, so we have to get space outside
++ * the aperture for RPTR_ADDR.
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off;
++
++ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
++ atomic_inc(&virt_to_page(alt_rh_off)->count);
++ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++
++ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
++ SET_RING_HEAD( &dev_priv->ring, 0 );
++ rptr_addr = __pa( dev_priv->ring.head );
++ } else
++ rptr_addr = dev_priv->ring_rptr->offset;
++ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr );
+ } else {
+ drm_sg_mem_t *entry = dev->sg;
+ unsigned long tmp_ofs, page_ofs;
+@@ -629,7 +660,19 @@
+ DRM_ERROR( "failed to cleanup PCI GART!\n" );
+ }
+ #endif
+-
++ /*
++ * Free the page we grabbed for RPTR_ADDR
++ */
++ if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off =
++ (unsigned long) dev_priv->ring.head;
++ struct page *p = virt_to_page((void *)alt_rh_off);
++
++ put_page(p);
++ unlock_page(p);
++ free_page(alt_rh_off);
++ }
++
+ DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm/radeon_cp.c kernel-source-2.4.27.bjorn/drivers/char/drm/radeon_cp.c
+--- kernel-source-2.4.27.orig/drivers/char/drm/radeon_cp.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm/radeon_cp.c 2005-03-14 10:36:16.648376639 -0700
+@@ -854,7 +854,7 @@
+ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
+ drm_radeon_private_t *dev_priv )
+ {
+- u32 ring_start, cur_read_ptr;
++ u32 ring_start, cur_read_ptr, rptr_addr;
+ u32 tmp;
+
+ /* Initialize the memory controller */
+@@ -892,8 +892,24 @@
+ dev_priv->ring.tail = cur_read_ptr;
+
+ if ( !dev_priv->is_pci ) {
+- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+- dev_priv->ring_rptr->offset );
++ /*
++ * 460GX doesn't claim PCI writes from the card into
++ * the AGP aperture, so we have to get space outside
++ * the aperture for RPTR_ADDR.
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off;
++
++ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
++ atomic_inc(&virt_to_page(alt_rh_off)->count);
++ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++
++ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
++ *dev_priv->ring.head = cur_read_ptr;
++ rptr_addr = __pa( dev_priv->ring.head );
++ } else
++ rptr_addr = dev_priv->ring_rptr->offset;
++ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr );
+ } else {
+ drm_sg_mem_t *entry = dev->sg;
+ unsigned long tmp_ofs, page_ofs;
+@@ -1278,6 +1294,19 @@
+ #endif /* __REALLY_HAVE_SG */
+ }
+
++ /*
++ * Free the page we grabbed for RPTR_ADDR
++ */
++ if ( !dev_priv->is_pci && dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off =
++ (unsigned long) dev_priv->ring.head;
++ struct page *p = virt_to_page((void *)alt_rh_off);
++
++ put_page(p);
++ unlock_page(p);
++ free_page(alt_rh_off);
++ }
++
+ DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/agpsupport.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/agpsupport.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/agpsupport.c 2003-11-28 11:26:20.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/agpsupport.c 2005-03-14 10:36:16.649353201 -0700
+@@ -30,6 +30,7 @@
+
+ #define __NO_VERSION__
+ #include "drmP.h"
++#include <linux/config.h>
+ #include <linux/module.h>
+ #if LINUX_VERSION_CODE < 0x020400
+ #include "agpsupport-pre24.h"
+@@ -305,6 +306,13 @@
+
+ default: head->chipset = "Unknown"; break;
+ }
++#if LINUX_VERSION_CODE <= 0x020408
++ head->cant_use_aperture = 0;
++ head->page_mask = ~(0xfff);
++#else
++ head->cant_use_aperture = head->agp_info.cant_use_aperture;
++ head->page_mask = head->agp_info.page_mask;
++#endif
+ DRM_INFO("AGP %d.%d on %s @ 0x%08lx %ZuMB\n",
+ head->agp_info.version.major,
+ head->agp_info.version.minor,
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/bufs.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/bufs.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/bufs.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/bufs.c 2005-03-14 10:36:16.649353201 -0700
+@@ -73,7 +73,7 @@
+ switch (map->type) {
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
+-#ifndef __sparc__
++#if !defined(__sparc__) && !defined(__ia64__)
+ if (map->offset + map->size < map->offset
+ || map->offset < virt_to_phys(high_memory)) {
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/drmP.h kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/drmP.h
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/drmP.h 2005-01-19 02:57:38.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/drmP.h 2005-03-14 10:36:16.650329763 -0700
+@@ -478,6 +478,8 @@
+ int acquired;
+ unsigned long base;
+ int agp_mtrr;
++ int cant_use_aperture;
++ unsigned long page_mask;
+ } drm_agp_head_t;
+ #endif
+
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/memory.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/memory.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/memory.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/memory.c 2005-03-14 10:36:16.650329763 -0700
+@@ -306,12 +306,44 @@
+ return NULL;
+ }
+
++ if (dev->agp->cant_use_aperture) {
++ drm_map_t *map = NULL;
++ int i;
++
++ for (i = 0; i < dev->map_count; i++) {
++ map = dev->maplist[i];
++ if (!map) continue;
++ if (map->offset <= offset &&
++ (map->offset + map->size) >= (offset + size))
++ break;
++ }
++
++ if (map && map->type == _DRM_AGP) {
++ struct drm_agp_mem *agpmem;
++
++ for (agpmem = dev->agp->memory; agpmem;
++ agpmem = agpmem->next) {
++ if(agpmem->bound <= offset &&
++ (agpmem->bound + (agpmem->pages
++ << PAGE_SHIFT)) >= (offset + size))
++ break;
++ }
++
++ if (agpmem) {
++ pt = agpmem->memory->vmptr + (offset - agpmem->bound);
++ goto ioremap_success;
++ }
++ }
++ }
++
+ if (!(pt = ioremap(offset, size))) {
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&drm_mem_lock);
+ return NULL;
+ }
++
++ioremap_success:
+ spin_lock(&drm_mem_lock);
+ ++drm_mem_stats[DRM_MEM_MAPPINGS].succeed_count;
+ drm_mem_stats[DRM_MEM_MAPPINGS].bytes_allocated += size;
+@@ -327,7 +359,7 @@
+ if (!pt)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
+- else
++ else if (dev->agp->cant_use_aperture == 0)
+ iounmap(pt);
+
+ spin_lock(&drm_mem_lock);
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/mga_dma.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/mga_dma.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/mga_dma.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/mga_dma.c 2005-03-14 10:36:16.651306326 -0700
+@@ -741,10 +741,18 @@
+ return -ENOMEM;
+ }
+
+- /* Write status page when secend or softrap occurs */
++ /* Write status page when secend or softrap occurs
++ *
++ * Disable this on ia64 on the off chance that real status page will be
++ * above 4GB.
++ */
++#if defined(__ia64__)
++ MGA_WRITE(MGAREG_PRIMPTR,
++ virt_to_bus((void *)dev_priv->real_status_page));
++#else
+ MGA_WRITE(MGAREG_PRIMPTR,
+ virt_to_bus((void *)dev_priv->real_status_page) | 0x00000003);
+-
++#endif
+
+ /* Private is now filled in, initialize the hardware */
+ {
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/mga_drv.h kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/mga_drv.h
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/mga_drv.h 2002-02-25 12:37:57.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/mga_drv.h 2005-03-14 10:36:16.651306326 -0700
+@@ -295,7 +295,7 @@
+ num_dwords + 1 + outcount, ADRINDEX(reg), val); \
+ if( ++outcount == 4) { \
+ outcount = 0; \
+- dma_ptr[0] = *(unsigned long *)tempIndex; \
++ dma_ptr[0] = *(u32 *)tempIndex; \
+ dma_ptr+=5; \
+ num_dwords += 5; \
+ } \
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/r128_cce.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/r128_cce.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/r128_cce.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/r128_cce.c 2005-03-14 10:36:16.652282888 -0700
+@@ -229,7 +229,21 @@
+ int i;
+
+ for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
++#ifndef CONFIG_AGP_I460
+ if ( *dev_priv->ring.head == dev_priv->ring.tail ) {
++#else
++ /*
++ * XXX - this is (I think) a 460GX specific hack
++ *
++ * When doing texturing, ring.tail sometimes gets ahead of
++ * PM4_BUFFER_DL_WPTR by 2; consequently, the card processes
++ * its whole quota of instructions and *ring.head is still 2
++ * short of ring.tail. Work around this for now in lieu of
++ * a better solution.
++ */
++ if ( (*dev_priv->ring.head == dev_priv->ring.tail) ||
++ ((dev_priv->ring.tail - *dev_priv->ring.head) == 2) ) {
++#endif
+ int pm4stat = R128_READ( R128_PM4_STAT );
+ if ( ( (pm4stat & R128_PM4_FIFOCNT_MASK) >=
+ dev_priv->cce_fifo_size ) &&
+@@ -330,7 +344,7 @@
+ static void r128_cce_init_ring_buffer( drm_device_t *dev )
+ {
+ drm_r128_private_t *dev_priv = dev->dev_private;
+- u32 ring_start;
++ u32 ring_start, rptr_addr;
+ u32 tmp;
+
+ /* The manual (p. 2) says this address is in "VM space". This
+@@ -342,10 +356,27 @@
+ R128_WRITE( R128_PM4_BUFFER_DL_WPTR, 0 );
+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR, 0 );
+
++ /*
++ * 460GX doesn't claim PCI writes from the card into the AGP
++ * aperture, so we have to get space outside the aperture for
++ * RPTR_ADDR.
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off;
++
++ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
++ atomic_inc(&virt_to_page(alt_rh_off)->count);
++ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++
++ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
++ rptr_addr = __pa( dev_priv->ring.head );
++ } else {
++ rptr_addr = dev_priv->ring_rptr->offset;
++ }
++
+ /* DL_RPTR_ADDR is a physical address in AGP space. */
+ *dev_priv->ring.head = 0;
+- R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+- dev_priv->ring_rptr->offset );
++ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR, rptr_addr );
+
+ /* Set watermark control */
+ R128_WRITE( R128_PM4_BUFFER_WM_CNTL,
+@@ -530,6 +561,19 @@
+ }
+ #endif
+
++ /*
++ * Free the page we grabbed for RPTR_ADDR
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off =
++ (unsigned long) dev_priv->ring.head;
++
++ atomic_dec(&virt_to_page(alt_rh_off)->count);
++ clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++ wake_up(&virt_to_page(alt_rh_off)->wait);
++ free_page(alt_rh_off);
++ }
++
+ drm_free( dev->dev_private, sizeof(drm_r128_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/radeon_cp.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/radeon_cp.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/radeon_cp.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/radeon_cp.c 2005-03-14 10:36:16.653259451 -0700
+@@ -569,7 +569,7 @@
+ static void radeon_cp_init_ring_buffer( drm_device_t *dev )
+ {
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+- u32 ring_start, cur_read_ptr;
++ u32 ring_start, cur_read_ptr, rptr_addr;
+ u32 tmp;
+
+ /* Initialize the memory controller */
+@@ -592,10 +592,29 @@
+ /* Initialize the ring buffer's read and write pointers */
+ cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
+ RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
++
+ *dev_priv->ring.head = cur_read_ptr;
+ dev_priv->ring.tail = cur_read_ptr;
+
+- RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset );
++ /*
++ * 460GX doesn't claim PCI writes from the card into the AGP
++ * aperture, so we have to get space outside the aperture for
++ * RPTR_ADDR.
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off;
++
++ alt_rh_off = __get_free_page(GFP_KERNEL | GFP_DMA);
++ atomic_inc(&virt_to_page(alt_rh_off)->count);
++ set_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++
++ dev_priv->ring.head = (__volatile__ u32 *) alt_rh_off;
++ *dev_priv->ring.head = cur_read_ptr;
++ rptr_addr = __pa( dev_priv->ring.head );
++ } else
++ rptr_addr = dev_priv->ring_rptr->offset;
++
++ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, rptr_addr);
+
+ /* Set ring buffer size */
+ RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw );
+@@ -837,6 +856,19 @@
+ }
+ #endif
+
++ /*
++ * Free the page we grabbed for RPTR_ADDR.
++ */
++ if ( dev->agp->agp_info.chipset == INTEL_460GX ) {
++ unsigned long alt_rh_off =
++ (unsigned long) dev_priv->ring.head;
++
++ atomic_dec(&virt_to_page(alt_rh_off)->count);
++ clear_bit(PG_locked, &virt_to_page(alt_rh_off)->flags);
++ wake_up(&virt_to_page(alt_rh_off)->wait);
++ free_page(alt_rh_off);
++ }
++
+ drm_free( dev->dev_private, sizeof(drm_radeon_private_t),
+ DRM_MEM_DRIVER );
+ dev->dev_private = NULL;
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/radeon_drv.h kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/radeon_drv.h
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/radeon_drv.h 2002-02-25 12:37:57.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/radeon_drv.h 2005-03-14 10:36:16.653259451 -0700
+@@ -535,7 +535,7 @@
+ #define RADEON_MAX_VB_VERTS (0xffff)
+
+
+-#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle))
++#define RADEON_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
+ #define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg)
+
+ #define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg)
+diff -urN kernel-source-2.4.27.orig/drivers/char/drm-4.0/vm.c kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/vm.c
+--- kernel-source-2.4.27.orig/drivers/char/drm-4.0/vm.c 2002-02-25 12:37:57.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/drm-4.0/vm.c 2005-03-14 10:36:16.654236013 -0700
+@@ -30,6 +30,7 @@
+ */
+
+ #define __NO_VERSION__
++#include <linux/config.h>
+ #include "drmP.h"
+
+ struct vm_operations_struct drm_vm_ops = {
+@@ -67,7 +68,56 @@
+ int write_access)
+ #endif
+ {
+- return NOPAGE_SIGBUS; /* Disallow mremap */
++ drm_file_t *priv = vma->vm_file->private_data;
++ drm_device_t *dev = priv->dev;
++ drm_map_t *map = NULL;
++ int i;
++
++ if (!dev->agp->cant_use_aperture)
++ return NOPAGE_SIGBUS; /* Disallow mremap */
++
++ /*
++ * Find the right map
++ */
++ for (i = 0; i < dev->map_count; i++) {
++ map = dev->maplist[i];
++ if (!map) continue;
++ if (map->offset == VM_OFFSET(vma)) break;
++ }
++
++ if (map && map->type == _DRM_AGP) {
++ unsigned long offset = address - vma->vm_start;
++ unsigned long baddr = VM_OFFSET(vma) + offset, paddr;
++ struct drm_agp_mem *agpmem;
++ struct page *page;
++
++ /*
++ * It's AGP memory - find the real physical page to map
++ */
++ for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
++ if (agpmem->bound <= baddr &&
++ agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
++ break;
++ }
++
++ if (!agpmem)
++ return NOPAGE_SIGBUS;
++
++ /*
++ * Get the page, inc the use count, and return it
++ */
++ offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
++ paddr = agpmem->memory->memory[offset];
++ page = virt_to_page(__va(paddr));
++ get_page(page);
++
++#if LINUX_VERSION_CODE < 0x020317
++ return page_address(page);
++#else
++ return page;
++#endif
++ }
++ return NOPAGE_SIGBUS;
+ }
+
+ #if LINUX_VERSION_CODE < 0x020317
+@@ -272,6 +322,7 @@
+ drm_file_t *priv = filp->private_data;
+ drm_device_t *dev = priv->dev;
+ drm_map_t *map = NULL;
++ unsigned long off;
+ int i;
+
+ DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
+@@ -288,7 +339,16 @@
+ bit longer. */
+ for (i = 0; i < dev->map_count; i++) {
+ map = dev->maplist[i];
+- if (map->offset == VM_OFFSET(vma)) break;
++ off = map->offset ^ VM_OFFSET(vma);
++#ifdef __ia64__
++ /*
++ * Ignore region bits, makes IA32 processes happier
++ * XXX This is a hack...
++ */
++ off &= ~0xe000000000000000;
++#endif
++ if (off == 0)
++ break;
+ }
+
+ if (i >= dev->map_count) return -EINVAL;
+@@ -312,9 +372,19 @@
+ }
+
+ switch (map->type) {
++ case _DRM_AGP:
++ if (dev->agp->cant_use_aperture) {
++ /*
++ * On some systems we can't talk to bus dma address from
++ * the CPU, so for memory of type DRM_AGP, we'll deal
++ * with sorting out the real physical pages and mappings
++ * in nopage()
++ */
++ vma->vm_ops = &drm_vm_ops;
++ break;
++ }
+ case _DRM_FRAME_BUFFER:
+ case _DRM_REGISTERS:
+- case _DRM_AGP:
+ if (VM_OFFSET(vma) >= __pa(high_memory)) {
+ #if defined(__i386__) || defined(__x86_64__)
+ if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
+diff -urN kernel-source-2.4.27.orig/drivers/char/mem.c kernel-source-2.4.27.bjorn/drivers/char/mem.c
+--- kernel-source-2.4.27.orig/drivers/char/mem.c 2004-08-07 17:26:04.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/char/mem.c 2005-03-14 10:36:16.655212576 -0700
+@@ -27,6 +27,10 @@
+ #include <asm/io.h>
+ #include <asm/pgalloc.h>
+
++#ifdef CONFIG_IA64
++# include <linux/efi.h>
++#endif
++
+ #ifdef CONFIG_I2C
+ extern int i2c_init_all(void);
+ #endif
+@@ -42,7 +46,46 @@
+ #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
+ extern void tapechar_init(void);
+ #endif
+-
++
++/*
++ * Architectures vary in how they handle caching for addresses
++ * outside of main memory.
++ *
++ */
++static inline int uncached_access(struct file *file, unsigned long addr)
++{
++#if defined(__i386__)
++ /*
++ * On the PPro and successors, the MTRRs are used to set
++ * memory types for physical addresses outside main memory,
++ * so blindly setting PCD or PWT on those pages is wrong.
++ * For Pentiums and earlier, the surround logic should disable
++ * caching for the high addresses through the KEN pin, but
++ * we maintain the tradition of paranoia in this code.
++ */
++ if (file->f_flags & O_SYNC)
++ return 1;
++ return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) ||
++ test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) ||
++ test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
++ test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) )
++ && addr >= __pa(high_memory);
++#elif defined(CONFIG_IA64)
++ /*
++ * On ia64, we ignore O_SYNC because we cannot tolerate memory attribute aliases.
++ */
++ return !(efi_mem_attributes(addr) & EFI_MEMORY_WB);
++#else
++ /*
++ * Accessing memory above the top the kernel knows about or through a file pointer
++ * that was marked O_SYNC will be done non-cached.
++ */
++ if (file->f_flags & O_SYNC)
++ return 1;
++ return addr >= __pa(high_memory);
++#endif
++}
++
+ static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
+ const char * buf, size_t count, loff_t *ppos)
+ {
+@@ -79,7 +122,7 @@
+ unsigned long p = *ppos;
+ unsigned long end_mem;
+ ssize_t read;
+-
++
+ end_mem = __pa(high_memory);
+ if (p >= end_mem)
+ return 0;
+@@ -123,77 +166,16 @@
+ return do_write_mem(file, __va(p), p, buf, count, ppos);
+ }
+
+-#ifndef pgprot_noncached
+-
+-/*
+- * This should probably be per-architecture in <asm/pgtable.h>
+- */
+-static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+-{
+- unsigned long prot = pgprot_val(_prot);
+-
+-#if defined(__i386__) || defined(__x86_64__)
+- /* On PPro and successors, PCD alone doesn't always mean
+- uncached because of interactions with the MTRRs. PCD | PWT
+- means definitely uncached. */
+- if (boot_cpu_data.x86 > 3)
+- prot |= _PAGE_PCD | _PAGE_PWT;
+-#elif defined(__powerpc__)
+- prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+-#elif defined(__mc68000__)
+-#ifdef SUN3_PAGE_NOCACHE
+- if (MMU_IS_SUN3)
+- prot |= SUN3_PAGE_NOCACHE;
+- else
+-#endif
+- if (MMU_IS_851 || MMU_IS_030)
+- prot |= _PAGE_NOCACHE030;
+- /* Use no-cache mode, serialized */
+- else if (MMU_IS_040 || MMU_IS_060)
+- prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
+-#endif
+-
+- return __pgprot(prot);
+-}
+-
+-#endif /* !pgprot_noncached */
+-
+-/*
+- * Architectures vary in how they handle caching for addresses
+- * outside of main memory.
+- */
+-static inline int noncached_address(unsigned long addr)
+-{
+-#if defined(__i386__)
+- /*
+- * On the PPro and successors, the MTRRs are used to set
+- * memory types for physical addresses outside main memory,
+- * so blindly setting PCD or PWT on those pages is wrong.
+- * For Pentiums and earlier, the surround logic should disable
+- * caching for the high addresses through the KEN pin, but
+- * we maintain the tradition of paranoia in this code.
+- */
+- return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
+- test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
+- test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
+- test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
+- && addr >= __pa(high_memory);
+-#else
+- return addr >= __pa(high_memory);
+-#endif
+-}
+-
+ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+ {
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
++ int uncached;
+
+- /*
+- * Accessing memory above the top the kernel knows about or
+- * through a file pointer that was marked O_SYNC will be
+- * done non-cached.
+- */
+- if (noncached_address(offset) || (file->f_flags & O_SYNC))
++ uncached = uncached_access(file, offset);
++#ifdef pgprot_noncached
++ if (uncached)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++#endif
+
+ /* Don't try to swap out physical pages.. */
+ vma->vm_flags |= VM_RESERVED;
+@@ -201,7 +183,7 @@
+ /*
+ * Don't dump addresses that are not real memory to a core file.
+ */
+- if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
++ if (uncached)
+ vma->vm_flags |= VM_IO;
+
+ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
+@@ -512,11 +494,13 @@
+ ret = file->f_pos;
+ force_successful_syscall_return();
+ break;
++
+ case 1:
+ file->f_pos += offset;
+ ret = file->f_pos;
+ force_successful_syscall_return();
+ break;
++
+ default:
+ ret = -EINVAL;
+ }
+@@ -581,6 +565,7 @@
+ {
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long size = vma->vm_end - vma->vm_start;
++ int uncached;
+
+ /*
+ * If the user is not attempting to mmap a high memory address then
+@@ -591,13 +576,11 @@
+ if ((offset + size) < (unsigned long) high_memory)
+ return mmap_mem(file, vma);
+
+- /*
+- * Accessing memory above the top the kernel knows about or
+- * through a file pointer that was marked O_SYNC will be
+- * done non-cached.
+- */
+- if (noncached_address(offset) || (file->f_flags & O_SYNC))
++ uncached = uncached_access(file, offset);
++#ifdef pgprot_noncached
++ if (uncached)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++#endif
+
+ /* Don't do anything here; "nopage" will fill the holes */
+ vma->vm_ops = &kmem_vm_ops;
+@@ -608,7 +591,8 @@
+ /*
+ * Don't dump addresses that are not real memory to a core file.
+ */
+- vma->vm_flags |= VM_IO;
++ if (uncached)
++ vma->vm_flags |= VM_IO;
+
+ return 0;
+ }
+diff -urN kernel-source-2.4.27.orig/drivers/char/serial.c kernel-source-2.4.27.bjorn/drivers/char/serial.c
+--- kernel-source-2.4.27.orig/drivers/char/serial.c 2005-01-19 02:57:54.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/char/serial.c 2005-03-14 10:36:16.659118826 -0700
+@@ -92,9 +92,8 @@
+ * ever possible.
+ *
+ * CONFIG_SERIAL_ACPI
+- * Enable support for serial console port and serial
+- * debug port as defined by the SPCR and DBGP tables in
+- * ACPI 2.0.
++ * Enable support for serial ports found in the ACPI
++ * namespace.
+ */
+
+ #include <linux/config.h>
+@@ -222,6 +221,10 @@
+ #ifdef CONFIG_MAGIC_SYSRQ
+ #include <linux/sysrq.h>
+ #endif
++#ifdef ENABLE_SERIAL_ACPI
++#include <linux/acpi.h>
++#include <acpi/acpi_bus.h>
++#endif
+
+ /*
+ * All of the compatibilty code so we can compile serial.c against
+@@ -257,6 +260,10 @@
+
+ static struct timer_list serial_timer;
+
++#define HP_DIVA_CHECKTIME (1*HZ)
++static struct timer_list hp_diva_timer;
++static int hp_diva_count = 0;
++
+ /* serial subtype definitions */
+ #ifndef SERIAL_TYPE_NORMAL
+ #define SERIAL_TYPE_NORMAL 1
+@@ -793,6 +800,41 @@
+ }
+
+ #ifdef CONFIG_SERIAL_SHARE_IRQ
++static inline int is_hp_diva_info(struct async_struct *info)
++{
++ struct pci_dev *dev = info->state->dev;
++ return (dev && dev->vendor == PCI_VENDOR_ID_HP &&
++ dev->device == PCI_DEVICE_ID_HP_SAS);
++}
++
++static inline int is_hp_diva_irq(int irq)
++{
++ struct async_struct *info = IRQ_ports[irq];
++ return (info && is_hp_diva_info(info));
++}
++
++/*
++ * It is possible to "use up" transmit empty interrupts in some
++ * cases with HP Diva cards. Figure out if there _should_ be a
++ * transmit interrupt and if so, return a suitable iir value so
++ * that we can recover when called from rs_timer().
++ */
++static inline int hp_diva_iir(int irq, struct async_struct *info)
++{
++ int iir = serial_in(info, UART_IIR);
++
++ if (is_hp_diva_info(info) &&
++ (iir & UART_IIR_NO_INT) != 0 &&
++ (info->IER & UART_IER_THRI) != 0 &&
++ (info->xmit.head != info->xmit.tail || info->x_char) &&
++ (serial_in(info, UART_LSR) & UART_LSR_THRE) != 0) {
++ iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
++ iir |= UART_IIR_THRI;
++ }
++
++ return iir;
++}
++
+ /*
+ * This is the serial driver's generic interrupt routine
+ */
+@@ -823,7 +865,7 @@
+
+ do {
+ if (!info->tty ||
+- ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
++ ((iir=hp_diva_iir(irq, info)) & UART_IIR_NO_INT)) {
+ if (!end_mark)
+ end_mark = info;
+ goto next;
+@@ -1095,9 +1137,11 @@
+ #ifdef CONFIG_SERIAL_SHARE_IRQ
+ if (info->next_port) {
+ do {
+- serial_out(info, UART_IER, 0);
+- info->IER |= UART_IER_THRI;
+- serial_out(info, UART_IER, info->IER);
++ if (!is_hp_diva_info(info)) {
++ serial_out(info, UART_IER, 0);
++ info->IER |= UART_IER_THRI;
++ serial_out(info, UART_IER, info->IER);
++ }
+ info = info->next_port;
+ } while (info);
+ #ifdef CONFIG_SERIAL_MULTIPORT
+@@ -1129,6 +1173,35 @@
+ }
+
+ /*
++ * This subroutine is called when the hp_diva_timer goes off. In
++ * certain cases (multiple gettys in particular) Diva seems to issue
++ * only a single transmit empty interrupt instead of one each time
++ * THRI is enabled, causing interrupts to be "used up". This serves
++ * to poll the Diva UARTS more frequently than rs_timer() does.
++ */
++static void hp_diva_check(unsigned long dummy)
++{
++#ifdef CONFIG_SERIAL_SHARE_IRQ
++ static unsigned long last_strobe;
++ unsigned long flags;
++ int i;
++
++ if (time_after_eq(jiffies, last_strobe + HP_DIVA_CHECKTIME)) {
++ for (i = 0; i < NR_IRQS; i++) {
++ if (is_hp_diva_irq(i)) {
++ save_flags(flags); cli();
++ rs_interrupt(i, NULL, NULL);
++ restore_flags(flags);
++ }
++ }
++ }
++ last_strobe = jiffies;
++ mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
++#endif
++}
++
++
++/*
+ * ---------------------------------------------------------------
+ * Low level utility subroutines for the serial driver: routines to
+ * figure out the appropriate timeout for an interrupt chain, routines
+@@ -4288,6 +4361,12 @@
+ break;
+ }
+
++ if (hp_diva_count++ == 0) {
++ init_timer(&hp_diva_timer);
++ hp_diva_timer.function = hp_diva_check;
++ mod_timer(&hp_diva_timer, jiffies + HP_DIVA_CHECKTIME);
++ }
++
+ return 0;
+ }
+
+@@ -4591,6 +4670,129 @@
+ }
+ }
+
++#ifdef ENABLE_SERIAL_ACPI
++static acpi_status acpi_serial_address(struct serial_struct *req,
++ struct acpi_resource_address64 *addr)
++{
++ unsigned long size;
++
++ size = addr->max_address_range - addr->min_address_range + 1;
++ req->iomem_base = ioremap(addr->min_address_range, size);
++ if (!req->iomem_base) {
++ printk("%s: couldn't ioremap 0x%lx-0x%lx\n", __FUNCTION__,
++ addr->min_address_range, addr->max_address_range);
++ return AE_ERROR;
++ }
++ req->io_type = SERIAL_IO_MEM;
++ return AE_OK;
++}
++
++static acpi_status acpi_serial_ext_irq(struct serial_struct *req,
++ struct acpi_resource_ext_irq *ext_irq)
++{
++ if (ext_irq->number_of_interrupts > 0) {
++#ifdef CONFIG_IA64
++ req->irq = acpi_register_irq(ext_irq->interrupts[0],
++ ext_irq->active_high_low, ext_irq->edge_level);
++#else
++ req->irq = ext_irq->interrupts[0];
++#endif
++ }
++ return AE_OK;
++}
++
++static acpi_status acpi_serial_port(struct serial_struct *req,
++ struct acpi_resource_io *io)
++{
++ req->port = io->min_base_address;
++ req->io_type = SERIAL_IO_PORT;
++ return AE_OK;
++}
++
++static acpi_status acpi_serial_irq(struct serial_struct *req,
++ struct acpi_resource_irq *irq)
++{
++ if (irq->number_of_interrupts > 0) {
++#ifdef CONFIG_IA64
++ req->irq = acpi_register_irq(irq->interrupts[0],
++ irq->active_high_low, irq->edge_level);
++#else
++ req->irq = irq->interrupts[0];
++#endif
++ }
++ return AE_OK;
++}
++
++static acpi_status acpi_serial_resource(struct acpi_resource *res, void *data)
++{
++ struct serial_struct *serial_req = (struct serial_struct *) data;
++ struct acpi_resource_address64 addr;
++ acpi_status status;
++
++ status = acpi_resource_to_address64(res, &addr);
++ if (ACPI_SUCCESS(status))
++ return acpi_serial_address(serial_req, &addr);
++ else if (res->id == ACPI_RSTYPE_EXT_IRQ)
++ return acpi_serial_ext_irq(serial_req, &res->data.extended_irq);
++ else if (res->id == ACPI_RSTYPE_IO)
++ return acpi_serial_port(serial_req, &res->data.io);
++ else if (res->id == ACPI_RSTYPE_IRQ)
++ return acpi_serial_irq(serial_req, &res->data.irq);
++ return AE_OK;
++}
++
++static int acpi_serial_add(struct acpi_device *device)
++{
++ acpi_status status;
++ struct serial_struct serial_req;
++ int line;
++
++ memset(&serial_req, 0, sizeof(serial_req));
++
++ status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
++ acpi_serial_resource, &serial_req);
++ if (ACPI_FAILURE(status))
++ return -ENODEV;
++
++ if (!serial_req.iomem_base && !serial_req.port) {
++ printk("%s: no iomem or port address in %s _CRS\n", __FUNCTION__,
++ device->pnp.bus_id);
++ return -ENODEV;
++ }
++
++ serial_req.baud_base = BASE_BAUD;
++ serial_req.flags = ASYNC_SKIP_TEST|ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ;
++ serial_req.xmit_fifo_size = serial_req.custom_divisor = 0;
++ serial_req.close_delay = serial_req.hub6 = serial_req.closing_wait = 0;
++ serial_req.iomem_reg_shift = 0;
++
++ line = register_serial(&serial_req);
++ if (line < 0)
++ return -ENODEV;
++
++ return 0;
++}
++
++static int acpi_serial_remove(struct acpi_device *device, int type)
++{
++ return 0;
++}
++
++static struct acpi_driver acpi_serial_driver = {
++ .name = "serial",
++ .class = "",
++ .ids = "PNP0501",
++ .ops = {
++ .add = acpi_serial_add,
++ .remove = acpi_serial_remove,
++ },
++};
++
++static void __devinit probe_serial_acpi(void)
++{
++ acpi_bus_register_driver(&acpi_serial_driver);
++}
++#endif /* ENABLE_SERIAL_ACPI */
+
+ static struct pci_device_id serial_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
+@@ -5552,6 +5754,9 @@
+ tty_register_devfs(&callout_driver, 0,
+ callout_driver.minor_start + state->line);
+ }
++#ifdef ENABLE_SERIAL_ACPI
++ probe_serial_acpi();
++#endif
+ #ifdef ENABLE_SERIAL_PCI
+ probe_serial_pci();
+ #endif
+@@ -5729,6 +5934,8 @@
+
+ /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
+ del_timer_sync(&serial_timer);
++ if (hp_diva_count > 0)
++ del_timer_sync(&hp_diva_timer);
+ save_flags(flags); cli();
+ remove_bh(SERIAL_BH);
+ if ((e1 = tty_unregister_driver(&serial_driver)))
+diff -urN kernel-source-2.4.27.orig/drivers/net/tulip/media.c kernel-source-2.4.27.bjorn/drivers/net/tulip/media.c
+--- kernel-source-2.4.27.orig/drivers/net/tulip/media.c 2003-06-13 08:51:35.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/net/tulip/media.c 2005-03-14 10:36:16.660095388 -0700
+@@ -284,6 +284,10 @@
+ for (i = 0; i < init_length; i++)
+ outl(init_sequence[i], ioaddr + CSR12);
+ }
++
++ (void) inl(ioaddr + CSR6); /* flush CSR12 writes */
++ udelay(500); /* Give MII time to recover */
++
+ tmp_info = get_u16(&misc_info[1]);
+ if (tmp_info)
+ tp->advertising[phy_num] = tmp_info | 1;
+diff -urN kernel-source-2.4.27.orig/drivers/pci/pci.c kernel-source-2.4.27.bjorn/drivers/pci/pci.c
+--- kernel-source-2.4.27.orig/drivers/pci/pci.c 2004-08-07 17:26:05.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/pci/pci.c 2005-03-14 10:36:16.661071951 -0700
+@@ -1061,8 +1061,14 @@
+ {
+ unsigned int pos, reg, next;
+ u32 l, sz;
++ u16 cmd;
+ struct resource *res;
+
++ /* Disable I/O & memory decoding while we size the BARs. */
++ pci_read_config_word(dev, PCI_COMMAND, &cmd);
++ pci_write_config_word(dev, PCI_COMMAND,
++ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
++
+ for(pos=0; pos<howmany; pos = next) {
+ next = pos+1;
+ res = &dev->resource[pos];
+@@ -1127,13 +1133,16 @@
+ if (sz && sz != 0xffffffff) {
+ sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);
+ if (!sz)
+- return;
++ goto out;
+ res->flags = (l & PCI_ROM_ADDRESS_ENABLE) |
+ IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+ res->start = l & PCI_ROM_ADDRESS_MASK;
+ res->end = res->start + (unsigned long) sz;
+ }
+ }
++
++out:
++ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+
+ void __devinit pci_read_bridge_bases(struct pci_bus *child)
+@@ -2066,16 +2075,16 @@
+ int map, block;
+
+ if ((page = pool_find_page (pool, dma)) == 0) {
+- printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
++ printk (KERN_ERR "pci_pool_free %s/%s, %p/%lx (bad dma)\n",
+ pool->dev ? pool->dev->slot_name : NULL,
+- pool->name, vaddr, (int) (dma & 0xffffffff));
++ pool->name, vaddr, (unsigned long) dma);
+ return;
+ }
+ #ifdef CONFIG_PCIPOOL_DEBUG
+ if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
+- printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
++ printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%lx\n",
+ pool->dev ? pool->dev->slot_name : NULL,
+- pool->name, vaddr, (int) (dma & 0xffffffff));
++ pool->name, vaddr, (unsigned long) dma);
+ return;
+ }
+ #endif
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/megaraid.c kernel-source-2.4.27.bjorn/drivers/scsi/megaraid.c
+--- kernel-source-2.4.27.orig/drivers/scsi/megaraid.c 2004-02-18 06:36:31.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/megaraid.c 2005-03-14 10:36:16.663025076 -0700
+@@ -2234,9 +2234,6 @@
+
+
+ #if DEBUG
+-static unsigned int cum_time = 0;
+-static unsigned int cum_time_cnt = 0;
+-
+ static void showMbox (mega_scb * pScb)
+ {
+ mega_mailbox *mbox;
+@@ -2245,7 +2242,7 @@
+ return;
+
+ mbox = (mega_mailbox *) pScb->mboxData;
+- printk ("%u cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
++ printk ("%lu cmd:%x id:%x #scts:%x lba:%x addr:%x logdrv:%x #sg:%x\n",
+ pScb->SCpnt->pid,
+ mbox->cmd, mbox->cmdid, mbox->numsectors,
+ mbox->lba, mbox->xferaddr, mbox->logdrv, mbox->numsgelements);
+@@ -3569,10 +3566,14 @@
+ mbox[0] = IS_BIOS_ENABLED;
+ mbox[2] = GET_BIOS;
+
+- mboxpnt->xferaddr = virt_to_bus ((void *) megacfg->mega_buffer);
++ mboxpnt->xferaddr = pci_map_single(megacfg->dev,
++ (void *) megacfg->mega_buffer, (2 * 1024L),
++ PCI_DMA_FROMDEVICE);
+
+ ret = megaIssueCmd (megacfg, mbox, NULL, 0);
+
++ pci_unmap_single(megacfg->dev, mboxpnt->xferaddr, 2 * 1024L, PCI_DMA_FROMDEVICE);
++
+ return (*(char *) megacfg->mega_buffer);
+ }
+
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/qla1280.c kernel-source-2.4.27.bjorn/drivers/scsi/qla1280.c
+--- kernel-source-2.4.27.orig/drivers/scsi/qla1280.c 2003-11-28 11:26:20.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/qla1280.c 2005-03-14 10:36:16.665954763 -0700
+@@ -2112,7 +2112,7 @@
+ ha->flags.abort_isp_active = 0;
+
+ ha->flags.ints_enabled = 0;
+-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
++#if defined(CONFIG_IA64_SGI_SN2)
+ if (ia64_platform_is("sn2")) {
+ int count1, count2;
+ int c;
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/scsi_dma.c kernel-source-2.4.27.bjorn/drivers/scsi/scsi_dma.c
+--- kernel-source-2.4.27.orig/drivers/scsi/scsi_dma.c 2002-02-25 12:38:04.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/scsi_dma.c 2005-03-14 10:36:16.665954763 -0700
+@@ -30,8 +30,69 @@
+ typedef unsigned char FreeSectorBitmap;
+ #elif SECTORS_PER_PAGE <= 32
+ typedef unsigned int FreeSectorBitmap;
+-#else
+-#error You lose.
++#elif SECTORS_PER_PAGE <= 64
++typedef u64 FreeSectorBitmap;
++#elif SECTORS_PER_PAGE <= 128
++
++typedef struct {
++ u64 hi, lo;
++} FreeSectorBitmap;
++
++/* No side effects on MAP-macro-arguments, please... */
++
++#define MAP_MAKE_MASK(m, nbits) \
++do { \
++ if ((nbits) >= 64) { \
++ (m).hi = ((u64) 1 << ((nbits) - 64)) - 1; \
++ (m).lo = ~(u64) 0; \
++ } else { \
++ (m).hi = 0; \
++ (m).lo = ((u64) 1 << (nbits)) - 1; \
++ } \
++} while (0)
++
++#define MAP_SHIFT_LEFT(m, count) \
++do { \
++ if ((count) >= 64) { \
++ (m).hi = (m).lo << ((count) - 64); \
++ (m).lo = 0; \
++ } else { \
++ (m).hi = ((m).hi << (count)) | ((m).lo >> (64 - (count))); \
++ (m).lo <<= count; \
++ } \
++} while (0)
++
++#define MAP_AND(r, left, right) \
++do { \
++ (r).hi = (left).hi & (right).hi; \
++ (r).lo = (left).lo & (right).lo; \
++} while (0)
++
++#define MAP_SET(r, mask) \
++do { \
++ (r).hi |= (mask).hi; \
++ (r).lo |= (mask).lo; \
++} while (0)
++
++#define MAP_CLEAR(r, mask) \
++do { \
++ (r).hi &= ~(mask).hi; \
++ (r).lo &= ~(mask).lo; \
++} while (0)
++
++#define MAP_EQUAL(left, right) (((left.hi ^ right.hi) | (left.lo ^ right.lo)) == 0)
++#define MAP_EMPTY(m) ((m.lo | m.hi) == 0)
++
++#endif
++
++#ifndef MAP_MAKE_MASK
++# define MAP_MAKE_MASK(m,nbits) ((m) = (((u64) 1 << (nbits)) - 1))
++# define MAP_SHIFT_LEFT(m,nbits) ((m) <<= (nbits))
++# define MAP_AND(res,l,r) ((res) = (l) & (r))
++# define MAP_EQUAL(l,r) ((l) == (r))
++# define MAP_EMPTY(m) ((m) == 0)
++# define MAP_CLEAR(m, bits) ((m) &= ~(bits))
++# define MAP_SET(m, bits) ((m) |= (bits))
+ #endif
+
+ /*
+@@ -71,7 +132,8 @@
+ */
+ void *scsi_malloc(unsigned int len)
+ {
+- unsigned int nbits, mask;
++ FreeSectorBitmap mask, busy_sectors, result;
++ unsigned int nbits;
+ unsigned long flags;
+
+ int i, j;
+@@ -79,23 +141,29 @@
+ return NULL;
+
+ nbits = len >> 9;
+- mask = (1 << nbits) - 1;
+
+ spin_lock_irqsave(&allocator_request_lock, flags);
+
+- for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++)
++ for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) {
++ MAP_MAKE_MASK(mask, nbits);
++ busy_sectors = dma_malloc_freelist[i];
+ for (j = 0; j <= SECTORS_PER_PAGE - nbits; j++) {
+- if ((dma_malloc_freelist[i] & (mask << j)) == 0) {
+- dma_malloc_freelist[i] |= (mask << j);
++ MAP_AND(result, busy_sectors, mask);
++ if (MAP_EMPTY(result)) {
++ MAP_SET(dma_malloc_freelist[i], mask);
+ scsi_dma_free_sectors -= nbits;
+ #ifdef DEBUG
+- SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9)));
+- printk("SMalloc: %d %p [From:%p]\n", len, dma_malloc_pages[i] + (j << 9));
++ SCSI_LOG_MLQUEUE(3, printk("SMalloc: %d %p\n",
++ len, dma_malloc_pages[i] + (j << 9)));
++ printk("SMalloc: %d %p\n",
++ len, dma_malloc_pages[i] + (j << 9));
+ #endif
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
+ }
++ MAP_SHIFT_LEFT(mask, 1);
+ }
++ }
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return NULL; /* Nope. No more */
+ }
+@@ -121,7 +189,8 @@
+ */
+ int scsi_free(void *obj, unsigned int len)
+ {
+- unsigned int page, sector, nbits, mask;
++ FreeSectorBitmap mask, result;
++ unsigned int page, sector, nbits;
+ unsigned long flags;
+
+ #ifdef DEBUG
+@@ -145,13 +214,14 @@
+ sector = (((unsigned long) obj) - page_addr) >> 9;
+
+ nbits = len >> 9;
+- mask = (1 << nbits) - 1;
++ MAP_MAKE_MASK(mask, nbits);
+
+ if (sector + nbits > SECTORS_PER_PAGE)
+ panic("scsi_free:Bad memory alignment");
+
+- if ((dma_malloc_freelist[page] &
+- (mask << sector)) != (mask << sector)) {
++ MAP_SHIFT_LEFT(mask, sector);
++ MAP_AND(result, mask, dma_malloc_freelist[page]);
++ if (!MAP_EQUAL(result, mask)) {
+ #ifdef DEBUG
+ printk("scsi_free(obj=%p, len=%d) called from %08lx\n",
+ obj, len, ret);
+@@ -159,7 +229,7 @@
+ panic("scsi_free:Trying to free unused memory");
+ }
+ scsi_dma_free_sectors += nbits;
+- dma_malloc_freelist[page] &= ~(mask << sector);
++ MAP_CLEAR(dma_malloc_freelist[page], mask);
+ spin_unlock_irqrestore(&allocator_request_lock, flags);
+ return 0;
+ }
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/scsi_ioctl.c kernel-source-2.4.27.bjorn/drivers/scsi/scsi_ioctl.c
+--- kernel-source-2.4.27.orig/drivers/scsi/scsi_ioctl.c 2003-08-25 05:44:42.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/scsi/scsi_ioctl.c 2005-03-14 10:36:16.666931326 -0700
+@@ -198,6 +198,9 @@
+ unsigned int needed, buf_needed;
+ int timeout, retries, result;
+ int data_direction;
++#if __GNUC__ < 3
++ int foo;
++#endif
+
+ if (!sic)
+ return -EINVAL;
+@@ -207,12 +210,21 @@
+ if (verify_area(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command)))
+ return -EFAULT;
+
+- if(__get_user(inlen, &sic->inlen))
++#if __GNUC__ < 3
++ foo = __get_user(inlen, &sic->inlen);
++ if(foo)
+ return -EFAULT;
+
+- if(__get_user(outlen, &sic->outlen))
++ foo = __get_user(outlen, &sic->outlen);
++ if(foo)
++ return -EFAULT;
++#else
++ if(__get_user(inlen, &sic->inlen))
+ return -EFAULT;
+
++ if(__get_user(outlen, &sic->outlen))
++ return -EFAULT;
++#endif
+ /*
+ * We do not transfer more than MAX_BUF with this interface.
+ * If the user needs to transfer more data than this, they
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/scsi_merge.c kernel-source-2.4.27.bjorn/drivers/scsi/scsi_merge.c
+--- kernel-source-2.4.27.orig/drivers/scsi/scsi_merge.c 2002-11-28 16:53:14.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/scsi_merge.c 2005-03-14 10:36:16.667907888 -0700
+@@ -1155,7 +1155,7 @@
+ {
+ struct Scsi_Host *SHpnt = SDpnt->host;
+ request_queue_t *q = &SDpnt->request_queue;
+- dma64_addr_t bounce_limit;
++ u64 bounce_limit;
+
+ /*
+ * If this host has an unlimited tablesize, then don't bother with a
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx.c kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx.c
+--- kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx.c 2004-04-14 07:05:32.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx.c 2005-03-14 10:36:16.672790701 -0700
+@@ -12979,6 +12979,7 @@
+ }
+ if (pci_enable_device(pcidev)) /* @!*!$&*!%-*#;! */
+ continue;
++#ifdef CONFIG_X86
+ /* Some HW as the HP LH4 may report twice PCI devices */
+ for (i = 0; i < count ; i++) {
+ if (devtbl[i].slot.bus == PciBusNumber(pcidev) &&
+@@ -12987,6 +12988,7 @@
+ }
+ if (i != count) /* Ignore this device if we already have it */
+ continue;
++#endif
+ devp = &devtbl[count];
+ devp->host_id = driver_setup.host_id;
+ devp->attach_done = 0;
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx_2/sym_glue.c kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx_2/sym_glue.c
+--- kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-01-19 02:57:52.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx_2/sym_glue.c 2005-03-14 10:36:16.674743826 -0700
+@@ -302,12 +302,8 @@
+ #ifndef SYM_LINUX_DYNAMIC_DMA_MAPPING
+ typedef u_long bus_addr_t;
+ #else
+-#if SYM_CONF_DMA_ADDRESSING_MODE > 0
+-typedef dma64_addr_t bus_addr_t;
+-#else
+ typedef dma_addr_t bus_addr_t;
+ #endif
+-#endif
+
+ /*
+ * Used by the eh thread to wait for command completion.
+@@ -2803,6 +2799,7 @@
+ /* This one is guaranteed by AC to do nothing :-) */
+ if (pci_enable_device(pcidev))
+ continue;
++#ifdef CONFIG_X86
+ /* Some HW as the HP LH4 may report twice PCI devices */
+ for (i = 0; i < count ; i++) {
+ if (devtbl[i].s.bus == PciBusNumber(pcidev) &&
+@@ -2811,6 +2808,7 @@
+ }
+ if (i != count) /* Ignore this device if we already have it */
+ continue;
++#endif
+ devp = &devtbl[count];
+ devp->host_id = SYM_SETUP_HOST_ID;
+ devp->attach_done = 0;
+diff -urN kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx_comm.h kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx_comm.h
+--- kernel-source-2.4.27.orig/drivers/scsi/sym53c8xx_comm.h 2002-11-28 16:53:14.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/scsi/sym53c8xx_comm.h 2005-03-14 10:36:16.675720388 -0700
+@@ -2579,6 +2579,7 @@
+ }
+ if (pci_enable_device(pcidev)) /* @!*!$&*!%-*#;! */
+ continue;
++#ifdef CONFIG_X86
+ /* Some HW as the HP LH4 may report twice PCI devices */
+ for (i = 0; i < count ; i++) {
+ if (devtbl[i].slot.bus == PciBusNumber(pcidev) &&
+@@ -2587,6 +2588,7 @@
+ }
+ if (i != count) /* Ignore this device if we already have it */
+ continue;
++#endif
+ devp = &devtbl[count];
+ devp->host_id = driver_setup.host_id;
+ devp->attach_done = 0;
+diff -urN kernel-source-2.4.27.orig/drivers/sound/.indent.pro kernel-source-2.4.27.bjorn/drivers/sound/.indent.pro
+--- kernel-source-2.4.27.orig/drivers/sound/.indent.pro 1997-09-30 09:46:46.000000000 -0600
++++ kernel-source-2.4.27.bjorn/drivers/sound/.indent.pro 1969-12-31 17:00:00.000000000 -0700
+@@ -1,8 +0,0 @@
+--bad
+--bap
+--nfca
+--bl
+--psl
+--di16
+--lp
+--ip5
+diff -urN kernel-source-2.4.27.orig/drivers/sound/.version kernel-source-2.4.27.bjorn/drivers/sound/.version
+--- kernel-source-2.4.27.orig/drivers/sound/.version 1997-11-10 00:01:54.000000000 -0700
++++ kernel-source-2.4.27.bjorn/drivers/sound/.version 1969-12-31 17:00:00.000000000 -0700
+@@ -1,2 +0,0 @@
+-3.8s
+-0x030804
+diff -urN kernel-source-2.4.27.orig/fs/Config.in kernel-source-2.4.27.bjorn/fs/Config.in
+--- kernel-source-2.4.27.orig/fs/Config.in 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/Config.in 2005-03-14 10:36:16.679626638 -0700
+@@ -63,6 +63,13 @@
+ bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
+ define_bool CONFIG_RAMFS y
+
++bool 'HugeTLB file system support' CONFIG_HUGETLBFS
++if [ "$CONFIG_HUGETLBFS" = "y" ] ; then
++ define_bool CONFIG_HUGETLB_PAGE y
++else
++ define_bool CONFIG_HUGETLB_PAGE n
++fi
++
+ tristate 'ISO 9660 CDROM file system support' CONFIG_ISO9660_FS
+ dep_mbool ' Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
+ dep_mbool ' Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS
+@@ -81,13 +88,17 @@
+
+ bool '/proc file system support' CONFIG_PROC_FS
+
+-# For some reason devfs corrupts memory badly on x86-64. Disable it
+-# for now.
+-if [ "$CONFIG_X86_64" != "y" ] ; then
+-dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL
++if [ "$CONFIG_IA64_SGI_SN2" = "y" ] ; then
++ define_bool CONFIG_DEVFS_FS y
++else
++ # For some reason devfs corrupts memory badly on x86-64. Disable it
++ # for now.
++ if [ "$CONFIG_X86_64" != "y" ] ; then
++ dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL
++ fi
++fi
+ dep_bool ' Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS
+ dep_bool ' Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS
+-fi
+
+ # It compiles as a module for testing only. It should not be used
+ # as a module in general. If we make this "tristate", a bunch of people
+diff -urN kernel-source-2.4.27.orig/fs/Makefile kernel-source-2.4.27.bjorn/fs/Makefile
+--- kernel-source-2.4.27.orig/fs/Makefile 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/Makefile 2005-03-14 10:36:16.679626638 -0700
+@@ -28,6 +28,7 @@
+ subdir-$(CONFIG_EXT2_FS) += ext2
+ subdir-$(CONFIG_CRAMFS) += cramfs
+ subdir-$(CONFIG_RAMFS) += ramfs
++subdir-$(CONFIG_HUGETLBFS) += hugetlbfs
+ subdir-$(CONFIG_CODA_FS) += coda
+ subdir-$(CONFIG_INTERMEZZO_FS) += intermezzo
+ subdir-$(CONFIG_MINIX_FS) += minix
+diff -urN kernel-source-2.4.27.orig/fs/binfmt_misc.c kernel-source-2.4.27.bjorn/fs/binfmt_misc.c
+--- kernel-source-2.4.27.orig/fs/binfmt_misc.c 2005-01-19 02:57:40.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/binfmt_misc.c 2005-03-14 10:36:16.680603201 -0700
+@@ -35,6 +35,7 @@
+ static int enabled = 1;
+
+ enum {Enabled, Magic};
++#define MISC_FMT_PRESERVE_ARGV0 (1<<31)
+
+ typedef struct {
+ struct list_head list;
+@@ -121,7 +122,9 @@
+ bprm->file = NULL;
+
+ /* Build args for interpreter */
+- remove_arg_zero(bprm);
++ if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
++ remove_arg_zero(bprm);
++ }
+ retval = copy_strings_kernel(1, &bprm->filename, bprm);
+ if (retval < 0) goto _ret;
+ bprm->argc++;
+@@ -287,6 +290,11 @@
+ if (!e->interpreter[0])
+ goto Einval;
+
++ if (*p == 'P') {
++ p++;
++ e->flags |= MISC_FMT_PRESERVE_ARGV0;
++ }
++
+ if (*p == '\n')
+ p++;
+ if (p != buf + count)
+diff -urN kernel-source-2.4.27.orig/fs/hugetlbfs/Makefile kernel-source-2.4.27.bjorn/fs/hugetlbfs/Makefile
+--- kernel-source-2.4.27.orig/fs/hugetlbfs/Makefile 1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/hugetlbfs/Makefile 2005-03-14 10:36:16.680603201 -0700
+@@ -0,0 +1,11 @@
++#
++# Makefile for the linux hugetlbfs routines.
++#
++
++O_TARGET := hugetlbfs.o
++
++obj-y := inode.o
++
++obj-m := $(O_TARGET)
++
++include $(TOPDIR)/Rules.make
+diff -urN kernel-source-2.4.27.orig/fs/hugetlbfs/inode.c kernel-source-2.4.27.bjorn/fs/hugetlbfs/inode.c
+--- kernel-source-2.4.27.orig/fs/hugetlbfs/inode.c 1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/hugetlbfs/inode.c 2005-03-14 10:36:16.682556326 -0700
+@@ -0,0 +1,762 @@
++/*
++ * hugetlbpage-backed filesystem. Based on ramfs.
++ *
++ * William Irwin, 2002
++ *
++ * Copyright (C) 2002 Linus Torvalds.
++ * Backported from 2.5.48 11/19/2002 Rohit Seth <rohit.seth@intel.com>
++ */
++
++#include <linux/module.h>
++#include <asm/current.h>
++#include <linux/sched.h> /* remove ASAP */
++#include <linux/fs.h>
++#include <linux/mount.h>
++#include <linux/file.h>
++#include <linux/pagemap.h>
++#include <linux/highmem.h>
++#include <linux/init.h>
++#include <linux/string.h>
++#include <linux/hugetlb.h>
++#include <linux/quotaops.h>
++#include <linux/slab.h>
++#include <linux/dnotify.h>
++
++#include <asm/uaccess.h>
++#include <asm/statfs.h>
++#include <asm/div64.h>
++
++extern struct list_head inode_unused;
++
++/* some random number */
++#define HUGETLBFS_MAGIC 0x958458f6
++
++static struct super_operations hugetlbfs_ops;
++static struct address_space_operations hugetlbfs_aops;
++struct file_operations hugetlbfs_file_operations;
++static struct inode_operations hugetlbfs_dir_inode_operations;
++static struct inode_operations hugetlbfs_inode_operations;
++
++static inline int hugetlbfs_positive(struct dentry *dentry)
++{
++ return dentry->d_inode && ! d_unhashed(dentry);
++}
++
++static int hugetlbfs_empty(struct dentry *dentry)
++{
++ struct list_head *list;
++ spin_lock (&dcache_lock);
++ list = dentry->d_subdirs.next;
++ while (list != &dentry->d_subdirs) {
++ struct dentry *de = list_entry(list, struct dentry, d_child);
++ if (hugetlbfs_positive(de)) {
++ spin_unlock(&dcache_lock);
++ return 0;
++ }
++ list = list->next;
++ }
++ spin_unlock(&dcache_lock);
++ return 1;
++}
++
++int hugetlbfs_sync_file(struct file * file, struct dentry *dentry, int datasync)
++{
++ return 0;
++}
++static int hugetlbfs_statfs(struct super_block *sb, struct statfs *buf)
++{
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
++
++ if (sbinfo) {
++ spin_lock(&sbinfo->stat_lock);
++ buf->f_blocks = sbinfo->max_blocks;
++ buf->f_bavail = buf->f_bfree = sbinfo->free_blocks;
++ buf->f_files = sbinfo->max_inodes;
++ buf->f_ffree = sbinfo->free_inodes;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++ buf->f_type = HUGETLBFS_MAGIC;
++ buf->f_bsize = HPAGE_SIZE;
++ buf->f_namelen = NAME_MAX;
++ return 0;
++}
++
++static int hugetlbfs_rename(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)
++{
++ int error = - ENOTEMPTY;
++
++ if (hugetlbfs_empty(new_dentry)) {
++ struct inode *inode = new_dentry->d_inode;
++ if (inode) {
++ inode->i_nlink--;
++ dput(new_dentry);
++ }
++ old_dir->i_size -= PSEUDO_DIRENT_SIZE;
++ new_dir->i_size += PSEUDO_DIRENT_SIZE;
++ old_dir->i_ctime = old_dir->i_mtime =
++ new_dir->i_ctime = new_dir->i_mtime =
++ inode->i_ctime = CURRENT_TIME;
++ error = 0;
++ }
++ return error;
++}
++static int hugetlbfs_unlink(struct inode *dir, struct dentry *dentry)
++{
++ struct inode *inode = dentry->d_inode;
++
++ if (!hugetlbfs_empty(dentry))
++ return -ENOTEMPTY;
++ dir->i_size -= PSEUDO_DIRENT_SIZE;
++ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++ dentry->d_inode->i_nlink--;
++ dput (dentry);
++ return 0;
++}
++
++#define hugetlbfs_rmdir hugetlbfs_unlink
++
++static int hugetlbfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
++{
++ struct inode *inode = old_dentry->d_inode;
++ if (S_ISDIR(inode->i_mode))
++ return -EPERM;
++ dir->i_size += PSEUDO_DIRENT_SIZE;
++ inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++ inode->i_nlink++;
++ atomic_inc(&inode->i_count);
++ dget(dentry);
++ d_instantiate(dentry, inode);
++ return 0;
++}
++
++static struct dentry *hugetlbfs_lookup(struct inode *dir, struct dentry *dentry)
++{
++ d_add(dentry, NULL);
++ return NULL;
++}
++
++static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
++{
++ struct inode *inode = file->f_dentry->d_inode;
++ struct address_space *mapping = inode->i_mapping;
++ loff_t len, vma_len;
++ int ret;
++
++ if (vma->vm_start & ~HPAGE_MASK)
++ return -EINVAL;
++
++ if (vma->vm_end & ~HPAGE_MASK)
++ return -EINVAL;
++
++ if (vma->vm_end - vma->vm_start < HPAGE_SIZE)
++ return -EINVAL;
++#ifdef CONFIG_IA64
++ if (vma->vm_start < (REGION_HPAGE << REGION_SHIFT))
++ return -EINVAL;
++#endif
++ vma_len = (loff_t)(vma->vm_end - vma->vm_start);
++
++ down(&inode->i_sem);
++
++ UPDATE_ATIME(inode);
++ vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
++ vma->vm_ops = &hugetlb_vm_ops;
++ ret = hugetlb_prefault(mapping, vma);
++ len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
++ if (ret == 0 && inode->i_size < len)
++ inode->i_size = len;
++ up(&inode->i_sem);
++
++ return ret;
++}
++
++/*
++ * Called under down_write(mmap_sem), page_table_lock is not held
++ */
++
++#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
++unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
++ unsigned long len, unsigned long pgoff, unsigned long flags);
++#else
++static unsigned long
++hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
++ unsigned long len, unsigned long pgoff, unsigned long flags)
++{
++ struct mm_struct *mm = current->mm;
++ struct vm_area_struct *vma;
++
++ if (len & ~HPAGE_MASK)
++ return -EINVAL;
++ if (len > TASK_SIZE)
++ return -ENOMEM;
++
++ if (addr) {
++ addr = COLOR_HALIGN(addr);
++ vma = find_vma(mm, addr);
++ if (TASK_SIZE - len >= addr &&
++ (!vma || addr + len <= vma->vm_start))
++ return addr;
++ }
++
++ addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
++
++ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
++ /* At this point: (!vma || addr < vma->vm_end). */
++ if (TASK_SIZE - len < addr)
++ return -ENOMEM;
++ if (!vma || addr + len <= vma->vm_start)
++ return addr;
++ addr = COLOR_HALIGN(vma->vm_end);
++ }
++}
++#endif
++
++/*
++ * Read a page. Again trivial. If it didn't already exist
++ * in the page cache, it is zero-filled.
++ */
++static int hugetlbfs_readpage(struct file *file, struct page * page)
++{
++ return -EINVAL;
++}
++
++static int hugetlbfs_prepare_write(struct file *file,
++ struct page *page, unsigned offset, unsigned to)
++{
++ return -EINVAL;
++}
++
++static int hugetlbfs_commit_write(struct file *file,
++ struct page *page, unsigned offset, unsigned to)
++{
++ return -EINVAL;
++}
++
++void truncate_huge_page(struct address_space *mapping, struct page *page)
++{
++ if (page->mapping != mapping)
++ return;
++
++ ClearPageDirty(page);
++ ClearPageUptodate(page);
++ remove_inode_page(page);
++ set_page_count(page, 1);
++ huge_page_release(page);
++}
++
++void truncate_hugepages(struct inode *inode, struct address_space *mapping, loff_t lstart)
++{
++ unsigned long start = lstart >> HPAGE_SHIFT;
++ unsigned long next;
++ unsigned long max_idx;
++ struct page *page;
++
++ max_idx = inode->i_size >> HPAGE_SHIFT;
++ next = start;
++ while (next < max_idx) {
++ page = find_lock_page(mapping, next);
++ next++;
++ if (page == NULL)
++ continue;
++ page_cache_release(page);
++ truncate_huge_page(mapping, page);
++ unlock_page(page);
++ hugetlb_put_quota(mapping);
++ }
++}
++
++static void hugetlbfs_delete_inode(struct inode *inode)
++{
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
++
++ list_del_init(&inode->i_hash);
++ list_del_init(&inode->i_list);
++ inode->i_state |= I_FREEING;
++ inodes_stat.nr_inodes--;
++
++ if (inode->i_data.nrpages)
++ truncate_hugepages(inode, &inode->i_data, 0);
++ if (sbinfo->free_inodes >= 0) {
++ spin_lock(&sbinfo->stat_lock);
++ sbinfo->free_inodes++;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++
++}
++
++static void hugetlbfs_forget_inode(struct inode *inode)
++{
++ struct super_block *super_block = inode->i_sb;
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
++
++ if (list_empty(&inode->i_hash))
++ goto out_truncate;
++
++ if (!(inode->i_state & (I_DIRTY|I_LOCK))) {
++ list_del(&inode->i_list);
++ list_add(&inode->i_list, &inode_unused);
++ }
++ inodes_stat.nr_unused++;
++ if (!super_block || (super_block->s_flags & MS_ACTIVE)) {
++ return;
++ }
++
++ /* write_inode_now() ? */
++ inodes_stat.nr_unused--;
++ list_del_init(&inode->i_hash);
++out_truncate:
++ list_del_init(&inode->i_list);
++ inode->i_state |= I_FREEING;
++ inodes_stat.nr_inodes--;
++ if (inode->i_data.nrpages)
++ truncate_hugepages(inode, &inode->i_data, 0);
++
++ if (sbinfo->free_inodes >= 0) {
++ spin_lock(&sbinfo->stat_lock);
++ sbinfo->free_inodes++;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++}
++
++static void hugetlbfs_drop_inode(struct inode *inode)
++{
++ if (!inode->i_nlink)
++ hugetlbfs_delete_inode(inode);
++ else
++ hugetlbfs_forget_inode(inode);
++}
++
++static void
++hugetlb_vmtruncate_list(struct vm_area_struct *mpnt, unsigned long pgoff)
++{
++
++ do {
++ unsigned long h_vm_pgoff;
++ unsigned long v_length;
++ unsigned long h_length;
++ unsigned long v_offset;
++
++ h_vm_pgoff = mpnt->vm_pgoff << (HPAGE_SHIFT - PAGE_SHIFT);
++ v_length = mpnt->vm_end - mpnt->vm_start;
++ h_length = v_length >> HPAGE_SHIFT;
++ v_offset = (pgoff - h_vm_pgoff) << HPAGE_SHIFT;
++
++ /*
++ * Is this VMA fully outside the truncation point?
++ */
++ if (h_vm_pgoff >= pgoff) {
++ zap_hugepage_range(mpnt, mpnt->vm_start, v_length);
++ continue;
++ }
++
++ /*
++ * Is this VMA fully inside the truncaton point?
++ */
++ if (h_vm_pgoff + (v_length >> HPAGE_SHIFT) <= pgoff)
++ continue;
++
++ /*
++ * The VMA straddles the truncation point. v_offset is the
++ * offset (in bytes) into the VMA where the point lies.
++ */
++ zap_hugepage_range(mpnt,
++ mpnt->vm_start + v_offset,
++ v_length - v_offset);
++ } while ((mpnt = mpnt->vm_next_share) != NULL);
++}
++
++/*
++ * Expanding truncates are not allowed.
++ */
++static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
++{
++ unsigned long pgoff;
++ struct address_space *mapping = inode->i_mapping;
++
++ if (offset > inode->i_size)
++ return -EINVAL;
++
++ BUG_ON(offset & ~HPAGE_MASK);
++ pgoff = offset >> HPAGE_SHIFT;
++
++ spin_lock(&mapping->i_shared_lock);
++ if (mapping->i_mmap != NULL)
++ hugetlb_vmtruncate_list(mapping->i_mmap, pgoff);
++ if (mapping->i_mmap_shared != NULL)
++ hugetlb_vmtruncate_list(mapping->i_mmap_shared, pgoff);
++
++ spin_unlock(&mapping->i_shared_lock);
++ truncate_hugepages(inode, mapping, offset);
++ inode->i_size = offset;
++ return 0;
++}
++
++static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
++{
++ struct inode *inode = dentry->d_inode;
++ int error;
++ unsigned int ia_valid = attr->ia_valid;
++
++ BUG_ON(!inode);
++
++ error = inode_change_ok(inode, attr);
++ if (error)
++ goto out;
++
++ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
++ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid))
++ error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0;
++ if (error)
++ goto out;
++ if (ia_valid & ATTR_SIZE) {
++ error = -EINVAL;
++ if (!(attr->ia_size & ~HPAGE_MASK))
++ error = hugetlb_vmtruncate(inode, attr->ia_size);
++ if (error)
++ goto out;
++ attr->ia_valid &= ~ATTR_SIZE;
++ }
++ error = inode_setattr(inode, attr);
++out:
++ return error;
++}
++
++static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
++ gid_t gid, int mode, int dev)
++{
++ struct inode *inode;
++ struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
++
++ if (sbinfo->free_inodes >= 0) {
++ spin_lock(&sbinfo->stat_lock);
++ if (!sbinfo->free_inodes) {
++ spin_unlock(&sbinfo->stat_lock);
++ return NULL;
++ }
++ sbinfo->free_inodes--;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++
++ inode = new_inode(sb);
++ if (inode) {
++ inode->i_mode = mode;
++ inode->i_uid = uid;
++ inode->i_gid = gid;
++ inode->i_blksize = HPAGE_SIZE;
++ inode->i_blocks = 0;
++ inode->i_rdev = NODEV;
++ inode->i_mapping->a_ops = &hugetlbfs_aops;
++ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
++ switch (mode & S_IFMT) {
++ default:
++ init_special_inode(inode, mode, dev);
++ break;
++ case S_IFREG:
++ inode->i_op = &hugetlbfs_inode_operations;
++ inode->i_fop = &hugetlbfs_file_operations;
++ break;
++ case S_IFDIR:
++ inode->i_op = &hugetlbfs_dir_inode_operations;
++ inode->i_fop = &dcache_dir_ops;
++
++ break;
++ case S_IFLNK:
++ inode->i_op = &page_symlink_inode_operations;
++ break;
++ }
++ }
++ return inode;
++}
++
++/*
++ * File creation. Allocate an inode, and we're done..
++ */
++/* SMP-safe */
++static int hugetlbfs_mknod(struct inode *dir,
++ struct dentry *dentry, int mode, int dev)
++{
++ struct inode *inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
++ current->fsgid, mode, dev);
++ int error = -ENOSPC;
++
++ if (inode) {
++ dir->i_size += PSEUDO_DIRENT_SIZE;
++ dir->i_ctime = dir->i_mtime = CURRENT_TIME;
++ d_instantiate(dentry, inode);
++ dget(dentry); /* Extra count - pin the dentry in core */
++ error = 0;
++ }
++ return error;
++}
++
++static int hugetlbfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++{
++ int retval = hugetlbfs_mknod(dir, dentry, mode | S_IFDIR, 0);
++// if (!retval)
++ //dir->i_nlink++;
++ return retval;
++}
++
++static int hugetlbfs_create(struct inode *dir, struct dentry *dentry, int mode)
++{
++ return hugetlbfs_mknod(dir, dentry, mode | S_IFREG, 0);
++}
++
++static int hugetlbfs_symlink(struct inode *dir,
++ struct dentry *dentry, const char *symname)
++{
++ int error = -ENOSPC;
++
++ error = hugetlbfs_mknod(dir, dentry, S_IFLNK|S_IRWXUGO, 0);
++ if (!error) {
++ int l = strlen(symname)+1;
++ struct inode *inode = dentry->d_inode;
++ error = block_symlink(inode, symname, l);
++ }
++ return error;
++}
++
++static struct address_space_operations hugetlbfs_aops = {
++ .readpage = hugetlbfs_readpage,
++ .writepage = fail_writepage,
++ .prepare_write = hugetlbfs_prepare_write,
++ .commit_write = hugetlbfs_commit_write,
++};
++
++struct file_operations hugetlbfs_file_operations = {
++ .mmap = hugetlbfs_file_mmap,
++ .fsync = hugetlbfs_sync_file,
++ .get_unmapped_area = hugetlb_get_unmapped_area,
++};
++
++static struct inode_operations hugetlbfs_dir_inode_operations = {
++ .create = hugetlbfs_create,
++ .lookup = hugetlbfs_lookup,
++ .link = hugetlbfs_link,
++ .unlink = hugetlbfs_unlink,
++ .symlink = hugetlbfs_symlink,
++ .mkdir = hugetlbfs_mkdir,
++ .rmdir = hugetlbfs_rmdir,
++ .mknod = hugetlbfs_mknod,
++ .rename = hugetlbfs_rename,
++ .setattr = hugetlbfs_setattr,
++};
++
++static struct inode_operations hugetlbfs_inode_operations = {
++ .setattr = hugetlbfs_setattr,
++};
++
++static struct super_operations hugetlbfs_ops = {
++ .statfs = hugetlbfs_statfs,
++ .put_inode = hugetlbfs_drop_inode,
++};
++
++static int hugetlbfs_parse_options(char *options, struct hugetlbfs_config *pconfig)
++{
++ char *opt, *value, *rest;
++
++ if (!options)
++ return 0;
++ while ((opt = strsep(&options, ",")) != NULL) {
++ if (!*opt)
++ continue;
++
++ value = strchr(opt, '=');
++ if (!value || !*value)
++ return -EINVAL;
++ else
++ *value++ = '\0';
++
++ if (!strcmp(opt, "uid"))
++ pconfig->uid = simple_strtoul(value, &value, 0);
++ else if (!strcmp(opt, "gid"))
++ pconfig->gid = simple_strtoul(value, &value, 0);
++ else if (!strcmp(opt, "mode"))
++ pconfig->mode = simple_strtoul(value, &value, 0) & 0777U;
++ else if (!strcmp(opt, "size")) {
++ unsigned long long size = memparse(value, &rest);
++ if (*rest == '%') {
++ size <<= HPAGE_SHIFT;
++ size *= htlbpage_max;
++ do_div(size, 100);
++ rest++;
++ }
++ size &= HPAGE_MASK;
++ pconfig->nr_blocks = (size >> HPAGE_SHIFT) ;
++ value = rest;
++ } else if (!strcmp(opt,"nr_inodes")) {
++ pconfig->nr_inodes = memparse(value, &rest);
++ value = rest;
++ } else
++ return -EINVAL;
++
++ if (*value)
++ return -EINVAL;
++ }
++ return 0;
++}
++
++static struct super_block *
++hugetlbfs_fill_super(struct super_block * sb, void * data, int silent)
++{
++ struct inode * inode;
++ struct dentry * root;
++ struct hugetlbfs_config config;
++ struct hugetlbfs_sb_info *sbinfo;
++
++ config.nr_blocks = -1; /* No limit on size by default. */
++ config.nr_inodes = -1; /* No limit on number of inodes by default. */
++ config.uid = current->fsuid;
++ config.gid = current->fsgid;
++ config.mode = 0755;
++ if (hugetlbfs_parse_options(data, &config))
++ return NULL;
++
++ sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL);
++ if (!sbinfo)
++ return NULL;
++ sb->u.generic_sbp = sbinfo;
++
++ spin_lock_init(&sbinfo->stat_lock);
++ sbinfo->max_blocks = config.nr_blocks;
++ sbinfo->free_blocks = config.nr_blocks;
++ sbinfo->max_inodes = config.nr_inodes;
++ sbinfo->free_inodes = config.nr_inodes;
++ sb->s_blocksize = HPAGE_SIZE;
++ sb->s_blocksize_bits = HPAGE_SHIFT;
++ sb->s_magic = HUGETLBFS_MAGIC;
++ sb->s_op = &hugetlbfs_ops;
++ inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
++ S_IFDIR | config.mode, 0);
++ if (!inode)
++ goto out_free;
++
++ root = d_alloc_root(inode);
++ if (!root) {
++ iput(inode);
++ goto out_free;
++ }
++ sb->s_root = root;
++ return sb;
++out_free:
++ kfree(sbinfo);
++ return NULL;
++}
++
++static DECLARE_FSTYPE(hugetlbfs_fs_type, "hugetlbfs", hugetlbfs_fill_super, FS_LITTER);
++
++static struct vfsmount *hugetlbfs_vfsmount;
++
++static atomic_t hugetlbfs_counter = ATOMIC_INIT(0);
++
++struct file *hugetlb_zero_setup(size_t size)
++{
++ int error, n;
++ struct file *file;
++ struct inode *inode;
++ struct dentry *dentry, *root;
++ struct qstr quick_string;
++ char buf[16];
++
++ if (!is_hugepage_mem_enough(size))
++ return ERR_PTR(-ENOMEM);
++ n = atomic_read(&hugetlbfs_counter);
++ atomic_inc(&hugetlbfs_counter);
++
++ root = hugetlbfs_vfsmount->mnt_root;
++ snprintf(buf, 16, "%d", n);
++ quick_string.name = buf;
++ quick_string.len = strlen(quick_string.name);
++ quick_string.hash = 0;
++ dentry = d_alloc(root, &quick_string);
++ if (!dentry)
++ return ERR_PTR(-ENOMEM);
++
++ error = -ENFILE;
++ file = get_empty_filp();
++ if (!file)
++ goto out_dentry;
++
++ error = -ENOSPC;
++ inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
++ current->fsgid, S_IFREG | S_IRWXUGO, 0);
++ if (!inode)
++ goto out_file;
++
++ d_instantiate(dentry, inode);
++ inode->i_size = size;
++ inode->i_nlink = 0;
++ file->f_vfsmnt = mntget(hugetlbfs_vfsmount);
++ file->f_dentry = dentry;
++ file->f_op = &hugetlbfs_file_operations;
++ file->f_mode = FMODE_WRITE | FMODE_READ;
++ return file;
++
++out_file:
++ put_filp(file);
++out_dentry:
++ dput(dentry);
++ return ERR_PTR(error);
++}
++
++int hugetlb_get_quota(struct address_space * mapping)
++{
++ int ret = 0;
++ struct hugetlbfs_sb_info *sbinfo =
++ HUGETLBFS_SB(mapping->host->i_sb);
++
++ if (sbinfo->free_blocks > -1) {
++ spin_lock(&sbinfo->stat_lock);
++ if (sbinfo->free_blocks > 0)
++ sbinfo->free_blocks--;
++ else
++ ret = -ENOMEM;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++
++ return ret;
++}
++
++void hugetlb_put_quota(struct address_space *mapping)
++{
++ struct hugetlbfs_sb_info *sbinfo =
++ HUGETLBFS_SB(mapping->host->i_sb);
++
++ if (sbinfo->free_blocks > -1) {
++ spin_lock(&sbinfo->stat_lock);
++ sbinfo->free_blocks++;
++ spin_unlock(&sbinfo->stat_lock);
++ }
++}
++
++static int __init init_hugetlbfs_fs(void)
++{
++ int error;
++ struct vfsmount *vfsmount;
++
++ error = register_filesystem(&hugetlbfs_fs_type);
++ if (error)
++ return error;
++
++ vfsmount = kern_mount(&hugetlbfs_fs_type);
++
++ if (!IS_ERR(vfsmount)) {
++ printk("Hugetlbfs mounted.\n");
++ hugetlbfs_vfsmount = vfsmount;
++ return 0;
++ }
++
++ printk("Error in mounting hugetlbfs.\n");
++ error = PTR_ERR(vfsmount);
++ return error;
++}
++
++static void __exit exit_hugetlbfs_fs(void)
++{
++ unregister_filesystem(&hugetlbfs_fs_type);
++}
++
++module_init(init_hugetlbfs_fs)
++module_exit(exit_hugetlbfs_fs)
++
++MODULE_LICENSE("GPL");
+diff -urN kernel-source-2.4.27.orig/fs/inode.c kernel-source-2.4.27.bjorn/fs/inode.c
+--- kernel-source-2.4.27.orig/fs/inode.c 2004-04-14 07:05:40.000000000 -0600
++++ kernel-source-2.4.27.bjorn/fs/inode.c 2005-03-14 10:36:16.683532888 -0700
+@@ -57,7 +57,7 @@
+ */
+
+ static LIST_HEAD(inode_in_use);
+-static LIST_HEAD(inode_unused);
++LIST_HEAD(inode_unused);
+ static LIST_HEAD(inode_unused_pagecache);
+ static struct list_head *inode_hashtable;
+ static LIST_HEAD(anon_hash_chain); /* for inodes with NULL i_sb */
+diff -urN kernel-source-2.4.27.orig/fs/proc/array.c kernel-source-2.4.27.bjorn/fs/proc/array.c
+--- kernel-source-2.4.27.orig/fs/proc/array.c 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/proc/array.c 2005-03-14 10:36:16.683532888 -0700
+@@ -64,6 +64,7 @@
+ #include <linux/proc_fs.h>
+ #include <linux/ioport.h>
+ #include <linux/mm.h>
++#include <linux/hugetlb.h>
+ #include <linux/pagemap.h>
+ #include <linux/swap.h>
+ #include <linux/slab.h>
+@@ -490,6 +491,18 @@
+ pgd_t *pgd = pgd_offset(mm, vma->vm_start);
+ int pages = 0, shared = 0, dirty = 0, total = 0;
+
++ if (is_vm_hugetlb_page(vma)) {
++ int num_pages = ((vma->vm_end - vma->vm_start)/PAGE_SIZE);
++ resident +=num_pages;
++ if (!(vma->vm_flags & VM_DONTCOPY))
++ share += num_pages;
++ if (vma->vm_flags & VM_WRITE)
++ dt += num_pages;
++ drs += num_pages;
++ vma = vma->vm_next;
++ continue;
++
++ }
+ statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
+ resident += pages;
+ share += shared;
+diff -urN kernel-source-2.4.27.orig/fs/proc/proc_misc.c kernel-source-2.4.27.bjorn/fs/proc/proc_misc.c
+--- kernel-source-2.4.27.orig/fs/proc/proc_misc.c 2005-01-19 02:57:41.000000000 -0700
++++ kernel-source-2.4.27.bjorn/fs/proc/proc_misc.c 2005-03-14 10:36:16.684509451 -0700
+@@ -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.totalswap),
+ K(i.freeswap));
+
++ len += hugetlb_report_meminfo(page + len);
++
+ return proc_calc_metrics(page, start, off, count, eof, len);
+ #undef B
+ #undef K
+diff -urN kernel-source-2.4.27.orig/include/asm-generic/tlb.h kernel-source-2.4.27.bjorn/include/asm-generic/tlb.h
+--- kernel-source-2.4.27.orig/include/asm-generic/tlb.h 2002-08-02 18:39:45.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-generic/tlb.h 2005-03-14 10:36:16.685486013 -0700
+@@ -31,15 +31,18 @@
+ pte_t ptes[FREE_PTE_NR];
+ } mmu_gather_t;
+
++#ifndef local_mmu_gathers
+ /* Users of the generic TLB shootdown code must declare this storage space. */
+ extern mmu_gather_t mmu_gathers[NR_CPUS];
++#define local_mmu_gathers &mmu_gathers[smp_processor_id()]
++#endif
+
+ /* tlb_gather_mmu
+ * Return a pointer to an initialized mmu_gather_t.
+ */
+ static inline mmu_gather_t *tlb_gather_mmu(struct mm_struct *mm)
+ {
+- mmu_gather_t *tlb = &mmu_gathers[smp_processor_id()];
++ mmu_gather_t *tlb = local_mmu_gathers;
+
+ tlb->mm = mm;
+ /* Use fast mode if there is only one user of this mm (this process) */
+diff -urN kernel-source-2.4.27.orig/include/asm-generic/xor.h kernel-source-2.4.27.bjorn/include/asm-generic/xor.h
+--- kernel-source-2.4.27.orig/include/asm-generic/xor.h 2000-11-12 20:39:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/asm-generic/xor.h 2005-03-14 10:36:16.686462576 -0700
+@@ -13,6 +13,8 @@
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <asm/processor.h>
++
+ static void
+ xor_8regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
+ {
+@@ -121,7 +123,7 @@
+ d5 ^= p2[5];
+ d6 ^= p2[6];
+ d7 ^= p2[7];
+- p1[0] = d0; /* Store the result (in burts) */
++ p1[0] = d0; /* Store the result (in bursts) */
+ p1[1] = d1;
+ p1[2] = d2;
+ p1[3] = d3;
+@@ -166,7 +168,7 @@
+ d5 ^= p3[5];
+ d6 ^= p3[6];
+ d7 ^= p3[7];
+- p1[0] = d0; /* Store the result (in burts) */
++ p1[0] = d0; /* Store the result (in bursts) */
+ p1[1] = d1;
+ p1[2] = d2;
+ p1[3] = d3;
+@@ -220,7 +222,7 @@
+ d5 ^= p4[5];
+ d6 ^= p4[6];
+ d7 ^= p4[7];
+- p1[0] = d0; /* Store the result (in burts) */
++ p1[0] = d0; /* Store the result (in bursts) */
+ p1[1] = d1;
+ p1[2] = d2;
+ p1[3] = d3;
+@@ -283,7 +285,7 @@
+ d5 ^= p5[5];
+ d6 ^= p5[6];
+ d7 ^= p5[7];
+- p1[0] = d0; /* Store the result (in burts) */
++ p1[0] = d0; /* Store the result (in bursts) */
+ p1[1] = d1;
+ p1[2] = d2;
+ p1[3] = d3;
+@@ -299,6 +301,382 @@
+ } while (--lines > 0);
+ }
+
++static void
++xor_8regs_p_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++ prefetchw(p1);
++ prefetch(p2);
++
++ do {
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ once_more:
++ p1[0] ^= p2[0];
++ p1[1] ^= p2[1];
++ p1[2] ^= p2[2];
++ p1[3] ^= p2[3];
++ p1[4] ^= p2[4];
++ p1[5] ^= p2[5];
++ p1[6] ^= p2[6];
++ p1[7] ^= p2[7];
++ p1 += 8;
++ p2 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_8regs_p_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++
++ do {
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ once_more:
++ p1[0] ^= p2[0] ^ p3[0];
++ p1[1] ^= p2[1] ^ p3[1];
++ p1[2] ^= p2[2] ^ p3[2];
++ p1[3] ^= p2[3] ^ p3[3];
++ p1[4] ^= p2[4] ^ p3[4];
++ p1[5] ^= p2[5] ^ p3[5];
++ p1[6] ^= p2[6] ^ p3[6];
++ p1[7] ^= p2[7] ^ p3[7];
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_8regs_p_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3, unsigned long *p4)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++ prefetch(p4);
++
++ do {
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ prefetch(p4+8);
++ once_more:
++ p1[0] ^= p2[0] ^ p3[0] ^ p4[0];
++ p1[1] ^= p2[1] ^ p3[1] ^ p4[1];
++ p1[2] ^= p2[2] ^ p3[2] ^ p4[2];
++ p1[3] ^= p2[3] ^ p3[3] ^ p4[3];
++ p1[4] ^= p2[4] ^ p3[4] ^ p4[4];
++ p1[5] ^= p2[5] ^ p3[5] ^ p4[5];
++ p1[6] ^= p2[6] ^ p3[6] ^ p4[6];
++ p1[7] ^= p2[7] ^ p3[7] ^ p4[7];
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ p4 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_8regs_p_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3, unsigned long *p4, unsigned long *p5)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++ prefetch(p4);
++ prefetch(p5);
++
++ do {
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ prefetch(p4+8);
++ prefetch(p5+8);
++ once_more:
++ p1[0] ^= p2[0] ^ p3[0] ^ p4[0] ^ p5[0];
++ p1[1] ^= p2[1] ^ p3[1] ^ p4[1] ^ p5[1];
++ p1[2] ^= p2[2] ^ p3[2] ^ p4[2] ^ p5[2];
++ p1[3] ^= p2[3] ^ p3[3] ^ p4[3] ^ p5[3];
++ p1[4] ^= p2[4] ^ p3[4] ^ p4[4] ^ p5[4];
++ p1[5] ^= p2[5] ^ p3[5] ^ p4[5] ^ p5[5];
++ p1[6] ^= p2[6] ^ p3[6] ^ p4[6] ^ p5[6];
++ p1[7] ^= p2[7] ^ p3[7] ^ p4[7] ^ p5[7];
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ p4 += 8;
++ p5 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_32regs_p_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++
++ do {
++ register long d0, d1, d2, d3, d4, d5, d6, d7;
++
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ once_more:
++ d0 = p1[0]; /* Pull the stuff into registers */
++ d1 = p1[1]; /* ... in bursts, if possible. */
++ d2 = p1[2];
++ d3 = p1[3];
++ d4 = p1[4];
++ d5 = p1[5];
++ d6 = p1[6];
++ d7 = p1[7];
++ d0 ^= p2[0];
++ d1 ^= p2[1];
++ d2 ^= p2[2];
++ d3 ^= p2[3];
++ d4 ^= p2[4];
++ d5 ^= p2[5];
++ d6 ^= p2[6];
++ d7 ^= p2[7];
++ p1[0] = d0; /* Store the result (in bursts) */
++ p1[1] = d1;
++ p1[2] = d2;
++ p1[3] = d3;
++ p1[4] = d4;
++ p1[5] = d5;
++ p1[6] = d6;
++ p1[7] = d7;
++ p1 += 8;
++ p2 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_32regs_p_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++
++ do {
++ register long d0, d1, d2, d3, d4, d5, d6, d7;
++
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ once_more:
++ d0 = p1[0]; /* Pull the stuff into registers */
++ d1 = p1[1]; /* ... in bursts, if possible. */
++ d2 = p1[2];
++ d3 = p1[3];
++ d4 = p1[4];
++ d5 = p1[5];
++ d6 = p1[6];
++ d7 = p1[7];
++ d0 ^= p2[0];
++ d1 ^= p2[1];
++ d2 ^= p2[2];
++ d3 ^= p2[3];
++ d4 ^= p2[4];
++ d5 ^= p2[5];
++ d6 ^= p2[6];
++ d7 ^= p2[7];
++ d0 ^= p3[0];
++ d1 ^= p3[1];
++ d2 ^= p3[2];
++ d3 ^= p3[3];
++ d4 ^= p3[4];
++ d5 ^= p3[5];
++ d6 ^= p3[6];
++ d7 ^= p3[7];
++ p1[0] = d0; /* Store the result (in bursts) */
++ p1[1] = d1;
++ p1[2] = d2;
++ p1[3] = d3;
++ p1[4] = d4;
++ p1[5] = d5;
++ p1[6] = d6;
++ p1[7] = d7;
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_32regs_p_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3, unsigned long *p4)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++ prefetch(p4);
++
++ do {
++ register long d0, d1, d2, d3, d4, d5, d6, d7;
++
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ prefetch(p4+8);
++ once_more:
++ d0 = p1[0]; /* Pull the stuff into registers */
++ d1 = p1[1]; /* ... in bursts, if possible. */
++ d2 = p1[2];
++ d3 = p1[3];
++ d4 = p1[4];
++ d5 = p1[5];
++ d6 = p1[6];
++ d7 = p1[7];
++ d0 ^= p2[0];
++ d1 ^= p2[1];
++ d2 ^= p2[2];
++ d3 ^= p2[3];
++ d4 ^= p2[4];
++ d5 ^= p2[5];
++ d6 ^= p2[6];
++ d7 ^= p2[7];
++ d0 ^= p3[0];
++ d1 ^= p3[1];
++ d2 ^= p3[2];
++ d3 ^= p3[3];
++ d4 ^= p3[4];
++ d5 ^= p3[5];
++ d6 ^= p3[6];
++ d7 ^= p3[7];
++ d0 ^= p4[0];
++ d1 ^= p4[1];
++ d2 ^= p4[2];
++ d3 ^= p4[3];
++ d4 ^= p4[4];
++ d5 ^= p4[5];
++ d6 ^= p4[6];
++ d7 ^= p4[7];
++ p1[0] = d0; /* Store the result (in bursts) */
++ p1[1] = d1;
++ p1[2] = d2;
++ p1[3] = d3;
++ p1[4] = d4;
++ p1[5] = d5;
++ p1[6] = d6;
++ p1[7] = d7;
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ p4 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
++static void
++xor_32regs_p_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
++ unsigned long *p3, unsigned long *p4, unsigned long *p5)
++{
++ long lines = bytes / (sizeof (long)) / 8 - 1;
++
++ prefetchw(p1);
++ prefetch(p2);
++ prefetch(p3);
++ prefetch(p4);
++ prefetch(p5);
++
++ do {
++ register long d0, d1, d2, d3, d4, d5, d6, d7;
++
++ prefetchw(p1+8);
++ prefetch(p2+8);
++ prefetch(p3+8);
++ prefetch(p4+8);
++ prefetch(p5+8);
++ once_more:
++ d0 = p1[0]; /* Pull the stuff into registers */
++ d1 = p1[1]; /* ... in bursts, if possible. */
++ d2 = p1[2];
++ d3 = p1[3];
++ d4 = p1[4];
++ d5 = p1[5];
++ d6 = p1[6];
++ d7 = p1[7];
++ d0 ^= p2[0];
++ d1 ^= p2[1];
++ d2 ^= p2[2];
++ d3 ^= p2[3];
++ d4 ^= p2[4];
++ d5 ^= p2[5];
++ d6 ^= p2[6];
++ d7 ^= p2[7];
++ d0 ^= p3[0];
++ d1 ^= p3[1];
++ d2 ^= p3[2];
++ d3 ^= p3[3];
++ d4 ^= p3[4];
++ d5 ^= p3[5];
++ d6 ^= p3[6];
++ d7 ^= p3[7];
++ d0 ^= p4[0];
++ d1 ^= p4[1];
++ d2 ^= p4[2];
++ d3 ^= p4[3];
++ d4 ^= p4[4];
++ d5 ^= p4[5];
++ d6 ^= p4[6];
++ d7 ^= p4[7];
++ d0 ^= p5[0];
++ d1 ^= p5[1];
++ d2 ^= p5[2];
++ d3 ^= p5[3];
++ d4 ^= p5[4];
++ d5 ^= p5[5];
++ d6 ^= p5[6];
++ d7 ^= p5[7];
++ p1[0] = d0; /* Store the result (in bursts) */
++ p1[1] = d1;
++ p1[2] = d2;
++ p1[3] = d3;
++ p1[4] = d4;
++ p1[5] = d5;
++ p1[6] = d6;
++ p1[7] = d7;
++ p1 += 8;
++ p2 += 8;
++ p3 += 8;
++ p4 += 8;
++ p5 += 8;
++ } while (--lines > 0);
++ if (lines == 0)
++ goto once_more;
++}
++
+ static struct xor_block_template xor_block_8regs = {
+ name: "8regs",
+ do_2: xor_8regs_2,
+@@ -315,8 +693,26 @@
+ do_5: xor_32regs_5,
+ };
+
++static struct xor_block_template xor_block_8regs_p = {
++ name: "8regs_prefetch",
++ do_2: xor_8regs_p_2,
++ do_3: xor_8regs_p_3,
++ do_4: xor_8regs_p_4,
++ do_5: xor_8regs_p_5,
++};
++
++static struct xor_block_template xor_block_32regs_p = {
++ name: "32regs_prefetch",
++ do_2: xor_32regs_p_2,
++ do_3: xor_32regs_p_3,
++ do_4: xor_32regs_p_4,
++ do_5: xor_32regs_p_5,
++};
++
+ #define XOR_TRY_TEMPLATES \
+ do { \
+ xor_speed(&xor_block_8regs); \
++ xor_speed(&xor_block_8regs_p); \
+ xor_speed(&xor_block_32regs); \
++ xor_speed(&xor_block_32regs_p); \
+ } while (0)
+diff -urN kernel-source-2.4.27.orig/include/asm-i386/hw_irq.h kernel-source-2.4.27.bjorn/include/asm-i386/hw_irq.h
+--- kernel-source-2.4.27.orig/include/asm-i386/hw_irq.h 2003-08-25 05:44:43.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-i386/hw_irq.h 2005-03-14 10:36:16.686462576 -0700
+@@ -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 -urN kernel-source-2.4.27.orig/include/asm-i386/page.h kernel-source-2.4.27.bjorn/include/asm-i386/page.h
+--- kernel-source-2.4.27.orig/include/asm-i386/page.h 2002-08-02 18:39:45.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-i386/page.h 2005-03-14 10:36:16.687439138 -0700
+@@ -30,8 +30,8 @@
+
+ #endif
+
+-#define clear_user_page(page, vaddr) clear_page(page)
+-#define copy_user_page(to, from, vaddr) copy_page(to, from)
++#define clear_user_page(page, vaddr, pg) clear_page(page)
++#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
+
+ /*
+ * These are used to make use of C type-checking..
+@@ -137,6 +137,8 @@
+ #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
++#define is_invalid_hugepage_range(addr, len) 0
++
+ #endif /* __KERNEL__ */
+
+ #endif /* _I386_PAGE_H */
+diff -urN kernel-source-2.4.27.orig/include/asm-i386/pgtable.h kernel-source-2.4.27.bjorn/include/asm-i386/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-i386/pgtable.h 2002-11-28 16:53:15.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/asm-i386/pgtable.h 2005-03-14 10:36:16.687439138 -0700
+@@ -302,6 +302,13 @@
+ static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }
+
+ /*
++ * Macro to mark a page protection value as "uncacheable". On processors which do not support
++ * it, this is a no-op.
++ */
++#define pgprot_noncached(prot) ((boot_cpu_data.x86 > 3) \
++ ? (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT)) : (prot))
++
++/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+diff -urN kernel-source-2.4.27.orig/include/asm-i386/ptrace.h kernel-source-2.4.27.bjorn/include/asm-i386/ptrace.h
+--- kernel-source-2.4.27.orig/include/asm-i386/ptrace.h 2001-09-14 15:04:08.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-i386/ptrace.h 2005-03-14 10:36:16.687439138 -0700
+@@ -58,6 +58,7 @@
+ #define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs))
+ #define instruction_pointer(regs) ((regs)->eip)
+ extern void show_regs(struct pt_regs *);
++#define force_successful_syscall_return() do { } while (0)
+ #endif
+
+ #endif
+diff -urN kernel-source-2.4.27.orig/include/asm-ia64/page.h kernel-source-2.4.27.bjorn/include/asm-ia64/page.h
+--- kernel-source-2.4.27.orig/include/asm-ia64/page.h 2004-04-14 07:05:40.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-ia64/page.h 2005-03-14 10:36:16.688415701 -0700
+@@ -59,6 +59,7 @@
+ #endif
+ #define RGN_MAP_LIMIT ((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE) /* per region addr limit */
+
++
+ #ifdef __ASSEMBLY__
+ # define __pa(x) ((x) - PAGE_OFFSET)
+ # define __va(x) ((x) + PAGE_OFFSET)
+diff -urN kernel-source-2.4.27.orig/include/asm-ia64/pgtable.h kernel-source-2.4.27.bjorn/include/asm-ia64/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-ia64/pgtable.h 2004-02-18 06:36:32.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/asm-ia64/pgtable.h 2005-03-14 10:36:16.688415701 -0700
+@@ -60,7 +60,8 @@
+ #define _PAGE_PROTNONE (__IA64_UL(1) << 63)
+
+ #define _PFN_MASK _PAGE_PPN_MASK
+-#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_A | _PAGE_D)
++/* Mask of bits which may be changed by pte_modify(); the odd bits are there for _PAGE_PROTNONE */
++#define _PAGE_CHG_MASK (_PAGE_P | _PAGE_PROTNONE | _PAGE_PL_MASK | _PAGE_AR_MASK | _PAGE_ED)
+
+ #define _PAGE_SIZE_4K 12
+ #define _PAGE_SIZE_8K 13
+@@ -216,7 +217,7 @@
+ ({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
+
+ #define pte_modify(_pte, newprot) \
+- (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)))
++ (__pte((pte_val(_pte) & ~_PAGE_CHG_MASK) | (pgprot_val(newprot) & _PAGE_CHG_MASK)))
+
+ #define page_pte_prot(page,prot) mk_pte(page, prot)
+ #define page_pte(page) page_pte_prot(page, __pgprot(0))
+diff -urN kernel-source-2.4.27.orig/include/asm-m68k/pgtable.h kernel-source-2.4.27.bjorn/include/asm-m68k/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-m68k/pgtable.h 2004-02-18 06:36:32.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/asm-m68k/pgtable.h 2005-03-14 10:36:16.688415701 -0700
+@@ -180,6 +180,24 @@
+
+ #ifndef __ASSEMBLY__
+ #include <asm-generic/pgtable.h>
++
++/*
++ * Macro to mark a page protection value as "uncacheable".
++ */
++#ifdef SUN3_PAGE_NOCACHE
++# define __SUN3_PAGE_NOCACHE SUN3_PAGE_NOCACHE
++#else
++# define __SUN3_PAGE_NOCACHE 0
++#endif
++#define pgprot_noncached(prot) \
++ (MMU_IS_SUN3 \
++ ? (__pgprot(pgprot_val(prot) | __SUN3_PAGE_NOCACHE)) \
++ : ((MMU_IS_851 || MMU_IS_030) \
++ ? (__pgprot(pgprot_val(prot) | _PAGE_NOCACHE030)) \
++ : (MMU_IS_040 || MMU_IS_060) \
++ ? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S)) \
++ : (prot)))
++
+ #endif /* !__ASSEMBLY__ */
+
+ /*
+diff -urN kernel-source-2.4.27.orig/include/asm-ppc/pgtable.h kernel-source-2.4.27.bjorn/include/asm-ppc/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-ppc/pgtable.h 2004-02-18 06:36:32.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/asm-ppc/pgtable.h 2005-03-14 10:36:16.689392263 -0700
+@@ -587,6 +587,11 @@
+ pte_update(ptep, 0, _PAGE_DIRTY);
+ }
+
++/*
++ * Macro to mark a page protection value as "uncacheable".
++ */
++#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
++
+ #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0)
+
+ #define pmd_page(pmd) (pmd_val(pmd) & PAGE_MASK)
+diff -urN kernel-source-2.4.27.orig/include/asm-ppc64/pgtable.h kernel-source-2.4.27.bjorn/include/asm-ppc64/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-ppc64/pgtable.h 2003-08-25 05:44:44.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-ppc64/pgtable.h 2005-03-14 10:36:16.689392263 -0700
+@@ -317,6 +317,11 @@
+ pte_update(ptep, 0, _PAGE_DIRTY);
+ }
+
++/*
++ * Macro to mark a page protection value as "uncacheable".
++ */
++#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_NO_CACHE | _PAGE_GUARDED))
++
+ #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HPTEFLAGS) == 0)
+
+ /*
+diff -urN kernel-source-2.4.27.orig/include/asm-x86_64/pgtable.h kernel-source-2.4.27.bjorn/include/asm-x86_64/pgtable.h
+--- kernel-source-2.4.27.orig/include/asm-x86_64/pgtable.h 2004-04-14 07:05:40.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/asm-x86_64/pgtable.h 2005-03-14 10:36:16.690368826 -0700
+@@ -342,6 +342,11 @@
+ static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_DIRTY, ptep); }
+
+ /*
++ * Macro to mark a page protection value as "uncacheable".
++ */
++#define pgprot_noncached(prot) (__pgprot(pgprot_val(prot) | _PAGE_PCD | _PAGE_PWT))
++
++/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+diff -urN kernel-source-2.4.27.orig/include/linux/agp_backend.h kernel-source-2.4.27.bjorn/include/linux/agp_backend.h
+--- kernel-source-2.4.27.orig/include/linux/agp_backend.h 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/agp_backend.h 2005-03-14 10:36:16.690368826 -0700
+@@ -142,6 +142,7 @@
+ size_t page_count;
+ int num_scratch_pages;
+ unsigned long *memory;
++ void *vmptr;
+ off_t pg_start;
+ u32 type;
+ u32 physical;
+diff -urN kernel-source-2.4.27.orig/include/linux/fs.h kernel-source-2.4.27.bjorn/include/linux/fs.h
+--- kernel-source-2.4.27.orig/include/linux/fs.h 2005-01-19 02:57:51.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/fs.h 2005-03-14 10:36:16.691345388 -0700
+@@ -249,7 +249,7 @@
+ /* First cache line: */
+ struct buffer_head *b_next; /* Hash queue list */
+ unsigned long b_blocknr; /* block number */
+- unsigned short b_size; /* block size */
++ unsigned int b_size; /* block size */
+ unsigned short b_list; /* List that this buffer appears */
+ kdev_t b_dev; /* device (B_FREE = free) */
+
+diff -urN kernel-source-2.4.27.orig/include/linux/highmem.h kernel-source-2.4.27.bjorn/include/linux/highmem.h
+--- kernel-source-2.4.27.orig/include/linux/highmem.h 2003-08-25 05:44:44.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/linux/highmem.h 2005-03-14 10:36:16.692321950 -0700
+@@ -84,7 +84,7 @@
+ static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
+ {
+ void *addr = kmap_atomic(page, KM_USER0);
+- clear_user_page(addr, vaddr);
++ clear_user_page(addr, vaddr, page);
+ kunmap_atomic(addr, KM_USER0);
+ }
+
+@@ -116,7 +116,7 @@
+
+ vfrom = kmap_atomic(from, KM_USER0);
+ vto = kmap_atomic(to, KM_USER1);
+- copy_user_page(vto, vfrom, vaddr);
++ copy_user_page(vto, vfrom, vaddr, to);
+ kunmap_atomic(vfrom, KM_USER0);
+ kunmap_atomic(vto, KM_USER1);
+ }
+diff -urN kernel-source-2.4.27.orig/include/linux/hugetlb.h kernel-source-2.4.27.bjorn/include/linux/hugetlb.h
+--- kernel-source-2.4.27.orig/include/linux/hugetlb.h 1969-12-31 17:00:00.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/hugetlb.h 2005-03-14 10:36:16.692321950 -0700
+@@ -0,0 +1,102 @@
++#ifndef _LINUX_HUGETLB_H
++#define _LINUX_HUGETLB_H
++
++#ifdef CONFIG_HUGETLB_PAGE
++
++#define COLOR_HALIGN(addr) ((addr + HPAGE_SIZE - 1) & ~(HPAGE_SIZE - 1))
++struct ctl_table;
++
++static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
++{
++ return vma->vm_flags & VM_HUGETLB;
++}
++static inline int is_hugepage_addr(unsigned long addr)
++{
++ return (rgn_index(addr) == REGION_HPAGE);
++}
++
++int hugetlb_sysctl_handler(struct ctl_table *, int, struct file *, void *, size_t *);
++int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *, struct vm_area_struct *);
++int follow_hugetlb_page(struct mm_struct *, struct vm_area_struct *, struct page **, struct vm_area_struct **, unsigned long *, int *, int);
++void zap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
++void unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long);
++int hugetlb_prefault(struct address_space *, struct vm_area_struct *);
++void huge_page_release(struct page *);
++int hugetlb_report_meminfo(char *);
++int is_hugepage_mem_enough(size_t);
++int is_aligned_hugepage_range(unsigned long addr, unsigned long len);
++void hugetlb_free_pgtables(struct mm_struct * mm, struct vm_area_struct * prev,
++ unsigned long start, unsigned long end);
++
++extern int htlbpage_max;
++
++#else /* !CONFIG_HUGETLB_PAGE */
++static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
++{
++ return 0;
++}
++
++#define follow_hugetlb_page(m,v,p,vs,a,b,i) ({ BUG(); 0; })
++#define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; })
++#define hugetlb_prefault(mapping, vma) ({ BUG(); 0; })
++#define zap_hugepage_range(vma, start, len) BUG()
++#define unmap_hugepage_range(vma, start, end) BUG()
++#define huge_page_release(page) BUG()
++#define hugetlb_report_meminfo(buf) 0
++#define is_hugepage_mem_enough(size) 0
++#define is_hugepage_addr(addr) 0
++#define is_aligned_hugepage_range(addr, len) 0
++#define hugetlb_free_pgtables(mm, prev, start, end) do { } while (0)
++
++#endif /* !CONFIG_HUGETLB_PAGE */
++
++#ifdef CONFIG_HUGETLBFS
++struct hugetlbfs_config {
++ uid_t uid;
++ gid_t gid;
++ umode_t mode;
++ long nr_blocks;
++ long nr_inodes;
++};
++
++struct hugetlbfs_sb_info {
++ long max_blocks; /* How many blocks are allowed */
++ long free_blocks; /* How many are left for allocation */
++ long max_inodes; /* How many inodes are allowed */
++ long free_inodes; /* How many are left for allocation */
++ spinlock_t stat_lock;
++};
++
++static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb)
++{
++ return sb->u.generic_sbp;
++}
++
++#define PSEUDO_DIRENT_SIZE 20
++
++extern struct file_operations hugetlbfs_file_operations;
++extern struct vm_operations_struct hugetlb_vm_ops;
++struct file *hugetlb_zero_setup(size_t);
++int hugetlb_get_quota(struct address_space *mapping);
++void hugetlb_put_quota(struct address_space *mapping);
++
++static inline int is_file_hugepages(struct file *file)
++{
++ return file->f_op == &hugetlbfs_file_operations;
++}
++
++static inline void set_file_hugepages(struct file *file)
++{
++ file->f_op = &hugetlbfs_file_operations;
++}
++#else /* !CONFIG_HUGETLBFS */
++
++#define is_file_hugepages(file) 0
++#define set_file_hugepages(file) BUG()
++#define hugetlb_zero_setup(size) ERR_PTR(-ENOSYS)
++#define hugetlb_get_quota(mapping) 0
++#define hugetlb_put_quota(mapping) 0
++
++#endif /* !CONFIG_HUGETLBFS */
++
++#endif /* _LINUX_HUGETLB_H */
+diff -urN kernel-source-2.4.27.orig/include/linux/irq.h kernel-source-2.4.27.bjorn/include/linux/irq.h
+--- kernel-source-2.4.27.orig/include/linux/irq.h 2002-08-02 18:39:45.000000000 -0600
++++ kernel-source-2.4.27.bjorn/include/linux/irq.h 2005-03-14 10:36:16.693298513 -0700
+@@ -56,7 +56,7 @@
+ *
+ * Pad this out to 32 bytes for cache and indexing reasons.
+ */
+-typedef struct {
++typedef struct irq_desc {
+ unsigned int status; /* IRQ status */
+ hw_irq_controller *handler;
+ struct irqaction *action; /* IRQ action list */
+@@ -64,8 +64,6 @@
+ spinlock_t lock;
+ } ____cacheline_aligned irq_desc_t;
+
+-extern irq_desc_t irq_desc [NR_IRQS];
+-
+ #include <asm/hw_irq.h> /* the arch dependent stuff */
+
+ extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
+diff -urN kernel-source-2.4.27.orig/include/linux/irq_cpustat.h kernel-source-2.4.27.bjorn/include/linux/irq_cpustat.h
+--- kernel-source-2.4.27.orig/include/linux/irq_cpustat.h 2001-11-22 12:46:18.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/irq_cpustat.h 2005-03-14 10:38:36.533140550 -0700
+@@ -23,15 +23,31 @@
+ #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
+ #else
+ #define __IRQ_STAT(cpu, member) ((void)(cpu), irq_stat[0].member)
+-#endif
++#endif
+
+ /* arch independent irq_stat fields */
+ #define softirq_pending(cpu) __IRQ_STAT((cpu), __softirq_pending)
+-#define local_irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count)
+-#define local_bh_count(cpu) __IRQ_STAT((cpu), __local_bh_count)
++#define irq_count(cpu) __IRQ_STAT((cpu), __local_irq_count)
++#define bh_count(cpu) __IRQ_STAT((cpu), __local_bh_count)
+ #define syscall_count(cpu) __IRQ_STAT((cpu), __syscall_count)
+ #define ksoftirqd_task(cpu) __IRQ_STAT((cpu), __ksoftirqd_task)
+ /* arch dependent irq_stat fields */
+ #define nmi_count(cpu) __IRQ_STAT((cpu), __nmi_count) /* i386, ia64 */
+
++#define local_hardirq_trylock() hardirq_trylock(smp_processor_id())
++#define local_hardirq_endlock() hardirq_trylock(smp_processor_id())
++#define local_irq_enter(irq) irq_enter(smp_processor_id(), (irq))
++#define local_irq_exit(irq) irq_exit(smp_processor_id(), (irq))
++#define local_softirq_pending() softirq_pending(smp_processor_id())
++#define local_ksoftirqd_task() ksoftirqd_task(smp_processor_id())
++
++/* These will lose the "really_" prefix when the interim macros below are removed. */
++#define really_local_irq_count()irq_count(smp_processor_id())
++#define really_local_bh_count() bh_count(smp_processor_id())
++
++/* Interim macros for backward compatibility. They are deprecated. Use irq_count() and
++ bh_count() instead. --davidm 01/11/28 */
++#define local_irq_count(cpu) irq_count(cpu)
++#define local_bh_count(cpu) bh_count(cpu)
++
+ #endif /* __irq_cpustat_h */
+diff -urN kernel-source-2.4.27.orig/include/linux/mm.h kernel-source-2.4.27.bjorn/include/linux/mm.h
+--- kernel-source-2.4.27.orig/include/linux/mm.h 2005-01-19 02:57:58.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/mm.h 2005-03-14 10:36:16.695251638 -0700
+@@ -103,6 +103,9 @@
+ #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */
+ #define VM_DONTEXPAND 0x00040000 /* Cannot expand with mremap() */
+ #define VM_RESERVED 0x00080000 /* Don't unmap it from swap_out */
++#define VM_WRITECOMBINED 0x00100000 /* Write-combined */
++#define VM_NONCACHED 0x00200000 /* Noncached access */
++#define VM_HUGETLB 0x00400000 /* Huge tlb Page*/
+
+ #ifndef VM_STACK_FLAGS
+ #define VM_STACK_FLAGS 0x00000177
+diff -urN kernel-source-2.4.27.orig/include/linux/mmzone.h kernel-source-2.4.27.bjorn/include/linux/mmzone.h
+--- kernel-source-2.4.27.orig/include/linux/mmzone.h 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/mmzone.h 2005-03-14 10:36:16.695251638 -0700
+@@ -8,6 +8,12 @@
+ #include <linux/spinlock.h>
+ #include <linux/list.h>
+ #include <linux/wait.h>
++#ifdef CONFIG_DISCONTIGMEM
++#include <asm/numnodes.h>
++#endif
++#ifndef MAX_NUMNODES
++#define MAX_NUMNODES 1
++#endif
+
+ /*
+ * Free memory management - zoned buddy allocator.
+@@ -134,7 +140,7 @@
+ * footprint of this construct is very small.
+ */
+ typedef struct zonelist_struct {
+- zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
++ zone_t * zones [MAX_NUMNODES*MAX_NR_ZONES+1]; // NULL delimited
+ } zonelist_t;
+
+ #define GFP_ZONEMASK 0x0f
+@@ -236,6 +242,18 @@
+ #define for_each_zone(zone) \
+ for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
+
++#ifdef CONFIG_NUMA
++#define MAX_NR_MEMBLKS BITS_PER_LONG /* Max number of Memory Blocks */
++#include <asm/topology.h>
++#else /* !CONFIG_NUMA */
++#define MAX_NR_MEMBLKS 1
++#endif /* CONFIG_NUMA */
++
++/* Returns the number of the current Node. */
++
++#ifndef CONFIG_NUMA
++#define numa_node_id() (__cpu_to_node(smp_processor_id()))
++#endif
+
+ #ifndef CONFIG_DISCONTIGMEM
+
+diff -urN kernel-source-2.4.27.orig/include/linux/shm.h kernel-source-2.4.27.bjorn/include/linux/shm.h
+--- kernel-source-2.4.27.orig/include/linux/shm.h 2001-11-22 12:46:18.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/shm.h 2005-03-14 10:36:16.695251638 -0700
+@@ -75,6 +75,7 @@
+ /* shm_mode upper byte flags */
+ #define SHM_DEST 01000 /* segment will be destroyed on last detach */
+ #define SHM_LOCKED 02000 /* segment will not be swapped */
++#define SHM_HUGETLB 04000 /* segment will use HugeTLB pages */
+
+ asmlinkage long sys_shmget (key_t key, size_t size, int flag);
+ asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, unsigned long *addr);
+diff -urN kernel-source-2.4.27.orig/include/linux/smp.h kernel-source-2.4.27.bjorn/include/linux/smp.h
+--- kernel-source-2.4.27.orig/include/linux/smp.h 2001-11-22 12:46:19.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/smp.h 2005-03-14 10:36:16.696228200 -0700
+@@ -35,11 +35,6 @@
+ extern void smp_boot_cpus(void);
+
+ /*
+- * Processor call in. Must hold processors until ..
+- */
+-extern void smp_callin(void);
+-
+-/*
+ * Multiprocessors may now schedule
+ */
+ extern void smp_commence(void);
+@@ -57,10 +52,6 @@
+
+ extern int smp_num_cpus;
+
+-extern volatile unsigned long smp_msg_data;
+-extern volatile int smp_src_cpu;
+-extern volatile int smp_msg_id;
+-
+ #define MSG_ALL_BUT_SELF 0x8000 /* Assume <32768 CPU's */
+ #define MSG_ALL 0x8001
+
+@@ -86,6 +77,7 @@
+ #define cpu_number_map(cpu) 0
+ #define smp_call_function(func,info,retry,wait) ({ 0; })
+ #define cpu_online_map 1
++#define cpu_online(cpu) (cpu == 0)
+
+ #endif
+ #endif
+diff -urN kernel-source-2.4.27.orig/include/linux/sysctl.h kernel-source-2.4.27.bjorn/include/linux/sysctl.h
+--- kernel-source-2.4.27.orig/include/linux/sysctl.h 2005-01-19 02:57:42.000000000 -0700
++++ kernel-source-2.4.27.bjorn/include/linux/sysctl.h 2005-03-14 10:44:54.072198425 -0700
+@@ -157,6 +157,7 @@
+ VM_MAPPED_RATIO=20, /* amount of unfreeable pages that triggers swapout */
+ VM_LAPTOP_MODE=21, /* kernel in laptop flush mode */
+ VM_BLOCK_DUMP=22, /* dump fs activity to log */
++ VM_HUGETLB_PAGES=23, /* int: Number of available Huge Pages */
+ };
+
+
+diff -urN kernel-source-2.4.27.orig/init/main.c kernel-source-2.4.27.bjorn/init/main.c
+--- kernel-source-2.4.27.orig/init/main.c 2005-01-19 02:57:53.000000000 -0700
++++ kernel-source-2.4.27.bjorn/init/main.c 2005-03-14 10:36:16.697204763 -0700
+@@ -314,6 +314,7 @@
+
+
+ extern void setup_arch(char **);
++extern void __init build_all_zonelists(void);
+ extern void cpu_idle(void);
+
+ unsigned long wait_init_idle;
+@@ -384,6 +385,7 @@
+ lock_kernel();
+ printk(linux_banner);
+ setup_arch(&command_line);
++ build_all_zonelists();
+ printk("Kernel command line: %s\n", saved_command_line);
+ parse_options(command_line);
+ trap_init();
+diff -urN kernel-source-2.4.27.orig/ipc/shm.c kernel-source-2.4.27.bjorn/ipc/shm.c
+--- kernel-source-2.4.27.orig/ipc/shm.c 2002-08-02 18:39:46.000000000 -0600
++++ kernel-source-2.4.27.bjorn/ipc/shm.c 2005-03-14 10:36:16.698181325 -0700
+@@ -18,6 +18,7 @@
+ #include <linux/config.h>
+ #include <linux/slab.h>
+ #include <linux/shm.h>
++#include <linux/hugetlb.h>
+ #include <linux/init.h>
+ #include <linux/file.h>
+ #include <linux/mman.h>
+@@ -125,7 +126,8 @@
+ shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ shm_rmid (shp->id);
+ shm_unlock(shp->id);
+- shmem_lock(shp->shm_file, 0);
++ if (!is_file_hugepages(shp->shm_file))
++ shmem_lock(shp->shm_file, 0);
+ fput (shp->shm_file);
+ kfree (shp);
+ }
+@@ -193,8 +195,12 @@
+ shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_USER);
+ if (!shp)
+ return -ENOMEM;
+- sprintf (name, "SYSV%08x", key);
+- file = shmem_file_setup(name, size);
++ if (shmflg & SHM_HUGETLB)
++ file = hugetlb_zero_setup(size);
++ else {
++ sprintf (name, "SYSV%08x", key);
++ file = shmem_file_setup(name, size);
++ }
+ error = PTR_ERR(file);
+ if (IS_ERR(file))
+ goto no_file;
+@@ -214,7 +220,10 @@
+ shp->id = shm_buildid(id,shp->shm_perm.seq);
+ shp->shm_file = file;
+ file->f_dentry->d_inode->i_ino = shp->id;
+- file->f_op = &shm_file_operations;
++ if (shmflg & SHM_HUGETLB)
++ set_file_hugepages(file);
++ else
++ file->f_op = &shm_file_operations;
+ shm_tot += numpages;
+ shm_unlock (id);
+ return shp->id;
+@@ -452,7 +461,10 @@
+ tbuf.shm_ctime = shp->shm_ctim;
+ tbuf.shm_cpid = shp->shm_cprid;
+ tbuf.shm_lpid = shp->shm_lprid;
+- tbuf.shm_nattch = shp->shm_nattch;
++ if (!is_file_hugepages(shp->shm_file))
++ tbuf.shm_nattch = shp->shm_nattch;
++ else
++ tbuf.shm_nattch = file_count(shp->shm_file)-1;
+ shm_unlock(shmid);
+ if(copy_shmid_to_user (buf, &tbuf, version))
+ return -EFAULT;
+@@ -474,10 +486,12 @@
+ if(err)
+ goto out_unlock;
+ if(cmd==SHM_LOCK) {
+- shmem_lock(shp->shm_file, 1);
++ if (!is_file_hugepages(shp->shm_file))
++ shmem_lock(shp->shm_file, 1);
+ shp->shm_flags |= SHM_LOCKED;
+ } else {
+- shmem_lock(shp->shm_file, 0);
++ if (!is_file_hugepages(shp->shm_file))
++ shmem_lock(shp->shm_file, 0);
+ shp->shm_flags &= ~SHM_LOCKED;
+ }
+ shm_unlock(shmid);
+@@ -678,7 +692,7 @@
+ down_write(&mm->mmap_sem);
+ for (shmd = mm->mmap; shmd; shmd = shmdnext) {
+ shmdnext = shmd->vm_next;
+- if (shmd->vm_ops == &shm_vm_ops
++ if (((shmd->vm_ops == &shm_vm_ops) || is_vm_hugetlb_page(shmd))
+ && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
+ do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
+ retval = 0;
+@@ -718,7 +732,7 @@
+ shp->shm_segsz,
+ shp->shm_cprid,
+ shp->shm_lprid,
+- shp->shm_nattch,
++ is_file_hugepages(shp->shm_file) ? (file_count(shp->shm_file)-1) : shp->shm_nattch,
+ shp->shm_perm.uid,
+ shp->shm_perm.gid,
+ shp->shm_perm.cuid,
+diff -urN kernel-source-2.4.27.orig/kernel/printk.c kernel-source-2.4.27.bjorn/kernel/printk.c
+--- kernel-source-2.4.27.orig/kernel/printk.c 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/kernel/printk.c 2005-03-14 10:36:16.699157888 -0700
+@@ -330,6 +330,12 @@
+ __call_console_drivers(start, end);
+ }
+ }
++#ifdef CONFIG_IA64_EARLY_PRINTK
++ if (!console_drivers) {
++ void early_printk (const char *str, size_t len);
++ early_printk(&LOG_BUF(start), end - start);
++ }
++#endif
+ }
+
+ /*
+@@ -696,3 +702,101 @@
+ tty->driver.write(tty, 0, msg, strlen(msg));
+ return;
+ }
++
++#ifdef CONFIG_IA64_EARLY_PRINTK
++
++#include <asm/io.h>
++
++#ifdef CONFIG_IA64_EARLY_PRINTK_UART
++
++#include <linux/serial_reg.h>
++#include <asm/system.h>
++
++static void early_printk_uart(const char *str, size_t len)
++{
++ static char *uart = 0;
++ unsigned long uart_base;
++ char c;
++
++ if (!uart) {
++#ifdef CONFIG_SERIAL_HCDP
++ extern unsigned long hcdp_early_uart(void);
++ uart_base = hcdp_early_uart();
++#endif
++#if CONFIG_IA64_EARLY_PRINTK_UART_BASE
++ uart_base = CONFIG_IA64_EARLY_PRINTK_UART_BASE;
++#endif
++ if (uart_base)
++ uart = ioremap(uart_base, 64);
++ }
++
++ if (!uart)
++ return;
++
++ while (len-- > 0) {
++ c = *str++;
++ while (!(UART_LSR_TEMT & readb(uart + UART_LSR)))
++ ; /* spin */
++
++ writeb(c, uart + UART_TX);
++
++ if (c == '\n')
++ writeb('\r', uart + UART_TX);
++ }
++}
++#endif /* CONFIG_IA64_EARLY_PRINTK_UART */
++
++#ifdef CONFIG_IA64_EARLY_PRINTK_VGA
++
++#define VGABASE ((char *)0xc0000000000b8000)
++#define VGALINES 24
++#define VGACOLS 80
++
++static int current_ypos = VGALINES, current_xpos = 0;
++
++static void early_printk_vga(const char *str, size_t len)
++{
++ char c;
++ int i, k, j;
++
++ while (len-- > 0) {
++ c = *str++;
++ if (current_ypos >= VGALINES) {
++ /* scroll 1 line up */
++ for (k = 1, j = 0; k < VGALINES; k++, j++) {
++ for (i = 0; i < VGACOLS; i++) {
++ writew(readw(VGABASE + 2*(VGACOLS*k + i)),
++ VGABASE + 2*(VGACOLS*j + i));
++ }
++ }
++ for (i = 0; i < VGACOLS; i++) {
++ writew(0x720, VGABASE + 2*(VGACOLS*j + i));
++ }
++ current_ypos = VGALINES-1;
++ }
++ if (c == '\n') {
++ current_xpos = 0;
++ current_ypos++;
++ } else if (c != '\r') {
++ writew(((0x7 << 8) | (unsigned short) c),
++ VGABASE + 2*(VGACOLS*current_ypos + current_xpos++));
++ if (current_xpos >= VGACOLS) {
++ current_xpos = 0;
++ current_ypos++;
++ }
++ }
++ }
++}
++#endif /* CONFIG_IA64_EARLY_PRINTK_VGA */
++
++void early_printk(const char *str, size_t len)
++{
++#ifdef CONFIG_IA64_EARLY_PRINTK_UART
++ early_printk_uart(str, len);
++#endif
++#ifdef CONFIG_IA64_EARLY_PRINTK_VGA
++ early_printk_vga(str, len);
++#endif
++}
++
++#endif /* CONFIG_IA64_EARLY_PRINTK */
+diff -urN kernel-source-2.4.27.orig/kernel/signal.c kernel-source-2.4.27.bjorn/kernel/signal.c
+--- kernel-source-2.4.27.orig/kernel/signal.c 2004-02-18 06:36:32.000000000 -0700
++++ kernel-source-2.4.27.bjorn/kernel/signal.c 2005-03-14 10:36:16.699157888 -0700
+@@ -1171,8 +1171,19 @@
+ ss_sp = NULL;
+ } else {
+ error = -ENOMEM;
++#ifdef __ia64__
++ /*
++ * XXX fix me: due to an oversight, MINSIGSTKSZ used to be defined
++ * as 2KB, which is far too small. This was after Linux kernel
++ * 2.4.9 but since there are a fair number of ia64 apps out there,
++ * we continue to allow "too" small sigaltstacks for a while.
++ */
++ if (ss_size < 2048)
++ goto out;
++#else
+ if (ss_size < MINSIGSTKSZ)
+ goto out;
++#endif
+ }
+
+ current->sas_ss_sp = (unsigned long) ss_sp;
+diff -urN kernel-source-2.4.27.orig/kernel/softirq.c kernel-source-2.4.27.bjorn/kernel/softirq.c
+--- kernel-source-2.4.27.orig/kernel/softirq.c 2002-11-28 16:53:15.000000000 -0700
++++ kernel-source-2.4.27.bjorn/kernel/softirq.c 2005-03-14 10:36:16.700134450 -0700
+@@ -40,7 +40,10 @@
+ - Bottom halves: globally serialized, grr...
+ */
+
++/* No separate irq_stat for ia64, it is part of PSA */
++#if !defined(CONFIG_IA64)
+ irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
++#endif
+
+ static struct softirq_action softirq_vec[32] __cacheline_aligned;
+
+@@ -60,7 +63,6 @@
+
+ asmlinkage void do_softirq()
+ {
+- int cpu = smp_processor_id();
+ __u32 pending;
+ unsigned long flags;
+ __u32 mask;
+@@ -70,7 +72,7 @@
+
+ local_irq_save(flags);
+
+- pending = softirq_pending(cpu);
++ pending = local_softirq_pending();
+
+ if (pending) {
+ struct softirq_action *h;
+@@ -79,7 +81,7 @@
+ local_bh_disable();
+ restart:
+ /* Reset the pending bitmask before enabling irqs */
+- softirq_pending(cpu) = 0;
++ local_softirq_pending() = 0;
+
+ local_irq_enable();
+
+@@ -94,7 +96,7 @@
+
+ local_irq_disable();
+
+- pending = softirq_pending(cpu);
++ pending = local_softirq_pending();
+ if (pending & mask) {
+ mask &= ~pending;
+ goto restart;
+@@ -102,7 +104,7 @@
+ __local_bh_enable();
+
+ if (pending)
+- wakeup_softirqd(cpu);
++ wakeup_softirqd(smp_processor_id());
+ }
+
+ local_irq_restore(flags);
+@@ -124,7 +126,7 @@
+ * Otherwise we wake up ksoftirqd to make sure we
+ * schedule the softirq soon.
+ */
+- if (!(local_irq_count(cpu) | local_bh_count(cpu)))
++ if (!(irq_count(cpu) | bh_count(cpu)))
+ wakeup_softirqd(cpu);
+ }
+
+@@ -287,18 +289,16 @@
+
+ static void bh_action(unsigned long nr)
+ {
+- int cpu = smp_processor_id();
+-
+ if (!spin_trylock(&global_bh_lock))
+ goto resched;
+
+- if (!hardirq_trylock(cpu))
++ if (!local_hardirq_trylock())
+ goto resched_unlock;
+
+ if (bh_base[nr])
+ bh_base[nr]();
+
+- hardirq_endlock(cpu);
++ local_hardirq_endlock();
+ spin_unlock(&global_bh_lock);
+ return;
+
+@@ -377,15 +377,15 @@
+ __set_current_state(TASK_INTERRUPTIBLE);
+ mb();
+
+- ksoftirqd_task(cpu) = current;
++ local_ksoftirqd_task() = current;
+
+ for (;;) {
+- if (!softirq_pending(cpu))
++ if (!local_softirq_pending())
+ schedule();
+
+ __set_current_state(TASK_RUNNING);
+
+- while (softirq_pending(cpu)) {
++ while (local_softirq_pending()) {
+ do_softirq();
+ if (current->need_resched)
+ schedule();
+diff -urN kernel-source-2.4.27.orig/kernel/sysctl.c kernel-source-2.4.27.bjorn/kernel/sysctl.c
+--- kernel-source-2.4.27.orig/kernel/sysctl.c 2004-08-07 17:26:06.000000000 -0600
++++ kernel-source-2.4.27.bjorn/kernel/sysctl.c 2005-03-14 10:36:16.701111013 -0700
+@@ -31,6 +31,7 @@
+ #include <linux/sysrq.h>
+ #include <linux/highuid.h>
+ #include <linux/swap.h>
++#include <linux/hugetlb.h>
+
+ #include <asm/uaccess.h>
+
+@@ -315,6 +316,10 @@
+ &laptop_mode, sizeof(int), 0644, NULL, &proc_dointvec},
+ {VM_BLOCK_DUMP, "block_dump",
+ &block_dump, 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}
+ };
+
+diff -urN kernel-source-2.4.27.orig/kernel/time.c kernel-source-2.4.27.bjorn/kernel/time.c
+--- kernel-source-2.4.27.orig/kernel/time.c 2002-11-28 16:53:15.000000000 -0700
++++ kernel-source-2.4.27.bjorn/kernel/time.c 2005-03-14 10:36:16.701111013 -0700
+@@ -39,6 +39,7 @@
+ /* The xtime_lock is not only serializing the xtime read/writes but it's also
+ serializing all accesses to the global NTP variables now. */
+ extern rwlock_t xtime_lock;
++extern unsigned long last_time_offset;
+
+ #if !defined(__alpha__) && !defined(__ia64__)
+
+@@ -84,6 +85,7 @@
+ xtime.tv_sec = value;
+ xtime.tv_usec = 0;
+ vxtime_unlock();
++ last_time_offset = 0;
+ time_adjust = 0; /* stop active adjtime() */
+ time_status |= STA_UNSYNC;
+ time_maxerror = NTP_PHASE_LIMIT;
+@@ -131,6 +133,7 @@
+ vxtime_lock();
+ xtime.tv_sec += sys_tz.tz_minuteswest * 60;
+ vxtime_unlock();
++ last_time_offset = 0;
+ write_unlock_irq(&xtime_lock);
+ }
+
+@@ -217,7 +220,7 @@
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+-
++
+ /* Now we validate the data before disabling interrupts */
+
+ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+@@ -228,7 +231,7 @@
+ if (txc->modes != ADJ_OFFSET_SINGLESHOT && (txc->modes & ADJ_OFFSET))
+ /* adjustment Offset limited to +- .512 seconds */
+ if (txc->offset <= - MAXPHASE || txc->offset >= MAXPHASE )
+- return -EINVAL;
++ return -EINVAL;
+
+ /* if the quartz is off by more than 10% something is VERY wrong ! */
+ if (txc->modes & ADJ_TICK)
+@@ -365,7 +368,7 @@
+ && (time_status & (STA_PPSWANDER|STA_PPSERROR)) != 0))
+ /* p. 24, (d) */
+ result = TIME_ERROR;
+-
++
+ if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT)
+ txc->offset = save_adjust;
+ else {
+@@ -390,6 +393,7 @@
+ txc->calcnt = pps_calcnt;
+ txc->errcnt = pps_errcnt;
+ txc->stbcnt = pps_stbcnt;
++ last_time_offset = 0;
+ write_unlock_irq(&xtime_lock);
+ do_gettimeofday(&txc->time);
+ return(result);
+diff -urN kernel-source-2.4.27.orig/kernel/timer.c kernel-source-2.4.27.bjorn/kernel/timer.c
+--- kernel-source-2.4.27.orig/kernel/timer.c 2002-11-28 16:53:15.000000000 -0700
++++ kernel-source-2.4.27.bjorn/kernel/timer.c 2005-03-14 10:36:16.702087575 -0700
+@@ -615,7 +615,7 @@
+ else
+ kstat.per_cpu_user[cpu] += user_tick;
+ kstat.per_cpu_system[cpu] += system;
+- } else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
++ } else if (really_local_bh_count() || really_local_irq_count() > 1)
+ kstat.per_cpu_system[cpu] += system;
+ }
+
+@@ -667,6 +667,7 @@
+ * This spinlock protect us from races in SMP while playing with xtime. -arca
+ */
+ rwlock_t xtime_lock = RW_LOCK_UNLOCKED;
++unsigned long last_time_offset;
+
+ static inline void update_times(void)
+ {
+@@ -686,6 +687,7 @@
+ update_wall_time(ticks);
+ }
+ vxtime_unlock();
++ last_time_offset = 0;
+ write_unlock_irq(&xtime_lock);
+ calc_load(ticks);
+ }
+@@ -698,7 +700,7 @@
+
+ void do_timer(struct pt_regs *regs)
+ {
+- (*(unsigned long *)&jiffies)++;
++ (*(volatile unsigned long *)&jiffies)++;
+ #ifndef CONFIG_SMP
+ /* SMP process accounting uses the local APIC timer */
+
+@@ -844,7 +846,7 @@
+ if (t.tv_nsec >= 1000000000L || t.tv_nsec < 0 || t.tv_sec < 0)
+ return -EINVAL;
+
+-
++#if !defined(__ia64__)
+ if (t.tv_sec == 0 && t.tv_nsec <= 2000000L &&
+ current->policy != SCHED_OTHER)
+ {
+@@ -857,6 +859,7 @@
+ udelay((t.tv_nsec + 999) / 1000);
+ return 0;
+ }
++#endif
+
+ expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
+
+diff -urN kernel-source-2.4.27.orig/mm/bootmem.c kernel-source-2.4.27.bjorn/mm/bootmem.c
+--- kernel-source-2.4.27.orig/mm/bootmem.c 2002-11-28 16:53:15.000000000 -0700
++++ kernel-source-2.4.27.bjorn/mm/bootmem.c 2005-03-14 10:36:16.702087575 -0700
+@@ -49,8 +49,24 @@
+ bootmem_data_t *bdata = pgdat->bdata;
+ unsigned long mapsize = ((end - start)+7)/8;
+
+- pgdat->node_next = pgdat_list;
+- pgdat_list = pgdat;
++
++ /*
++ * sort pgdat_list so that the lowest one comes first,
++ * which makes alloc_bootmem_low_pages work as desired.
++ */
++ if (!pgdat_list || pgdat_list->node_start_paddr > pgdat->node_start_paddr) {
++ pgdat->node_next = pgdat_list;
++ pgdat_list = pgdat;
++ } else {
++ pg_data_t *tmp = pgdat_list;
++ while (tmp->node_next) {
++ if (tmp->node_next->node_start_paddr > pgdat->node_start_paddr)
++ break;
++ tmp = tmp->node_next;
++ }
++ pgdat->node_next = tmp->node_next;
++ tmp->node_next = pgdat;
++ }
+
+ mapsize = (mapsize + (sizeof(long) - 1UL)) & ~(sizeof(long) - 1UL);
+ bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
+@@ -144,6 +160,7 @@
+ static void * __init __alloc_bootmem_core (bootmem_data_t *bdata,
+ unsigned long size, unsigned long align, unsigned long goal)
+ {
++ static unsigned long last_success;
+ unsigned long i, start = 0;
+ void *ret;
+ unsigned long offset, remaining_size;
+@@ -169,6 +186,9 @@
+ if (goal && (goal >= bdata->node_boot_start) &&
+ ((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
+ preferred = goal - bdata->node_boot_start;
++
++ if (last_success >= preferred)
++ preferred = last_success;
+ } else
+ preferred = 0;
+
+@@ -180,6 +200,8 @@
+ restart_scan:
+ for (i = preferred; i < eidx; i += incr) {
+ unsigned long j;
++ i = find_next_zero_bit((char *)bdata->node_bootmem_map, eidx, i);
++ i = (i + incr - 1) & -incr;
+ if (test_bit(i, bdata->node_bootmem_map))
+ continue;
+ for (j = i + 1; j < i + areasize; ++j) {
+@@ -198,6 +220,7 @@
+ }
+ return NULL;
+ found:
++ last_success = start << PAGE_SHIFT;
+ if (start >= eidx)
+ BUG();
+
+@@ -244,22 +267,24 @@
+
+ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
+ {
+- struct page *page = pgdat->node_mem_map;
+ bootmem_data_t *bdata = pgdat->bdata;
+ unsigned long i, count, total = 0;
++ struct page *page;
+ unsigned long idx;
+
+ if (!bdata->node_bootmem_map) BUG();
+
+ count = 0;
++ page = virt_to_page(phys_to_virt(bdata->node_boot_start));
+ idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+- for (i = 0; i < idx; i++, page++) {
+- if (!test_bit(i, bdata->node_bootmem_map)) {
+- count++;
+- ClearPageReserved(page);
+- set_page_count(page, 1);
+- __free_page(page);
+- }
++ for (i = find_first_zero_bit(bdata->node_bootmem_map, idx);
++ i < idx;
++ i = find_next_zero_bit(bdata->node_bootmem_map, idx, i + 1))
++ {
++ count++;
++ ClearPageReserved(page+i);
++ set_page_count(page+i, 1);
++ __free_page(page+i);
+ }
+ total += count;
+
+diff -urN kernel-source-2.4.27.orig/mm/memory.c kernel-source-2.4.27.bjorn/mm/memory.c
+--- kernel-source-2.4.27.orig/mm/memory.c 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/mm/memory.c 2005-03-14 10:36:16.703064138 -0700
+@@ -37,6 +37,7 @@
+ */
+
+ #include <linux/mm.h>
++#include <linux/hugetlb.h>
+ #include <linux/mman.h>
+ #include <linux/swap.h>
+ #include <linux/smp_lock.h>
+@@ -121,7 +122,7 @@
+ pmd = pmd_offset(dir, 0);
+ pgd_clear(dir);
+ for (j = 0; j < PTRS_PER_PMD ; j++) {
+- prefetchw(pmd+j+(PREFETCH_STRIDE/16));
++ prefetchw(pmd + j + PREFETCH_STRIDE/sizeof(*pmd));
+ free_one_pmd(pmd+j);
+ }
+ pmd_free(pmd);
+@@ -181,6 +182,9 @@
+ unsigned long end = vma->vm_end;
+ unsigned long cow = (vma->vm_flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE;
+
++ if (is_vm_hugetlb_page(vma))
++ return copy_hugetlb_page_range(dst, src, vma);
++
+ src_pgd = pgd_offset(src, address)-1;
+ dst_pgd = pgd_offset(dst, address)-1;
+
+@@ -473,6 +477,10 @@
+ if ( !vma || (pages && vma->vm_flags & VM_IO) || !(flags & vma->vm_flags) )
+ return i ? : -EFAULT;
+
++ if (is_vm_hugetlb_page(vma)) {
++ i = follow_hugetlb_page(mm, vma, pages, vmas, &start, &len, i);
++ continue;
++ }
+ spin_lock(&mm->page_table_lock);
+ do {
+ struct page *map;
+@@ -1371,6 +1379,9 @@
+ current->state = TASK_RUNNING;
+ pgd = pgd_offset(mm, address);
+
++ if (is_vm_hugetlb_page(vma))
++ return 0; /* mapping truncation does this. */
++
+ /*
+ * We need the page table lock to synchronize with kswapd
+ * and the SMP-safe atomic PTE updates.
+diff -urN kernel-source-2.4.27.orig/mm/mmap.c kernel-source-2.4.27.bjorn/mm/mmap.c
+--- kernel-source-2.4.27.orig/mm/mmap.c 2005-01-19 02:57:58.000000000 -0700
++++ kernel-source-2.4.27.bjorn/mm/mmap.c 2005-03-14 10:37:22.068297712 -0700
+@@ -15,6 +15,7 @@
+ #include <linux/fs.h>
+ #include <linux/personality.h>
+ #include <linux/mount.h>
++#include <linux/hugetlb.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -600,7 +601,10 @@
+ fput(file);
+
+ /* Undo any partial mapping done by a device driver. */
+- zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
++ if (is_vm_hugetlb_page(vma))
++ zap_hugepage_range(vma, vma->vm_start, vma->vm_end-vma->vm_start);
++ else
++ zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
+ free_vma:
+ kmem_cache_free(vm_area_cachep, vma);
+ return error;
+@@ -650,10 +654,26 @@
+ unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags)
+ {
+ if (flags & MAP_FIXED) {
++ unsigned long ret;
++
+ if (addr > TASK_SIZE - len)
+ return -ENOMEM;
+ if (addr & ~PAGE_MASK)
+ return -EINVAL;
++ if (file && is_file_hugepages(file))
++ /* If the request is for hugepages, then make sure
++ * that addr and length is properly aligned.
++ */
++ ret = is_aligned_hugepage_range(addr, len);
++ else
++ /*
++ * Make sure that a normal request is not falling
++ * in reserved hugepage range. For some archs like
++ * IA-64, there is a separate region for hugepages.
++ */
++ ret = is_invalid_hugepage_range(addr, len);
++ if (ret)
++ return ret;
+ return addr;
+ }
+
+@@ -947,6 +967,12 @@
+ return 0;
+ /* we have addr < mpnt->vm_end */
+
++ if (is_vm_hugetlb_page(mpnt)) {
++ int ret = is_aligned_hugepage_range(addr, len);
++ if (ret)
++ return ret;
++ }
++
+ if (mpnt->vm_start >= addr+len)
+ return 0;
+
+@@ -1000,7 +1026,10 @@
+ remove_shared_vm_struct(mpnt);
+ mm->map_count--;
+
+- zap_page_range(mm, st, size);
++ if (is_vm_hugetlb_page(mpnt))
++ zap_hugepage_range(mpnt, st, size);
++ else
++ zap_page_range(mm, st, size);
+
+ /*
+ * Fix the mapping, and free the old area if it wasn't reused.
+@@ -1015,7 +1044,10 @@
+ if (extra)
+ kmem_cache_free(vm_area_cachep, extra);
+
+- free_pgtables(mm, prev, addr, addr+len);
++ if (is_hugepage_addr(addr))
++ hugetlb_free_pgtables(mm, prev, addr, addr+len);
++ else
++ free_pgtables(mm, prev, addr, addr+len);
+
+ return 0;
+ }
+@@ -1175,7 +1207,10 @@
+ }
+ mm->map_count--;
+ remove_shared_vm_struct(mpnt);
+- zap_page_range(mm, start, size);
++ if (is_vm_hugetlb_page(mpnt))
++ zap_hugepage_range(mpnt, start, size);
++ else
++ zap_page_range(mm, start, size);
+ if (mpnt->vm_file)
+ fput(mpnt->vm_file);
+ kmem_cache_free(vm_area_cachep, mpnt);
+diff -urN kernel-source-2.4.27.orig/mm/mprotect.c kernel-source-2.4.27.bjorn/mm/mprotect.c
+--- kernel-source-2.4.27.orig/mm/mprotect.c 2003-11-28 11:26:21.000000000 -0700
++++ kernel-source-2.4.27.bjorn/mm/mprotect.c 2005-03-14 10:36:16.704040700 -0700
+@@ -7,6 +7,7 @@
+ #include <linux/smp_lock.h>
+ #include <linux/shm.h>
+ #include <linux/mman.h>
++#include <linux/hugetlb.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -294,6 +295,10 @@
+
+ /* Here we know that vma->vm_start <= nstart < vma->vm_end. */
+
++ if (is_vm_hugetlb_page(vma)) {
++ error = -EACCES;
++ goto out;
++ }
+ newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
+ if ((newflags & ~(newflags >> 4)) & 0xf) {
+ error = -EACCES;
+diff -urN kernel-source-2.4.27.orig/mm/mremap.c kernel-source-2.4.27.bjorn/mm/mremap.c
+--- kernel-source-2.4.27.orig/mm/mremap.c 2004-04-14 07:05:41.000000000 -0600
++++ kernel-source-2.4.27.bjorn/mm/mremap.c 2005-03-14 10:36:16.705017263 -0700
+@@ -9,6 +9,7 @@
+ #include <linux/shm.h>
+ #include <linux/mman.h>
+ #include <linux/swap.h>
++#include <linux/hugetlb.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/pgalloc.h>
+@@ -287,6 +288,10 @@
+ vma = find_vma(current->mm, addr);
+ if (!vma || vma->vm_start > addr)
+ goto out;
++ if (is_vm_hugetlb_page(vma)) {
++ ret = -EINVAL;
++ goto out;
++ }
+ /* We can't remap across vm area boundaries */
+ if (old_len > vma->vm_end - addr)
+ goto out;
+diff -urN kernel-source-2.4.27.orig/mm/page_alloc.c kernel-source-2.4.27.bjorn/mm/page_alloc.c
+--- kernel-source-2.4.27.orig/mm/page_alloc.c 2004-08-07 17:26:06.000000000 -0600
++++ kernel-source-2.4.27.bjorn/mm/page_alloc.c 2005-03-14 10:36:16.705993825 -0700
+@@ -77,11 +77,11 @@
+ /*
+ * Temporary debugging check.
+ */
+-#define BAD_RANGE(zone, page) \
+-( \
+- (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
+- || (((page) - mem_map) < (zone)->zone_start_mapnr) \
+- || ((zone) != page_zone(page)) \
++#define BAD_RANGE(zone, page) \
++( \
++ (((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
++ || (((page) - mem_map) < (zone)->zone_start_mapnr) \
++ || ((zone) != page_zone(page)) \
+ )
+
+ /*
+@@ -631,7 +631,7 @@
+ unsigned long nr, total, flags;
+
+ total = 0;
+- if (zone->size) {
++ if (zone->realsize) {
+ spin_lock_irqsave(&zone->lock, flags);
+ for (order = 0; order < MAX_ORDER; order++) {
+ head = &(zone->free_area + order)->free_list;
+@@ -663,13 +663,44 @@
+ /*
+ * Builds allocation fallback zone lists.
+ */
+-static inline void build_zonelists(pg_data_t *pgdat)
++static int __init build_zonelists_node(pg_data_t *pgdat, zonelist_t *zonelist, int j, int k)
+ {
+- int i, j, k;
++ zone_t *zone;
++ switch (k) {
++ default:
++ BUG();
++ /*
++ * fallthrough:
++ */
++ case ZONE_HIGHMEM:
++ zone = pgdat->node_zones + ZONE_HIGHMEM;
++ if (zone->realsize) {
++#ifndef CONFIG_HIGHMEM
++ BUG();
++#endif
++ zonelist->zones[j++] = zone;
++ }
++ case ZONE_NORMAL:
++ zone = pgdat->node_zones + ZONE_NORMAL;
++ if (zone->realsize)
++ zonelist->zones[j++] = zone;
++ case ZONE_DMA:
++ zone = pgdat->node_zones + ZONE_DMA;
++ if (zone->realsize)
++ zonelist->zones[j++] = zone;
++ }
++
++ return j;
++}
++
++static void __init build_zonelists(pg_data_t *pgdat)
++{
++ int i, j, k, node, local_node;
+
++ local_node = pgdat->node_id;
++ printk("Building zonelist for node : %d\n", local_node);
+ for (i = 0; i <= GFP_ZONEMASK; i++) {
+ zonelist_t *zonelist;
+- zone_t *zone;
+
+ zonelist = pgdat->node_zonelists + i;
+ memset(zonelist, 0, sizeof(*zonelist));
+@@ -681,33 +712,32 @@
+ if (i & __GFP_DMA)
+ k = ZONE_DMA;
+
+- switch (k) {
+- default:
+- BUG();
+- /*
+- * fallthrough:
+- */
+- case ZONE_HIGHMEM:
+- zone = pgdat->node_zones + ZONE_HIGHMEM;
+- if (zone->size) {
+-#ifndef CONFIG_HIGHMEM
+- BUG();
+-#endif
+- zonelist->zones[j++] = zone;
+- }
+- case ZONE_NORMAL:
+- zone = pgdat->node_zones + ZONE_NORMAL;
+- if (zone->size)
+- zonelist->zones[j++] = zone;
+- case ZONE_DMA:
+- zone = pgdat->node_zones + ZONE_DMA;
+- if (zone->size)
+- zonelist->zones[j++] = zone;
+- }
++ j = build_zonelists_node(pgdat, zonelist, j, k);
++ /*
++ * Now we build the zonelist so that it contains the zones
++ * of all the other nodes.
++ * We don't want to pressure a particular node, so when
++ * building the zones for node N, we make sure that the
++ * zones coming right after the local ones are those from
++ * node N+1 (modulo N)
++ */
++ for (node = local_node + 1; node < numnodes; node++)
++ j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
++ for (node = 0; node < local_node; node++)
++ j = build_zonelists_node(NODE_DATA(node), zonelist, j, k);
++
+ zonelist->zones[j++] = NULL;
+ }
+ }
+
++void __init build_all_zonelists(void)
++{
++ int i;
++
++ for(i = 0 ; i < numnodes ; i++)
++ build_zonelists(NODE_DATA(i));
++}
++
+ /*
+ * Helper functions to size the waitqueue hash table.
+ * Essentially these want to choose hash table sizes sufficiently
+@@ -750,6 +780,31 @@
+ return ffz(~size);
+ }
+
++static unsigned long memmap_init(struct page *start, struct page *end,
++ int zone, unsigned long start_paddr, int highmem)
++{
++ struct page *page;
++
++ for (page = start; page < end; page++) {
++ set_page_zone(page, zone);
++ set_page_count(page, 0);
++ SetPageReserved(page);
++ INIT_LIST_HEAD(&page->list);
++ if (!highmem)
++ set_page_address(page, __va(start_paddr));
++ start_paddr += PAGE_SIZE;
++ }
++ return start_paddr;
++}
++
++#ifdef HAVE_ARCH_MEMMAP_INIT
++#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
++ arch_memmap_init(memmap_init, start, end, zone, paddr, highmem)
++#else
++#define MEMMAP_INIT(start, end, zone, paddr, highmem) \
++ memmap_init(start, end, zone, paddr, highmem)
++#endif
++
+ #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
+ /*
+@@ -771,10 +826,8 @@
+ BUG();
+
+ totalpages = 0;
+- for (i = 0; i < MAX_NR_ZONES; i++) {
+- unsigned long size = zones_size[i];
+- totalpages += size;
+- }
++ for (i = 0; i < MAX_NR_ZONES; i++)
++ totalpages += zones_size[i];
+ realtotalpages = totalpages;
+ if (zholes_size)
+ for (i = 0; i < MAX_NR_ZONES; i++)
+@@ -783,7 +836,7 @@
+ printk("On node %d totalpages: %lu\n", nid, realtotalpages);
+
+ /*
+- * Some architectures (with lots of mem and discontinous memory
++ * Some architectures (with lots of mem and discontigous memory
+ * maps) have to search for a good mem_map area:
+ * For discontigmem, the conceptual mem map array starts from
+ * PAGE_OFFSET, we need to align the actual array onto a mem map
+@@ -796,7 +849,7 @@
+ MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
+ }
+ *gmap = pgdat->node_mem_map = lmem_map;
+- pgdat->node_size = totalpages;
++ pgdat->node_size = 0;
+ pgdat->node_start_paddr = zone_start_paddr;
+ pgdat->node_start_mapnr = (lmem_map - mem_map);
+ pgdat->nr_zones = 0;
+@@ -813,7 +866,7 @@
+ if (zholes_size)
+ realsize -= zholes_size[j];
+
+- printk("zone(%lu): %lu pages.\n", j, size);
++ printk("zone(%lu): %lu pages.\n", j, realsize);
+ zone->size = size;
+ zone->realsize = realsize;
+ zone->name = zone_names[j];
+@@ -824,6 +877,7 @@
+ zone->nr_active_pages = zone->nr_inactive_pages = 0;
+
+
++ pgdat->node_size += realsize;
+ if (!size)
+ continue;
+
+@@ -884,16 +938,10 @@
+ * up by free_all_bootmem() once the early boot process is
+ * done. Non-atomic initialization, single-pass.
+ */
+- for (i = 0; i < size; i++) {
+- struct page *page = mem_map + offset + i;
+- set_page_zone(page, nid * MAX_NR_ZONES + j);
+- set_page_count(page, 0);
+- SetPageReserved(page);
+- INIT_LIST_HEAD(&page->list);
+- if (j != ZONE_HIGHMEM)
+- set_page_address(page, __va(zone_start_paddr));
+- zone_start_paddr += PAGE_SIZE;
+- }
++ zone_start_paddr = MEMMAP_INIT(mem_map + offset,
++ mem_map + offset + size,
++ nid * MAX_NR_ZONES + j, zone_start_paddr,
++ (j == ZONE_HIGHMEM ? 1 : 0));
+
+ offset += size;
+ for (i = 0; ; i++) {
+@@ -934,7 +982,6 @@
+ (unsigned long *) alloc_bootmem_node(pgdat, bitmap_size);
+ }
+ }
+- build_zonelists(pgdat);
+ }
+
+ void __init free_area_init(unsigned long *zones_size)
Deleted: trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/nodebug.patch
===================================================================
--- trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/nodebug.patch 2005-03-14 20:21:07 UTC (rev 2714)
+++ trunk/kernel-2.4/ia64/kernel-patch-2.4.27-ia64-2.4.27/nodebug.patch 2005-03-14 23:03:51 UTC (rev 2715)
@@ -1,10 +0,0 @@
---- kernel-source-2.4.27/Makefile~ 2004-08-15 12:04:52.000000000 -0600
-+++ kernel-source-2.4.27/Makefile 2004-08-15 16:31:34.000000000 -0600
-@@ -100,7 +100,6 @@
-
- CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs $(optimize) \
- -fno-strict-aliasing -fno-common
--CFLAGS += -g
- ifndef CONFIG_FRAME_POINTER
- CFLAGS += -fomit-frame-pointer
- endif