Merge master.kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6
diff --git a/Documentation/filesystems/inotify.txt b/Documentation/filesystems/inotify.txt
index 2c71604..6d50190 100644
--- a/Documentation/filesystems/inotify.txt
+++ b/Documentation/filesystems/inotify.txt
@@ -1,18 +1,22 @@
-				    inotify
-	     a powerful yet simple file change notification system
+				   inotify
+	    a powerful yet simple file change notification system
 
 
 
 Document started 15 Mar 2005 by Robert Love <rml@novell.com>
 
+
 (i) User Interface
 
-Inotify is controlled by a set of three sys calls 
+Inotify is controlled by a set of three system calls and normal file I/O on a
+returned file descriptor.
 
-First step in using inotify is to initialise an inotify instance
+First step in using inotify is to initialise an inotify instance:
 
 	int fd = inotify_init ();
 
+Each instance is associated with a unique, ordered queue.
+
 Change events are managed by "watches".  A watch is an (object,mask) pair where
 the object is a file or directory and the mask is a bit mask of one or more
 inotify events that the application wishes to receive.  See <linux/inotify.h>
@@ -22,43 +26,52 @@
 
 Watches on a directory will return events on any files inside of the directory.
 
-Adding a watch is simple,
+Adding a watch is simple:
 
 	int wd = inotify_add_watch (fd, path, mask);
 
-You can add a large number of files via something like
-
-	for each file to watch {
-		int wd = inotify_add_watch (fd, file, mask);
-	}
+Where "fd" is the return value from inotify_init(), path is the path to the
+object to watch, and mask is the watch mask (see <linux/inotify.h>).
 
 You can update an existing watch in the same manner, by passing in a new mask.
 
-An existing watch is removed via the INOTIFY_IGNORE ioctl, for example
+An existing watch is removed via
 
-	inotify_rm_watch (fd, wd);
+	int ret = inotify_rm_watch (fd, wd);
 
 Events are provided in the form of an inotify_event structure that is read(2)
-from a inotify instance fd.  The filename is of dynamic length and follows the 
-struct. It is of size len.  The filename is padded with null bytes to ensure 
-proper alignment.  This padding is reflected in len.
+from a given inotify instance.  The filename is of dynamic length and follows
+the struct. It is of size len.  The filename is padded with null bytes to
+ensure proper alignment.  This padding is reflected in len.
 
 You can slurp multiple events by passing a large buffer, for example
 
 	size_t len = read (fd, buf, BUF_LEN);
 
-Will return as many events as are available and fit in BUF_LEN.
+Where "buf" is a pointer to an array of "inotify_event" structures at least
+BUF_LEN bytes in size.  The above example will return as many events as are
+available and fit in BUF_LEN.
 
-each inotify instance fd is also select()- and poll()-able.
+Each inotify instance fd is also select()- and poll()-able.
 
-You can find the size of the current event queue via the FIONREAD ioctl.
+You can find the size of the current event queue via the standard FIONREAD
+ioctl on the fd returned by inotify_init().
 
 All watches are destroyed and cleaned up on close.
 
 
-(ii) Internal Kernel Implementation
+(ii)
 
-Each open inotify instance is associated with an inotify_device structure.
+Prototypes:
+
+	int inotify_init (void);
+	int inotify_add_watch (int fd, const char *path, __u32 mask);
+	int inotify_rm_watch (int fd, __u32 mask);
+
+
+(iii) Internal Kernel Implementation
+
+Each inotify instance is associated with an inotify_device structure.
 
 Each watch is associated with an inotify_watch structure.  Watches are chained
 off of each associated device and each associated inode.
@@ -66,7 +79,7 @@
 See fs/inotify.c for the locking and lifetime rules.
 
 
-(iii) Rationale
+(iv) Rationale
 
 Q: What is the design decision behind not tying the watch to the open fd of
    the watched object?
@@ -75,9 +88,9 @@
    This solves the primary problem with dnotify: keeping the file open pins
    the file and thus, worse, pins the mount.  Dnotify is therefore infeasible
    for use on a desktop system with removable media as the media cannot be
-   unmounted.
+   unmounted.  Watching a file should not require that it be open.
 
-Q: What is the design decision behind using an-fd-per-device as opposed to
+Q: What is the design decision behind using an-fd-per-instance as opposed to
    an fd-per-watch?
 
 A: An fd-per-watch quickly consumes more file descriptors than are allowed,
@@ -86,8 +99,8 @@
    can use epoll, but requiring both is a silly and extraneous requirement.
    A watch consumes less memory than an open file, separating the number
    spaces is thus sensible.  The current design is what user-space developers
-   want: Users initialize inotify, once, and add n watches, requiring but one fd
-   and no twiddling with fd limits.  Initializing an inotify instance two
+   want: Users initialize inotify, once, and add n watches, requiring but one
+   fd and no twiddling with fd limits.  Initializing an inotify instance two
    thousand times is silly.  If we can implement user-space's preferences 
    cleanly--and we can, the idr layer makes stuff like this trivial--then we 
    should.
@@ -111,9 +124,6 @@
      example, love it.  Trust me, I asked.  It is not a surprise: Who'd want
      to manage and block on 1000 fd's via select?
 
-   - You'd have to manage the fd's, as an example: Call close() when you
-     received a delete event.
-
    - No way to get out of band data.
 
    - 1024 is still too low.  ;-)
@@ -122,6 +132,11 @@
    scales to 1000s of directories, juggling 1000s of fd's just does not seem
    the right interface.  It is too heavy.
 
+   Additionally, it _is_ possible to  more than one instance  and
+   juggle more than one queue and thus more than one associated fd.  There
+   need not be a one-fd-per-process mapping; it is one-fd-per-queue and a
+   process can easily want more than one queue.
+
 Q: Why the system call approach?
 
 A: The poor user-space interface is the second biggest problem with dnotify.
@@ -131,8 +146,6 @@
    Obtaining the fd and managing the watches could have been done either via a
    device file or a family of new system calls.  We decided to implement a
    family of system calls because that is the preffered approach for new kernel
-   features and it means our user interface requirements.
-
-   Additionally, it _is_ possible to  more than one instance  and
-   juggle more than one queue and thus more than one associated fd.
+   interfaces.  The only real difference was whether we wanted to use open(2)
+   and ioctl(2) or a couple of new system calls.  System calls beat ioctls.
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 5d01472..48aa6d3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1169,6 +1169,12 @@
 L:	linux-joystick@atrey.karlin.mff.cuni.cz
 S:	Maintained
 
+INOTIFY
+P:	John McCutchan and Robert Love
+M:	ttb@tentacle.dhs.org and rml@novell.com
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 INTEL 810/815 FRAMEBUFFER DRIVER
 P:      Antonino Daplas
 M:      adaplas@pol.net
@@ -2420,6 +2426,12 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USB OPTION-CARD DRIVER
+P:	Matthias Urlichs
+M:	smurf@smurf.noris.de
+L:	linux-usb-devel@lists.sourceforge.net
+S:	Maintained
+
 USB OV511 DRIVER
 P:	Mark McClelland
 M:	mmcclell@bigfoot.com
diff --git a/arch/i386/mach-visws/reboot.c b/arch/i386/mach-visws/reboot.c
index 3a81e90..95e4676 100644
--- a/arch/i386/mach-visws/reboot.c
+++ b/arch/i386/mach-visws/reboot.c
@@ -7,6 +7,7 @@
 #include "piix4.h"
 
 void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
 
 void machine_restart(char * __unused)
 {
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 2e08942..cbb3e0c 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -220,13 +220,6 @@
 	depends on !IA64_HP_SIM
 	default y
 
-config IA64_SGI_SN_SIM
-	bool "SGI Medusa Simulator Support"
-	depends on IA64_SGI_SN2 || IA64_GENERIC
-	help
-	  If you are compiling a kernel that will run under SGI's IA-64
-	  simulator (Medusa) then say Y, otherwise say N.
-
 config IA64_SGI_SN_XP
 	tristate "Support communication between SGI SSIs"
 	select IA64_UNCACHED_ALLOCATOR
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index c056139..04d0b00 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -81,7 +81,6 @@
 CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
 # CONFIG_IA64_CYCLONE is not set
 CONFIG_IOSAPIC=y
-CONFIG_IA64_SGI_SN_SIM=y
 CONFIG_FORCE_MAX_ZONEORDER=18
 CONFIG_SMP=y
 CONFIG_NR_CPUS=512
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 5c7c957..84f89da 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -20,6 +20,7 @@
  * 02/01/00 R.Seth	fixed get_cpuinfo for SMP
  * 01/07/99 S.Eranian	added the support for command line argument
  * 06/24/99 W.Drummond	added boot_cpu_data.
+ * 05/28/05 Z. Menyhart	Dynamic stride size for "flush_icache_range()"
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -85,6 +86,13 @@
 unsigned int num_io_spaces;
 
 /*
+ * "flush_icache_range()" needs to know what processor dependent stride size to use
+ * when it makes i-cache(s) coherent with d-caches.
+ */
+#define	I_CACHE_STRIDE_SHIFT	5	/* Safest way to go: 32 bytes by 32 bytes */
+unsigned long ia64_i_cache_stride_shift = ~0;
+
+/*
  * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
  * mask specifies a mask of address bits that must be 0 in order for two buffers to be
  * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
@@ -628,6 +636,12 @@
 	/* start_kernel() requires this... */
 }
 
+/*
+ * Calculate the max. cache line size.
+ *
+ * In addition, the minimum of the i-cache stride sizes is calculated for
+ * "flush_icache_range()".
+ */
 static void
 get_max_cacheline_size (void)
 {
@@ -641,6 +655,8 @@
                 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",
                        __FUNCTION__, status);
                 max = SMP_CACHE_BYTES;
+		/* Safest setup for "flush_icache_range()" */
+		ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;
 		goto out;
         }
 
@@ -649,14 +665,31 @@
 						    &cci);
 		if (status != 0) {
 			printk(KERN_ERR
-			       "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",
+			       "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",
 			       __FUNCTION__, l, status);
 			max = SMP_CACHE_BYTES;
+			/* The safest setup for "flush_icache_range()" */
+			cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+			cci.pcci_unified = 1;
 		}
 		line_size = 1 << cci.pcci_line_size;
 		if (line_size > max)
 			max = line_size;
-        }
+		if (!cci.pcci_unified) {
+			status = ia64_pal_cache_config_info(l,
+						    /* cache_type (instruction)= */ 1,
+						    &cci);
+			if (status != 0) {
+				printk(KERN_ERR
+				"%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",
+					__FUNCTION__, l, status);
+				/* The safest setup for "flush_icache_range()" */
+				cci.pcci_stride = I_CACHE_STRIDE_SHIFT;
+			}
+		}
+		if (cci.pcci_stride < ia64_i_cache_stride_shift)
+			ia64_i_cache_stride_shift = cci.pcci_stride;
+	}
   out:
 	if (max > ia64_max_cacheline_size)
 		ia64_max_cacheline_size = max;
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c
index d8030f3..92ff46a 100644
--- a/arch/ia64/kernel/topology.c
+++ b/arch/ia64/kernel/topology.c
@@ -36,12 +36,14 @@
 	parent = &sysfs_nodes[cpu_to_node(num)];
 #endif /* CONFIG_NUMA */
 
+#ifdef CONFIG_ACPI_BOOT
 	/*
 	 * If CPEI cannot be re-targetted, and this is
 	 * CPEI target, then dont create the control file
 	 */
 	if (!can_cpei_retarget() && is_cpu_cpei_target(num))
 		sysfs_cpus[num].cpu.no_control = 1;
+#endif
 
 	return register_cpu(&sysfs_cpus[num].cpu, num, parent);
 }
diff --git a/arch/ia64/lib/flush.S b/arch/ia64/lib/flush.S
index a1af914..3e2cfa2 100644
--- a/arch/ia64/lib/flush.S
+++ b/arch/ia64/lib/flush.S
@@ -3,37 +3,59 @@
  *
  * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 05/28/05 Zoltan Menyhart	Dynamic stride size
  */
+
 #include <asm/asmmacro.h>
-#include <asm/page.h>
+
 
 	/*
 	 * flush_icache_range(start,end)
-	 *	Must flush range from start to end-1 but nothing else (need to
+	 *
+	 *	Make i-cache(s) coherent with d-caches.
+	 *
+	 *	Must deal with range from start to end-1 but nothing else (need to
 	 *	be careful not to touch addresses that may be unmapped).
+	 *
+	 *	Note: "in0" and "in1" are preserved for debugging purposes.
 	 */
 GLOBAL_ENTRY(flush_icache_range)
+
 	.prologue
-	alloc r2=ar.pfs,2,0,0,0
-	sub r8=in1,in0,1
+	alloc	r2=ar.pfs,2,0,0,0
+	movl	r3=ia64_i_cache_stride_shift
+ 	mov	r21=1
 	;;
-	shr.u r8=r8,5			// we flush 32 bytes per iteration
-	.save ar.lc, r3
-	mov r3=ar.lc			// save ar.lc
+	ld8	r20=[r3]		// r20: stride shift
+	sub	r22=in1,r0,1		// last byte address
+	;;
+	shr.u	r23=in0,r20		// start / (stride size)
+	shr.u	r22=r22,r20		// (last byte address) / (stride size)
+	shl	r21=r21,r20		// r21: stride size of the i-cache(s)
+	;;
+	sub	r8=r22,r23		// number of strides - 1
+	shl	r24=r23,r20		// r24: addresses for "fc.i" =
+					//	"start" rounded down to stride boundary
+	.save	ar.lc,r3
+	mov	r3=ar.lc		// save ar.lc
 	;;
 
 	.body
-
-	mov ar.lc=r8
+	mov	ar.lc=r8
 	;;
-.Loop:	fc.i in0			// issuable on M2 only
-	add in0=32,in0
+	/*
+	 * 32 byte aligned loop, even number of (actually 2) bundles
+	 */
+.Loop:	fc.i	r24			// issuable on M0 only
+	add	r24=r21,r24		// we flush "stride size" bytes per iteration
+	nop.i	0
 	br.cloop.sptk.few .Loop
 	;;
 	sync.i
 	;;
 	srlz.i
 	;;
-	mov ar.lc=r3			// restore ar.lc
+	mov	ar.lc=r3		// restore ar.lc
 	br.ret.sptk.many rp
 END(flush_icache_range)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 720a861..54d9ed4 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -157,6 +157,7 @@
 
 	memset(controller, 0, sizeof(*controller));
 	controller->segment = seg;
+	controller->node = -1;
 	return controller;
 }
 
@@ -288,6 +289,7 @@
 	unsigned int windows = 0;
 	struct pci_bus *pbus;
 	char *name;
+	int pxm;
 
 	controller = alloc_pci_controller(domain);
 	if (!controller)
@@ -295,10 +297,16 @@
 
 	controller->acpi_handle = device->handle;
 
+	pxm = acpi_get_pxm(controller->acpi_handle);
+#ifdef CONFIG_NUMA
+	if (pxm >= 0)
+		controller->node = pxm_to_nid_map[pxm];
+#endif
+
 	acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
 			&windows);
-	controller->window = kmalloc(sizeof(*controller->window) * windows,
-			GFP_KERNEL);
+	controller->window = kmalloc_node(sizeof(*controller->window) * windows,
+			GFP_KERNEL, controller->node);
 	if (!controller->window)
 		goto out2;
 
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index a67f39e..a6649ba 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -61,7 +61,7 @@
 }
 
 static void *
-sn_default_pci_bus_fixup(struct pcibus_bussoft *soft)
+sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
 {
 	return NULL;
 }
@@ -362,7 +362,7 @@
 
 	provider_soft = NULL;
 	if (provider->bus_fixup)
-		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr);
+		provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller);
 
 	if (provider_soft == NULL)
 		return;		/* fixup failed or not applicable */
@@ -380,6 +380,22 @@
 	SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
 	    &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);
 
+	/*
+	 * If the node information we obtained during the fixup phase is invalid
+	 * then set controller->node to -1 (undetermined)
+	 */
+	if (controller->node >= num_online_nodes()) {
+		struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
+
+		printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu"
+				    "L_IO=%lx L_MEM=%lx BASE=%lx\n",
+			b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
+			b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
+		printk(KERN_WARNING "on node %d but only %d nodes online."
+			"Association set to undetermined.\n",
+			controller->node, num_online_nodes());
+		controller->node = -1;
+	}
 	return;
 
 error_return:
diff --git a/arch/ia64/sn/kernel/xpc_channel.c b/arch/ia64/sn/kernel/xpc_channel.c
index 6d02dac..94698be 100644
--- a/arch/ia64/sn/kernel/xpc_channel.c
+++ b/arch/ia64/sn/kernel/xpc_channel.c
@@ -72,7 +72,7 @@
 enum xpc_retval
 xpc_setup_infrastructure(struct xpc_partition *part)
 {
-	int ret;
+	int ret, cpuid;
 	struct timer_list *timer;
 	partid_t partid = XPC_PARTID(part);
 
@@ -223,9 +223,9 @@
 	xpc_vars_part[partid].openclose_args_pa =
 					__pa(part->local_openclose_args);
 	xpc_vars_part[partid].IPI_amo_pa = __pa(part->local_IPI_amo_va);
-	xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(smp_processor_id());
-	xpc_vars_part[partid].IPI_phys_cpuid =
-					cpu_physical_id(smp_processor_id());
+	cpuid = raw_smp_processor_id();	/* any CPU in this partition will do */
+	xpc_vars_part[partid].IPI_nasid = cpuid_to_nasid(cpuid);
+	xpc_vars_part[partid].IPI_phys_cpuid = cpu_physical_id(cpuid);
 	xpc_vars_part[partid].nchannels = part->nchannels;
 	xpc_vars_part[partid].magic = XPC_VP_MAGIC1;
 
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index a2f7a88..0e4b9ad 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -79,6 +79,7 @@
 {
 	void *cpuaddr;
 	unsigned long phys_addr;
+	int node;
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
 
@@ -86,10 +87,19 @@
 
 	/*
 	 * Allocate the memory.
-	 * FIXME: We should be doing alloc_pages_node for the node closest
-	 *        to the PCI device.
 	 */
-	if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+	node = pcibus_to_node(pdev->bus);
+	if (likely(node >=0)) {
+		struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
+
+		if (likely(p))
+			cpuaddr = page_address(p);
+		else
+			return NULL;
+	} else
+		cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
+
+	if (unlikely(!cpuaddr))
 		return NULL;
 
 	memset(cpuaddr, 0x0, size);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 9813da5..b95e928 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -85,7 +85,7 @@
 }
 
 void *
-pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 {
 	int nasid, cnode, j;
 	struct hubdev_info *hubdev_info;
@@ -158,6 +158,14 @@
 	memset(soft->pbi_int_ate_resource.ate, 0,
  	       (soft->pbi_int_ate_size * sizeof(uint64_t)));
 
+	if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP)
+		/*
+		 * TIO PCI Bridge with no closest node information.
+		 * FIXME: Find another way to determine the closest node
+		 */
+		controller->node = -1;
+	else
+		controller->node = cnode;
 	return soft;
 }
 
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 51cc4e6..5d76a75 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -581,7 +581,7 @@
  * the caller.
  */
 static void *
-tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
+tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
 {
 	struct tioca_common *tioca_common;
 	struct tioca_kernel *tioca_kern;
@@ -646,6 +646,8 @@
 		       __FUNCTION__, SGI_TIOCA_ERROR,
 		       (int)tioca_common->ca_common.bs_persist_busnum);
 
+	/* Setup locality information */
+	controller->node = tioca_kern->ca_closest_node;
 	return tioca_common;
 }
 
diff --git a/arch/um/Kconfig_net b/arch/um/Kconfig_net
index 1c2f9a7..fa2ab2d 100644
--- a/arch/um/Kconfig_net
+++ b/arch/um/Kconfig_net
@@ -135,7 +135,7 @@
 
 config UML_NET_PCAP
 	bool "pcap transport"
-	depends on UML_NET && BROKEN
+	depends on UML_NET && EXPERIMENTAL
 	help
 	The pcap transport makes a pcap packet stream on the host look
 	like an ethernet device inside UML.  This is useful for making 
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 4a375bb..eb4ac40 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -51,25 +51,26 @@
 endif
 SYS_DIR		:= $(ARCH_DIR)/include/sysdep-$(SUBARCH)
 
-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+# -Dvmap=kernel_vmap affects everything, and prevents anything from
+# referencing the libpcap.o symbol so named.
 
-core-y += $(SUBARCH_CORE)
-libs-y += $(SUBARCH_LIBS)
+CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
+	$(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap
+
+USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
+	$(MODE_INCLUDE)
 
 # -Derrno=kernel_errno - This turns all kernel references to errno into
 # kernel_errno to separate them from the libc errno.  This allows -fno-common
 # in CFLAGS.  Otherwise, it would cause ld to complain about the two different
 # errnos.
 
-CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
-	$(ARCH_INCLUDE) $(MODE_INCLUDE)
-
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
-	$(MODE_INCLUDE) $(ARCH_USER_CFLAGS)
 CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask
 CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+
 #This will adjust *FLAGS accordingly to the platform.
 include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
 
@@ -116,18 +117,19 @@
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
 
 ifndef START
-  START = $$(($(TOP_ADDR) - $(SIZE)))
+  START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
 endif
 
-CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
+CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \
 	-DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
-	-DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
-	-DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH))
+	-DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
+	-DKERNEL_STACK_SIZE=$(STACK_SIZE) \
+	-DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o
 
 #The wrappers will select whether using "malloc" or the kernel allocator.
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
-CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS)
+CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
 define cmd_vmlinux__
 	$(CC) $(CFLAGS_vmlinux) -o $@ \
 	-Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 3010590..93d0818 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,4 +1,4 @@
-SUBARCH_CORE := arch/um/sys-i386/ arch/i386/crypto/
+core-y += arch/um/sys-i386/ arch/i386/crypto/
 
 TOP_ADDR := $(CONFIG_TOP_ADDR)
 
@@ -8,21 +8,32 @@
   endif
 endif
 
+LDFLAGS			+= -m elf_i386
+ELF_ARCH		:= $(SUBARCH)
+ELF_FORMAT 		:= elf32-$(SUBARCH)
+OBJCOPYFLAGS  		:= -O binary -R .note -R .comment -S
+
+ifeq ("$(origin SUBARCH)", "command line")
+ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
+CFLAGS			+= $(call cc-option,-m32)
+USER_CFLAGS		+= $(call cc-option,-m32)
+HOSTCFLAGS		+= $(call cc-option,-m32)
+HOSTLDFLAGS		+= $(call cc-option,-m32)
+AFLAGS			+= $(call cc-option,-m32)
+LINK-y			+= $(call cc-option,-m32)
+UML_OBJCOPYFLAGS	+= -F $(ELF_FORMAT)
+
+export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
+endif
+endif
+
 CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) $(STUB_CFLAGS)
-ARCH_USER_CFLAGS :=
 
 ifneq ($(CONFIG_GPROF),y)
 ARCH_CFLAGS += -DUM_FASTCALL
 endif
 
-ELF_ARCH := $(SUBARCH)
-ELF_FORMAT := elf32-$(SUBARCH)
-
-OBJCOPYFLAGS  := -O binary -R .note -R .comment -S
-
-SYS_UTIL_DIR	:= $(ARCH_DIR)/sys-i386/util
-
-SYS_HEADERS := $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+SYS_HEADERS	:= $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
 
 prepare: $(SYS_HEADERS)
 
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index d80bd00..aa2f717 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,11 +1,13 @@
 # Copyright 2003 - 2004 Pathscale, Inc
 # Released under the GPL
 
-SUBARCH_LIBS := arch/um/sys-x86_64/
+libs-y += arch/um/sys-x86_64/
 START := 0x60000000
 
+#We #undef __x86_64__ for kernelspace, not for userspace where
+#it's needed for headers to work!
 CFLAGS += -U__$(SUBARCH)__ -fno-builtin $(STUB_CFLAGS)
-ARCH_USER_CFLAGS := -D__x86_64__
+USER_CFLAGS += -fno-builtin
 
 ELF_ARCH := i386:x86-64
 ELF_FORMAT := elf64-x86-64
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index b2de991..d6c31a9 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -10,7 +10,6 @@
 slirp-objs := slirp_kern.o slirp_user.o
 daemon-objs := daemon_kern.o daemon_user.o
 mcast-objs := mcast_kern.o mcast_user.o
-#pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
 hostaudio-objs := hostaudio_kern.o
@@ -18,6 +17,17 @@
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
 
+LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
+
+$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
+	$(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
+#XXX: The call below does not work because the flags are added before the
+# object name, so nothing from the library gets linked.
+#$(call if_changed,ld)
+
+# When the above is fixed, don't forget to add this too!
+#targets := $(obj)/pcap.o
+
 obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
 obj-$(CONFIG_SSL) += ssl.o
 obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
@@ -26,7 +36,7 @@
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
-#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
+obj-$(CONFIG_UML_NET_PCAP) += pcap.o
 obj-$(CONFIG_UML_NET) += net.o 
 obj-$(CONFIG_MCONSOLE) += mconsole.o
 obj-$(CONFIG_MMAPPER) += mmapper_kern.o 
@@ -41,6 +51,7 @@
 obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
 obj-$(CONFIG_UML_RANDOM) += random.o
 
-USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
+# pcap_user.o must be added explicitly.
+USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o
 
 include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 163476a..b03326d 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -16,8 +16,8 @@
   __binary_start = .;
 
 #ifdef MODE_TT
-  .remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) }
-  .remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) }
+  .remap_data : { UNMAP_PATH (.data .bss) }
+  .remap : { UNMAP_PATH (.text) }
 
   . = ALIGN(4096);		/* Init code and data */
 #endif
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
index 37a8f97..802d027 100644
--- a/arch/um/scripts/Makefile.unmap
+++ b/arch/um/scripts/Makefile.unmap
@@ -12,8 +12,8 @@
 
 quiet_cmd_wrapld = LD      $@
 define cmd_wrapld
-	$(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \
-	$(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
+	$(LD) $(LDFLAGS) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) $(CFLAGS) -print-file-name=libc.a); \
+	$(OBJCOPY) $(UML_OBJCOPYFLAGS) $(obj)/unmap_tmp.o $@ -G switcheroo
 endef
 
 $(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index dc755b0..bd3c34a 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -4,96 +4,106 @@
  */
 
 #include "linux/config.h"
+#include "linux/sched.h"
 #include "linux/slab.h"
+#include "linux/types.h"
 #include "asm/uaccess.h"
 #include "asm/ptrace.h"
+#include "asm/smp.h"
+#include "asm/ldt.h"
 #include "choose-mode.h"
 #include "kern.h"
+#include "mode_kern.h"
 
 #ifdef CONFIG_MODE_TT
+
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
-/* XXX this needs copy_to_user and copy_from_user */
-
-int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
+static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
 {
-	if (!access_ok(VERIFY_READ, ptr, bytecount))
-		return -EFAULT;
-
 	return modify_ldt(func, ptr, bytecount);
 }
+
 #endif
 
 #ifdef CONFIG_MODE_SKAS
-extern int userspace_pid[];
 
+#include "skas.h"
 #include "skas_ptrace.h"
 
-int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
+static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
 {
 	struct ptrace_ldt ldt;
-	void *buf;
-	int res, n;
+	u32 cpu;
+	int res;
 
-	buf = kmalloc(bytecount, GFP_KERNEL);
-	if(buf == NULL)
-		return(-ENOMEM);
+	ldt = ((struct ptrace_ldt) { .func	= func,
+				     .ptr	= ptr,
+				     .bytecount = bytecount });
 
-	res = 0;
+	cpu = get_cpu();
+	res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);
+	put_cpu();
+
+	return res;
+}
+#endif
+
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
+{
+	struct user_desc info;
+	int res = 0;
+	void *buf = NULL;
+	void *p = NULL; /* What we pass to host. */
 
 	switch(func){
 	case 1:
-	case 0x11:
-		res = copy_from_user(buf, ptr, bytecount);
-		break;
-	}
+	case 0x11: /* write_ldt */
+		/* Do this check now to avoid overflows. */
+		if (bytecount != sizeof(struct user_desc)) {
+			res = -EINVAL;
+			goto out;
+		}
 
-	if(res != 0){
-		res = -EFAULT;
+		if(copy_from_user(&info, ptr, sizeof(info))) {
+			res = -EFAULT;
+			goto out;
+		}
+
+		p = &info;
+		break;
+	case 0:
+	case 2: /* read_ldt */
+
+		/* The use of info avoids kmalloc on the write case, not on the
+		 * read one. */
+		buf = kmalloc(bytecount, GFP_KERNEL);
+		if (!buf) {
+			res = -ENOMEM;
+			goto out;
+		}
+		p = buf;
+	default:
+		res = -ENOSYS;
 		goto out;
 	}
 
-	ldt = ((struct ptrace_ldt) { .func	= func,
-				     .ptr	= buf,
-				     .bytecount = bytecount });
-#warning Need to look up userspace_pid by cpu
-	res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);
+	res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,
+				p, bytecount);
 	if(res < 0)
 		goto out;
 
 	switch(func){
 	case 0:
 	case 2:
-		n = res;
-		res = copy_to_user(ptr, buf, n);
-		if(res != 0)
+		/* Modify_ldt was for reading and returned the number of read
+		 * bytes.*/
+		if(copy_to_user(ptr, p, res))
 			res = -EFAULT;
-		else 
-			res = n;
 		break;
 	}
 
- out:
+out:
 	kfree(buf);
-	return(res);
+	return res;
 }
-#endif
-
-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
-{
-	return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 
-				ptr, bytecount));
-}
-
-
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 1368752..1b0ad0e 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -15,7 +15,7 @@
 	if(munmap(to, size) < 0){
 		return(-1);
 	}
-	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
+	if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
 		return(-1);
 	}
 	if(munmap(from, size) < 0){
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index 73a7926..8fdaed0 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -168,7 +168,7 @@
 
 	frame = (struct rt_sigframe __user *)
 		round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
-	((unsigned char *) frame) -= 128;
+        frame = (struct rt_sigframe *) ((unsigned long) frame - 128);
 
 	if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
 		goto out;
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index bc7094c..f4a4bff 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -15,7 +15,7 @@
 	if(munmap(to, size) < 0){
 		return(-1);
 	}
-	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
+	if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
 		return(-1);
 	}
 	if(munmap(from, size) < 0){
diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c
index 01d8db1..816a3b8 100644
--- a/arch/x86_64/ia32/syscall32.c
+++ b/arch/x86_64/ia32/syscall32.c
@@ -57,6 +57,7 @@
 	int npages = (VSYSCALL32_END - VSYSCALL32_BASE) >> PAGE_SHIFT;
 	struct vm_area_struct *vma;
 	struct mm_struct *mm = current->mm;
+	int ret;
 
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!vma)
@@ -78,7 +79,11 @@
 	vma->vm_mm = mm;
 
 	down_write(&mm->mmap_sem);
-	insert_vm_struct(mm, vma);
+	if ((ret = insert_vm_struct(mm, vma))) {
+		up_write(&mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, vma);
+		return ret;
+	}
 	mm->total_vm += npages;
 	up_write(&mm->mmap_sem);
 	return 0;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index f463d6b..5b1d368 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -355,7 +355,7 @@
 		ToRecv = space;
 
 	if (ToRecv <= 0)
-		return;
+		goto done;
 
 	/*
 	 * if status indicates there are errored characters in the
@@ -437,6 +437,7 @@
 	}
 	/*  Push the data up to the tty layer */
 	ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
+done:
 	tty_ldisc_deref(ld);
 }
 
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index d7aa7a2..30d9673 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -2796,7 +2796,7 @@
 		return;
 
 	if (vesa_off_interval) {
-		blank_state = blank_vesa_wait,
+		blank_state = blank_vesa_wait;
 		mod_timer(&console_timer, jiffies + vesa_off_interval);
 	}
 
diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h
index e72cc47..ce910d6 100644
--- a/drivers/firmware/pcdp.h
+++ b/drivers/firmware/pcdp.h
@@ -52,6 +52,8 @@
 	u32				clock_rate;
 	u8				pci_prog_intfc;
 	u8				flags;
+	u16				conout_index;
+	u32				reserved;
 } __attribute__((packed));
 
 #define PCDP_IF_PCI	1
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index a485f47..b12a970 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -1084,7 +1084,8 @@
 
 			initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1);
 
-			PRINT(KERN_ERR, "IR legacy activated");
+			if (printk_ratelimit())
+				PRINT(KERN_ERR, "IR legacy activated");
 		}
 
                 spin_lock_irqsave(&ohci->IR_channel_lock, flags);
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 95980ad..0c2ed99 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1345,7 +1345,8 @@
 	}
 }
 
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+			int degraded)
 {
 	bitmap_counter_t *bmc;
 	int rv;
@@ -1362,8 +1363,10 @@
 			rv = 1;
 		else if (NEEDED(*bmc)) {
 			rv = 1;
-			*bmc |= RESYNC_MASK;
-			*bmc &= ~NEEDED_MASK;
+			if (!degraded) { /* don't set/clear bits if degraded */
+				*bmc |= RESYNC_MASK;
+				*bmc &= ~NEEDED_MASK;
+			}
 		}
 	}
 	spin_unlock_irq(&bitmap->lock);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index e11dd14..2120710 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -314,16 +314,16 @@
 		sector_t space = conf->hash_spacing;
 		int round;
 		conf->preshift = 0;
-		if (sizeof(sector_t) > sizeof(unsigned long)) {
+		if (sizeof(sector_t) > sizeof(u32)) {
 			/*shift down space and s so that sector_div will work */
-			while (space > (sector_t) (~(unsigned long)0)) {
+			while (space > (sector_t) (~(u32)0)) {
 				s >>= 1;
 				space >>= 1;
 				s += 1; /* force round-up */
 				conf->preshift++;
 			}
 		}
-		round = sector_div(s, (unsigned long)space) ? 1 : 0;
+		round = sector_div(s, (u32)space) ? 1 : 0;
 		nb_zone = s + round;
 	}
 	printk("raid0 : nb_zone is %d.\n", nb_zone);
@@ -443,7 +443,7 @@
 		volatile
 #endif
 		sector_t x = block >> conf->preshift;
-		sector_div(x, (unsigned long)conf->hash_spacing);
+		sector_div(x, (u32)conf->hash_spacing);
 		zone = conf->hash_table[x];
 	}
  
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index ff1dbec..5f253ee 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1126,21 +1126,19 @@
 		 * only be one in raid1 resync.
 		 * We can find the current addess in mddev->curr_resync
 		 */
-		if (!conf->fullsync) {
-			if (mddev->curr_resync < max_sector)
-				bitmap_end_sync(mddev->bitmap,
-						mddev->curr_resync,
+		if (mddev->curr_resync < max_sector) /* aborted */
+			bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
 						&sync_blocks, 1);
-			bitmap_close_sync(mddev->bitmap);
-		}
-		if (mddev->curr_resync >= max_sector)
+		else /* completed sync */
 			conf->fullsync = 0;
+
+		bitmap_close_sync(mddev->bitmap);
 		close_sync(conf);
 		return 0;
 	}
 
-	if (!conf->fullsync &&
-	    !bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {
+	if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) &&
+	    !conf->fullsync) {
 		/* We can skip this block, and probably several more */
 		*skipped = 1;
 		return sync_blocks;
@@ -1243,15 +1241,15 @@
 			len = (max_sector - sector_nr) << 9;
 		if (len == 0)
 			break;
-		if (!conf->fullsync) {
-			if (sync_blocks == 0) {
-				if (!bitmap_start_sync(mddev->bitmap,
-						       sector_nr, &sync_blocks))
-					break;
-				if (sync_blocks < (PAGE_SIZE>>9))
-					BUG();
-				if (len > (sync_blocks<<9)) len = sync_blocks<<9;
-			}
+		if (sync_blocks == 0) {
+			if (!bitmap_start_sync(mddev->bitmap, sector_nr,
+					&sync_blocks, mddev->degraded) &&
+					!conf->fullsync)
+				break;
+			if (sync_blocks < (PAGE_SIZE>>9))
+				BUG();
+			if (len > (sync_blocks<<9))
+				len = sync_blocks<<9;
 		}
 
 		for (i=0 ; i < conf->raid_disks; i++) {
@@ -1264,7 +1262,8 @@
 					while (i > 0) {
 						i--;
 						bio = r1_bio->bios[i];
-						if (bio->bi_end_io==NULL) continue;
+						if (bio->bi_end_io==NULL)
+							continue;
 						/* remove last page from this bio */
 						bio->bi_vcnt--;
 						bio->bi_size -= len;
diff --git a/drivers/media/dvb/frontends/lgdt3302.c b/drivers/media/dvb/frontends/lgdt3302.c
index 2eea03d..c85a2a9 100644
--- a/drivers/media/dvb/frontends/lgdt3302.c
+++ b/drivers/media/dvb/frontends/lgdt3302.c
@@ -217,13 +217,11 @@
 	static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };
 	static u8 agc_rf_cfg[]     = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };
 	static u8 agc_ctrl_cfg[]   = { AGC_FUNC_CTRL2, 0xc6, 0x40 };
-	static u8 agc_delay_cfg[]  = { AGC_DELAY0, 0x00, 0x00, 0x00 };
+	static u8 agc_delay_cfg[]  = { AGC_DELAY0, 0x07, 0x00, 0xfe };
 	static u8 agc_loop_cfg[]   = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };
 
 	/* Change only if we are actually changing the modulation */
 	if (state->current_modulation != param->u.vsb.modulation) {
-		int value;
-
 		switch(param->u.vsb.modulation) {
 		case VSB_8:
 			dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
@@ -276,16 +274,8 @@
 		   recovery center frequency register */
 		i2c_writebytes(state, state->config->demod_address,
 				       vsb_freq_cfg, sizeof(vsb_freq_cfg));
-		/* Set the value of 'INLVTHD' register 0x2a/0x2c
-		   to value from 'IFACC' register 0x39/0x3b -1 */
-		i2c_selectreadbytes(state, AGC_RFIF_ACC0,
-				    &agc_delay_cfg[1], 3);
-		value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];
-		value = value -1;
-		dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);
-		agc_delay_cfg[1] = (value >> 8) & 0x0f;
-		agc_delay_cfg[2] = 0x00;
-		agc_delay_cfg[3] = value & 0xff;
+
+		/* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */
 		i2c_writebytes(state, state->config->demod_address,
 			       agc_delay_cfg, sizeof(agc_delay_cfg));
 
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index b0b47c3..3d0c784 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky Exp $
+ * $Id: cx88-cards.c,v 1.86 2005/07/14 03:06:43 mchehab Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * card-specific stuff.
@@ -682,9 +682,9 @@
 		.name           = "PixelView PlayTV Ultra Pro (Stereo)",
 		/* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */
 		.tuner_type     = TUNER_PHILIPS_FM1216ME_MK3,
-		.radio_type     = TUNER_TEA5767,
-		.tuner_addr	= 0xc2>>1,
-		.radio_addr	= 0xc0>>1,
+		.radio_type     = UNSET,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
 		.input          = {{
 			.type   = CX88_VMUX_TELEVISION,
 			.vmux   = 0,
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 8db68f2d..6ad1458 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-dvb.c,v 1.41 2005/07/04 19:35:05 mkrufky Exp $
+ * $Id: cx88-dvb.c,v 1.42 2005/07/12 15:44:55 mkrufky Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * MPEG Transport Stream (DVB) routines
@@ -180,12 +180,14 @@
 #if CONFIG_DVB_CX22702
 static struct cx22702_config connexant_refboard_config = {
 	.demod_address = 0x43,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
 	.pll_address   = 0x60,
 	.pll_desc      = &dvb_pll_thomson_dtt7579,
 };
 
 static struct cx22702_config hauppauge_novat_config = {
 	.demod_address = 0x43,
+	.output_mode   = CX22702_SERIAL_OUTPUT,
 	.pll_address   = 0x61,
 	.pll_desc      = &dvb_pll_thomson_dtt759x,
 };
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index c44a079..5588a3a 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88-video.c,v 1.79 2005/07/07 14:17:47 mchehab Exp $
+ * $Id: cx88-video.c,v 1.80 2005/07/13 08:49:08 mchehab Exp $
  *
  * device driver for Conexant 2388x based TV cards
  * video4linux video interface
@@ -1346,6 +1346,11 @@
 		dev->freq = f->frequency;
 		cx88_newstation(core);
 		cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f);
+
+		/* When changing channels it is required to reset TVAUDIO */
+		msleep (10);
+		cx88_set_tvaudio(core);
+
 		up(&dev->lock);
 		return 0;
 	}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 307beae..b008f7d 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,5 @@
 /*
- * $Id: cx88.h,v 1.68 2005/07/07 14:17:47 mchehab Exp $
+ * $Id: cx88.h,v 1.69 2005/07/13 17:25:25 mchehab Exp $
  *
  * v4l2 device driver for cx2388x based TV cards
  *
@@ -35,8 +35,8 @@
 #include "btcx-risc.h"
 #include "cx88-reg.h"
 
-#include <linux/version.h>
-#define CX88_VERSION_CODE KERNEL_VERSION(0,0,4)
+#include <linux/utsname.h>
+#define CX88_VERSION_CODE KERNEL_VERSION(0,0,5)
 
 #ifndef TRUE
 # define TRUE (1==1)
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c
index b53c748..4d27ac1 100644
--- a/drivers/media/video/tea5767.c
+++ b/drivers/media/video/tea5767.c
@@ -2,7 +2,7 @@
  * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
  * I2C address is allways 0xC0.
  *
- * $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $
+ * $Id: tea5767.c,v 1.21 2005/07/14 03:06:43 mchehab Exp $
  *
  * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)
  * This code is placed under the terms of the GNU General Public License
@@ -153,17 +153,17 @@
 
 	switch (TEA5767_HIGH_LO_32768) {
 	case TEA5767_HIGH_LO_13MHz:
-		frq = 1000 * (div * 50 - 700 - 225) / 4;	/* Freq in KHz */
+		frq = (div * 50000 - 700000 - 225000) / 4;	/* Freq in KHz */
 		break;
 	case TEA5767_LOW_LO_13MHz:
-		frq = 1000 * (div * 50 + 700 + 225) / 4;	/* Freq in KHz */
+		frq = (div * 50000 + 700000 + 225000) / 4;	/* Freq in KHz */
 		break;
 	case TEA5767_LOW_LO_32768:
-		frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4;	/* Freq in KHz */
+		frq = (div * 32768 + 700000 + 225000) / 4;	/* Freq in KHz */
 		break;
 	case TEA5767_HIGH_LO_32768:
 	default:
-		frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4;	/* Freq in KHz */
+		frq = (div * 32768 - 700000 - 225000) / 4;	/* Freq in KHz */
 		break;
 	}
 	buffer[0] = (div >> 8) & 0x3f;
@@ -196,7 +196,7 @@
 	unsigned div;
 	int rc;
 
-	tuner_dbg (PREFIX "radio freq counter %d\n", frq);
+	tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
 
 	/* Rounds freq to next decimal value - for 62.5 KHz step */
 	/* frq = 20*(frq/16)+radio_frq[frq%16]; */
@@ -224,19 +224,19 @@
 		tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");
 		buffer[2] |= TEA5767_HIGH_LO_INJECT;
 		buffer[4] |= TEA5767_PLLREF_ENABLE;
-		div = (frq * 4 / 16 + 700 + 225 + 25) / 50;
+		div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000;
 		break;
 	case TEA5767_LOW_LO_13MHz:
 		tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");
 
 		buffer[4] |= TEA5767_PLLREF_ENABLE;
-		div = (frq * 4 / 16 - 700 - 225 + 25) / 50;
+		div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000;
 		break;
 	case TEA5767_LOW_LO_32768:
 		tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");
 		buffer[3] |= TEA5767_XTAL_32768;
 		/* const 700=4000*175 Khz - to adjust freq to right value */
-		div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15;
+		div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15;
 		break;
 	case TEA5767_HIGH_LO_32768:
 	default:
@@ -244,17 +244,21 @@
 
 		buffer[2] |= TEA5767_HIGH_LO_INJECT;
 		buffer[3] |= TEA5767_XTAL_32768;
-		div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;
+		div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
 		break;
 	}
 	buffer[0] = (div >> 8) & 0x3f;
 	buffer[1] = div & 0xff;
 
-	if (tuner_debug)
-		tea5767_status_dump(buffer);
-
 	if (5 != (rc = i2c_master_send(c, buffer, 5)))
 		tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+
+	if (tuner_debug) {
+		if (5 != (rc = i2c_master_recv(c, buffer, 5)))
+			tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
+		else
+			tea5767_status_dump(buffer);
+	}
 }
 
 static int tea5767_signal(struct i2c_client *c)
@@ -294,7 +298,7 @@
 	struct tuner *t = i2c_get_clientdata(c);
 
 	if (5 != (rc = i2c_master_recv(c, buffer, 5))) {
-		tuner_warn("it is not a TEA5767. Received %i chars.\n", rc);
+		tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);
 		return EINVAL;
 	}
 
@@ -310,11 +314,11 @@
 	 *          bit 0   : internally set to 0
 	 *  Byte 5: bit 7:0 : == 0
 	 */
-
 	if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {
 		tuner_warn("Chip ID is not zero. It is not a TEA5767\n");
 		return EINVAL;
 	}
+
 	tuner_warn("TEA5767 detected.\n");
 	return 0;
 }
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index de19063..b25a9c0 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,5 +1,5 @@
 /*
- * $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $
+ * $Id: tuner-core.c,v 1.58 2005/07/14 03:06:43 mchehab Exp $
  *
  * i2c tv tuner chip device driver
  * core core, i.e. kernel interfaces, registering and so on
@@ -39,6 +39,9 @@
 static unsigned int addr = 0;
 module_param(addr, int, 0444);
 
+static unsigned int no_autodetect = 0;
+module_param(no_autodetect, int, 0444);
+
 /* insmod options used at runtime => read/write */
 unsigned int tuner_debug = 0;
 module_param(tuner_debug, int, 0644);
@@ -318,17 +321,19 @@
 	tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);
 
 	/* TEA5767 autodetection code - only for addr = 0xc0 */
-	if (addr == 0x60) {
-		if (tea5767_autodetection(&t->i2c) != EINVAL) {
-			t->type = TUNER_TEA5767;
-			t->mode_mask = T_RADIO;
-			t->mode = T_STANDBY;
-			t->freq = 87.5 * 16; /* Sets freq to FM range */
-			default_mode_mask &= ~T_RADIO;
+	if (!no_autodetect) {
+		if (addr == 0x60) {
+			if (tea5767_autodetection(&t->i2c) != EINVAL) {
+				t->type = TUNER_TEA5767;
+				t->mode_mask = T_RADIO;
+				t->mode = T_STANDBY;
+				t->freq = 87.5 * 16; /* Sets freq to FM range */
+				default_mode_mask &= ~T_RADIO;
 
-			i2c_attach_client (&t->i2c);
-			set_type(&t->i2c,t->type, t->mode_mask);
-			return 0;
+				i2c_attach_client (&t->i2c);
+				set_type(&t->i2c,t->type, t->mode_mask);
+				return 0;
+			}
 		}
 	}
 
@@ -631,7 +636,9 @@
 			break;
 		}
 	default:
-		tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);
+		tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n",
+					 cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),
+					_IOC_NR(cmd), _IOC_SIZE(cmd));
 		break;
 	}
 
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1bd71a5..eee5115 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -59,7 +59,7 @@
  *	The AG-AND chips have nice features for speed improvement,
  *	which are not supported yet. Read / program 4 pages in one go.
  *
- * $Id: nand_base.c,v 1.146 2005/06/17 15:02:06 gleixner Exp $
+ * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -1409,16 +1409,6 @@
 		thislen = min_t(int, thislen, len);
 		this->read_buf(mtd, &buf[i], thislen);
 		i += thislen;
-		
-		/* Apply delay or wait for ready/busy pin 
-		 * Do this before the AUTOINCR check, so no problems
-		 * arise if a chip which does auto increment
-		 * is marked as NOAUTOINCR by the board driver.
-		*/
-		if (!this->dev_ready) 
-			udelay (this->chip_delay);
-		else
-			nand_wait_ready(mtd);
 
 		/* Read more ? */
 		if (i < len) {
@@ -1432,6 +1422,16 @@
 				this->select_chip(mtd, chipnr);
 			}
 				
+			/* Apply delay or wait for ready/busy pin 
+			 * Do this before the AUTOINCR check, so no problems
+			 * arise if a chip which does auto increment
+			 * is marked as NOAUTOINCR by the board driver.
+			 */
+			if (!this->dev_ready) 
+				udelay (this->chip_delay);
+			else
+				nand_wait_ready(mtd);
+
 			/* Check, if the chip supports auto page increment 
 			 * or if we have hit a block boundary. 
 			*/ 
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 5ac2d29..7535ef5 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -6,7 +6,7 @@
  *   
  *  Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
  *
- * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $
+ * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -109,24 +109,21 @@
 /** 
  * check_short_pattern - [GENERIC] check if a pattern is in the buffer
  * @buf:	the buffer to search
- * @len:	the length of buffer to search
- * @paglen:	the pagelength
  * @td:		search pattern descriptor
  *
  * Check for a pattern at the given place. Used to search bad block
  * tables and good / bad block identifiers. Same as check_pattern, but 
- * no optional empty check and the pattern is expected to start
- * at offset 0.
+ * no optional empty check
  *
 */
-static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)
+static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
 {
 	int i;
 	uint8_t *p = buf;
 
 	/* Compare the pattern */
 	for (i = 0; i < td->len; i++) {
-		if (p[i] != td->pattern[i])
+		if (p[td->offs + i] != td->pattern[i])
 			return -1;
 	}
 	return 0;
@@ -337,13 +334,14 @@
 			if (!(bd->options & NAND_BBT_SCANEMPTY)) {
 				size_t retlen;
 				
-				/* No need to read pages fully, just read required OOB bytes */
-				ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,
-							readlen, &retlen, &buf[0]);
+				/* Read the full oob until read_oob is fixed to 
+				 * handle single byte reads for 16 bit buswidth */
+				ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
+							mtd->oobsize, &retlen, buf);
 				if (ret)
 					return ret;
 
-				if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+				if (check_short_pattern (buf, bd)) {
 					this->bbt[i >> 3] |= 0x03 << (i & 0x6);
 					printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 
 						i >> 1, (unsigned int) from);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index b722175..e925640 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -12,14 +12,25 @@
   History:
 
   2005-05-19  v0.1   Initial version, based on incomplete docs
-                     and analysis of misbehavior of the standard driver
+                     and analysis of misbehavior with the standard driver
   2005-05-20  v0.2   Extended the input buffer to avoid losing
                      random 64-byte chunks of data
   2005-05-21  v0.3   implemented chars_in_buffer()
                      turned on low_latency
                      simplified the code somewhat
+  2005-05-24  v0.4   option_write() sometimes deadlocked under heavy load
+                     removed some dead code
+                     added sponsor notice
+                     coding style clean-up
+  2005-06-20  v0.4.1 add missing braces :-/
+                     killed end-of-line whitespace
+  2005-07-15  v0.4.2 rename WLAN product to FUSION, add FUSION2
+
+  Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
+
 */
-#define DRIVER_VERSION "v0.3"
+
+#define DRIVER_VERSION "v0.4"
 #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
 #define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
 
@@ -44,7 +55,6 @@
 
 static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
 
-
 static int  option_write (struct usb_serial_port *port,
                           const unsigned char *buf, int count);
 
@@ -60,14 +70,17 @@
 static int  option_send_setup (struct usb_serial_port *port);
 
 /* Vendor and product IDs */
-#define OPTION_VENDOR_ID		0x0AF0
+#define OPTION_VENDOR_ID			0x0AF0
 
-#define	OPTION_PRODUCT_OLD		0x5000
-#define	OPTION_PRODUCT_WLAN		0x6000
+#define OPTION_PRODUCT_OLD		0x5000
+#define OPTION_PRODUCT_FUSION	0x6000
+#define OPTION_PRODUCT_FUSION2	0x6300
+
 
 static struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
-	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
+	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
 	{ } /* Terminating entry */
 };
 
@@ -85,58 +98,62 @@
  * recognizes separately, thus num_port=1.
  */
 static struct usb_serial_device_type option_3port_device = {
-	.owner			= THIS_MODULE,
-	.name			= "Option 3-port card",
-	.short_name		= "option",
-	.id_table		= option_ids,
-	.num_interrupt_in	= NUM_DONT_CARE,
-	.num_bulk_in		= NUM_DONT_CARE,
-	.num_bulk_out		= NUM_DONT_CARE,
-	.num_ports		= 1, /* 3 */
-	.open			= option_open,
-	.close			= option_close,
-	.write			= option_write,
-	.write_room		= option_write_room,
-	.chars_in_buffer	= option_chars_in_buffer,
-	.throttle		= option_rx_throttle,
-	.unthrottle		= option_rx_unthrottle,
-	.ioctl			= option_ioctl,
-	.set_termios		= option_set_termios,
-	.break_ctl		= option_break_ctl,
-	.tiocmget		= option_tiocmget,
-	.tiocmset		= option_tiocmset,
-	.attach			= option_startup,
-	.shutdown		= option_shutdown,
-	.read_int_callback	= option_instat_callback,
+	.owner             = THIS_MODULE,
+	.name              = "Option 3G data card",
+	.short_name        = "option",
+	.id_table          = option_ids,
+	.num_interrupt_in  = NUM_DONT_CARE,
+	.num_bulk_in       = NUM_DONT_CARE,
+	.num_bulk_out      = NUM_DONT_CARE,
+	.num_ports         = 1, /* 3, but the card reports its ports separately */
+	.open              = option_open,
+	.close             = option_close,
+	.write             = option_write,
+	.write_room        = option_write_room,
+	.chars_in_buffer   = option_chars_in_buffer,
+	.throttle          = option_rx_throttle,
+	.unthrottle        = option_rx_unthrottle,
+	.ioctl             = option_ioctl,
+	.set_termios       = option_set_termios,
+	.break_ctl         = option_break_ctl,
+	.tiocmget          = option_tiocmget,
+	.tiocmset          = option_tiocmset,
+	.attach            = option_startup,
+	.shutdown          = option_shutdown,
+	.read_int_callback = option_instat_callback,
 };
 
+#ifdef CONFIG_USB_DEBUG
 static int debug;
+#else
+#define debug 0
+#endif
+
 
 /* per port private data */
 
-#define N_IN_URB	4
-#define N_OUT_URB	1
-#define IN_BUFLEN	1024
-#define OUT_BUFLEN	1024
+#define N_IN_URB 4
+#define N_OUT_URB 1
+#define IN_BUFLEN 1024
+#define OUT_BUFLEN 128
 
 struct option_port_private {
 	/* Input endpoints and buffer for this port */
-	struct urb	*in_urbs[N_IN_URB];
-	char		in_buffer[N_IN_URB][IN_BUFLEN];
+	struct urb *in_urbs[N_IN_URB];
+	char in_buffer[N_IN_URB][IN_BUFLEN];
 	/* Output endpoints and buffer for this port */
-	struct urb	*out_urbs[N_OUT_URB];
-	char		out_buffer[N_OUT_URB][OUT_BUFLEN];
+	struct urb *out_urbs[N_OUT_URB];
+	char out_buffer[N_OUT_URB][OUT_BUFLEN];
 
 	/* Settings for the port */
-	int		rts_state;	/* Handshaking pins (outputs) */
-	int		dtr_state;
-	int		cts_state;	/* Handshaking pins (inputs) */
-	int		dsr_state;
-	int		dcd_state;
-	int		ri_state;
-	// int		break_on;
+	int rts_state;	/* Handshaking pins (outputs) */
+	int dtr_state;
+	int cts_state;	/* Handshaking pins (inputs) */
+	int dsr_state;
+	int dcd_state;
+	int ri_state;
 
-	unsigned long	tx_start_time[N_OUT_URB];
+	unsigned long tx_start_time[N_OUT_URB];
 };
 
 
@@ -190,13 +207,13 @@
 option_break_ctl (struct usb_serial_port *port, int break_state)
 {
 	/* Unfortunately, I don't know how to send a break */
- 	dbg("%s", __FUNCTION__);
+	dbg("%s", __FUNCTION__);
 }
 
 
 static void
 option_set_termios (struct usb_serial_port *port,
-				     struct termios *old_termios)
+                    struct termios *old_termios)
 {
 	dbg("%s", __FUNCTION__);
 
@@ -204,10 +221,10 @@
 }
 
 static int
-option_tiocmget(struct usb_serial_port *port, struct file *file)
+option_tiocmget (struct usb_serial_port *port, struct file *file)
 {
-	unsigned int			value;
-	struct option_port_private 	*portdata;
+	unsigned int value;
+	struct option_port_private *portdata;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -225,7 +242,7 @@
 option_tiocmset (struct usb_serial_port *port, struct file *file,
                  unsigned int set, unsigned int clear)
 {
-	struct option_port_private 	*portdata;
+	struct option_port_private *portdata;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -250,71 +267,50 @@
 
 /* Write */
 static int
-option_write(struct usb_serial_port *port,
-			 const unsigned char *buf, int count)
+option_write (struct usb_serial_port *port,
+			  const unsigned char *buf, int count)
 {
-	struct option_port_private 	*portdata;
-	int				i;
-	int 				left, todo;
-	struct urb			*this_urb = NULL; /* spurious */
- 	int 				err;
+	struct option_port_private *portdata;
+	int i;
+	int left, todo;
+	struct urb *this_urb = NULL; /* spurious */
+	int err;
 
 	portdata = usb_get_serial_port_data(port);
 
 	dbg("%s: write (%d chars)", __FUNCTION__, count);
 
-#if 0
-	spin_lock(&port->lock);
-	if (port->write_urb_busy) {
-		spin_unlock(&port->lock);
-		dbg("%s: already writing", __FUNCTION__);
-		return 0;
-	}
-	port->write_urb_busy = 1;
-	spin_unlock(&port->lock);
-#endif
-
 	i = 0;
 	left = count;
-	while (left>0) {
+	for (i=0; left > 0 && i < N_OUT_URB; i++) {
 		todo = left;
 		if (todo > OUT_BUFLEN)
 			todo = OUT_BUFLEN;
 
-		for (;i < N_OUT_URB; i++) {
-			/* Check we have a valid urb/endpoint before we use it... */
-			this_urb = portdata->out_urbs[i];
-			if (this_urb->status != -EINPROGRESS)
-				break;
+		this_urb = portdata->out_urbs[i];
+		if (this_urb->status == -EINPROGRESS) {
 			if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
 				continue;
 			if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
 				continue;
 			this_urb->transfer_flags |= URB_ASYNC_UNLINK;
 			usb_unlink_urb(this_urb);
+			continue;
 		}
-
-		if (i == N_OUT_URB) {
-			/* no bulk out free! */
-			dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
-#if 0
-			port->write_urb_busy = 0;
-#endif
-			return count-left;
-		}
+		if (this_urb->status != 0)
+			dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
 
 		dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
 
+		/* send the data */
 		memcpy (this_urb->transfer_buffer, buf, todo);
-
-		/* send the data out the bulk port */
 		this_urb->transfer_buffer_length = todo;
 
 		this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
 		err = usb_submit_urb(this_urb, GFP_ATOMIC);
 		if (err) {
-			dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
+			dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
 			continue;
 		}
 		portdata->tx_start_time[i] = jiffies;
@@ -323,9 +319,6 @@
 	}
 
 	count -= left;
-#if 0
-	port->write_urb_busy = 0;
-#endif
 	dbg("%s: wrote (did %d)", __FUNCTION__, count);
 	return count;
 }
@@ -333,7 +326,7 @@
 static void
 option_indat_callback (struct urb *urb, struct pt_regs *regs)
 {
-	int	i, err;
+	int i, err;
 	int endpoint;
 	struct usb_serial_port *port;
 	struct tty_struct *tty;
@@ -444,10 +437,11 @@
 
 	portdata = usb_get_serial_port_data(port);
 
-	for (i=0; i < N_OUT_URB; i++)
+	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
 		if (this_urb && this_urb->status != -EINPROGRESS)
 			data_len += OUT_BUFLEN;
+	}
 
 	dbg("%s: %d", __FUNCTION__, data_len);
 	return data_len;
@@ -464,11 +458,11 @@
 
 	portdata = usb_get_serial_port_data(port);
 
-	for (i=0; i < N_OUT_URB; i++)
+	for (i=0; i < N_OUT_URB; i++) {
 		this_urb = portdata->out_urbs[i];
 		if (this_urb && this_urb->status == -EINPROGRESS)
 			data_len += this_urb->transfer_buffer_length;
-
+	}
 	dbg("%s: %d", __FUNCTION__, data_len);
 	return data_len;
 }
@@ -477,10 +471,10 @@
 static int
 option_open (struct usb_serial_port *port, struct file *filp)
 {
-	struct option_port_private 	*portdata;
-	struct usb_serial 		*serial = port->serial;
-	int				i, err;
-	struct urb			*urb;
+	struct option_port_private *portdata;
+	struct usb_serial *serial = port->serial;
+	int i, err;
+	struct urb *urb;
 
 	portdata = usb_get_serial_port_data(port);
 
@@ -528,7 +522,7 @@
 }
 
 static inline void
-stop_urb(struct urb *urb)
+stop_urb (struct urb *urb)
 {
 	if (urb && urb->status == -EINPROGRESS) {
 		urb->transfer_flags &= ~URB_ASYNC_UNLINK;
@@ -537,11 +531,11 @@
 }
 
 static void
-option_close(struct usb_serial_port *port, struct file *filp)
+option_close (struct usb_serial_port *port, struct file *filp)
 {
-	int			i;
-	struct usb_serial	*serial = port->serial;
-	struct option_port_private 	*portdata;
+	int i;
+	struct usb_serial *serial = port->serial;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 	portdata = usb_get_serial_port_data(port);
@@ -589,11 +583,11 @@
 
 /* Setup urbs */
 static void
-option_setup_urbs(struct usb_serial *serial)
+option_setup_urbs (struct usb_serial *serial)
 {
-	int				j;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int j;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -617,7 +611,7 @@
 
 
 static int
-option_send_setup(struct usb_serial_port *port)
+option_send_setup (struct usb_serial_port *port)
 {
 	struct usb_serial *serial = port->serial;
 	struct option_port_private *portdata;
@@ -644,9 +638,9 @@
 static int
 option_startup (struct usb_serial *serial)
 {
-	int				i, err;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int i, err;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -677,9 +671,9 @@
 static void
 option_shutdown (struct usb_serial *serial)
 {
-	int				i, j;
-	struct usb_serial_port		*port;
-	struct option_port_private	*portdata;
+	int i, j;
+	struct usb_serial_port *port;
+	struct option_port_private *portdata;
 
 	dbg("%s", __FUNCTION__);
 
@@ -724,6 +718,8 @@
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
 
+#ifdef CONFIG_USB_DEBUG
 module_param(debug, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "Debug messages");
+#endif
 
diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c
index d44431d..0aa5ac1 100644
--- a/fs/ext2/xip.c
+++ b/fs/ext2/xip.c
@@ -15,66 +15,79 @@
 #include "xip.h"
 
 static inline int
-__inode_direct_access(struct inode *inode, sector_t sector, unsigned long *data) {
+__inode_direct_access(struct inode *inode, sector_t sector,
+		      unsigned long *data)
+{
 	BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);
 	return inode->i_sb->s_bdev->bd_disk->fops
 		->direct_access(inode->i_sb->s_bdev,sector,data);
 }
 
+static inline int
+__ext2_get_sector(struct inode *inode, sector_t offset, int create,
+		   sector_t *result)
+{
+	struct buffer_head tmp;
+	int rc;
+
+	memset(&tmp, 0, sizeof(struct buffer_head));
+	rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,
+			    create);
+	*result = tmp.b_blocknr;
+
+	/* did we get a sparse block (hole in the file)? */
+	if (!(*result)) {
+		BUG_ON(create);
+		rc = -ENODATA;
+	}
+
+	return rc;
+}
+
 int
-ext2_clear_xip_target(struct inode *inode, int block) {
-	sector_t sector = block*(PAGE_SIZE/512);
+ext2_clear_xip_target(struct inode *inode, int block)
+{
+	sector_t sector = block * (PAGE_SIZE/512);
 	unsigned long data;
 	int rc;
 
 	rc = __inode_direct_access(inode, sector, &data);
-	if (rc)
-		return rc;
-	clear_page((void*)data);
-	return 0;
+	if (!rc)
+		clear_page((void*)data);
+	return rc;
 }
 
 void ext2_xip_verify_sb(struct super_block *sb)
 {
 	struct ext2_sb_info *sbi = EXT2_SB(sb);
 
-	if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {
-		if ((sb->s_bdev == NULL) ||
-			sb->s_bdev->bd_disk == NULL ||
-			sb->s_bdev->bd_disk->fops == NULL ||
-			sb->s_bdev->bd_disk->fops->direct_access == NULL) {
-			sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
-			ext2_warning(sb, __FUNCTION__,
-				"ignoring xip option - not supported by bdev");
-		}
+	if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&
+	    !sb->s_bdev->bd_disk->fops->direct_access) {
+		sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);
+		ext2_warning(sb, __FUNCTION__,
+			     "ignoring xip option - not supported by bdev");
 	}
 }
 
-struct page*
-ext2_get_xip_page(struct address_space *mapping, sector_t blockno,
+struct page *
+ext2_get_xip_page(struct address_space *mapping, sector_t offset,
 		   int create)
 {
 	int rc;
 	unsigned long data;
-	struct buffer_head tmp;
+	sector_t sector;
 
-	tmp.b_state = 0;
-	tmp.b_blocknr = 0;
-	rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,
-				create);
+	/* first, retrieve the sector number */
+	rc = __ext2_get_sector(mapping->host, offset, create, &sector);
 	if (rc)
-		return ERR_PTR(rc);
-	if (tmp.b_blocknr == 0) {
-		/* SPARSE block */
-		BUG_ON(create);
-		return ERR_PTR(-ENODATA);
-	}
+		goto error;
 
+	/* retrieve address of the target data */
 	rc = __inode_direct_access
-		(mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);
-	if (rc)
-		return ERR_PTR(rc);
+		(mapping->host, sector * (PAGE_SIZE/512), &data);
+	if (!rc)
+		return virt_to_page(data);
 
-	SetPageUptodate(virt_to_page(data));
-	return virt_to_page(data);
+ error:
+	return ERR_PTR(rc);
 }
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 4bf43ea..88e68ca 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -15,7 +15,6 @@
 #include <linux/pagemap.h>
 #include <linux/blkdev.h>
 #include <linux/list.h>
-#include <linux/root_dev.h>
 #include <linux/statfs.h>
 #include <linux/kdev_t.h>
 #include <asm/uaccess.h>
@@ -160,8 +159,6 @@
 	ino->i_size = i_size;
 	ino->i_blksize = i_blksize;
 	ino->i_blocks = i_blocks;
-	if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
-		ino->i_uid = 0;
 	return(0);
 }
 
@@ -841,16 +838,10 @@
 		attrs.ia_mode = attr->ia_mode;
 	}
 	if(attr->ia_valid & ATTR_UID){
-		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
-		   (attr->ia_uid == 0))
-			attr->ia_uid = getuid();
 		attrs.ia_valid |= HOSTFS_ATTR_UID;
 		attrs.ia_uid = attr->ia_uid;
 	}
 	if(attr->ia_valid & ATTR_GID){
-		if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) &&
-		   (attr->ia_gid == 0))
-			attr->ia_gid = getgid();
 		attrs.ia_valid |= HOSTFS_ATTR_GID;
 		attrs.ia_gid = attr->ia_gid;
 	}
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 6f553e1..ff150fe 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -233,7 +233,7 @@
 		set_fs(USER_DS);
 
 	if(ppos) *ppos = file->f_pos;
-	return(n);
+	return n;
 }
 
 static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
@@ -254,7 +254,7 @@
 		err = os_read_file(fd, new_buf, cur);
 		if(err < 0){
 			printk("hppfs_read : read failed, errno = %d\n",
-			       count);
+			       err);
 			n = err;
 			goto out_free;
 		}
@@ -271,7 +271,7 @@
  out_free:
 	kfree(new_buf);
  out:
-	return(n);
+	return n;
 }
 
 static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 6a4c0a3..787d84a 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
  *
  * For licensing information, see the file 'LICENCE' in this directory.
  *
- * $Id: erase.c,v 1.76 2005/05/03 15:11:40 dedekind Exp $
+ * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $
  *
  */
 
@@ -300,100 +300,86 @@
 	jeb->last_node = NULL;
 }
 
+static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset)
+{
+	void *ebuf;
+	uint32_t ofs;
+	size_t retlen;
+	int ret = -EIO;
+	
+	ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!ebuf) {
+		printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);
+		return -EAGAIN;
+	}
+
+	D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
+
+	for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) {
+		uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
+		int i;
+
+		*bad_offset = ofs;
+
+		ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
+		if (ret) {
+			printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
+			goto fail;
+		}
+		if (retlen != readlen) {
+			printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
+			goto fail;
+		}
+		for (i=0; i<readlen; i += sizeof(unsigned long)) {
+			/* It's OK. We know it's properly aligned */
+			unsigned long *datum = ebuf + i;
+			if (*datum + 1) {
+				*bad_offset += i;
+				printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset);
+				goto fail;
+			}
+		}
+		ofs += readlen;
+		cond_resched();
+	}
+	ret = 0;
+fail:
+	kfree(ebuf);
+	return ret;
+}
+
 static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
 {
 	struct jffs2_raw_node_ref *marker_ref = NULL;
-	unsigned char *ebuf;
 	size_t retlen;
 	int ret;
 	uint32_t bad_offset;
 
-	if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) {
-		marker_ref = jffs2_alloc_raw_node_ref();
-		if (!marker_ref) {
-			printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
-			/* Stick it back on the list from whence it came and come back later */
-			jffs2_erase_pending_trigger(c);
-			spin_lock(&c->erase_completion_lock);
-			list_add(&jeb->list, &c->erase_complete_list);
-			spin_unlock(&c->erase_completion_lock);
-			return;
-		}
+	switch (jffs2_block_check_erase(c, jeb, &bad_offset)) {
+	case -EAGAIN:	goto refile;
+	case -EIO:	goto filebad;
 	}
-	ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!ebuf) {
-		printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset);
-	} else {
-		uint32_t ofs = jeb->offset;
-
-		D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
-		while(ofs < jeb->offset + c->sector_size) {
-			uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
-			int i;
-
-			bad_offset = ofs;
-
-			ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
-
-			if (ret) {
-				printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
-				goto bad;
-			}
-			if (retlen != readlen) {
-				printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
-				goto bad;
-			}
-			for (i=0; i<readlen; i += sizeof(unsigned long)) {
-				/* It's OK. We know it's properly aligned */
-				unsigned long datum = *(unsigned long *)(&ebuf[i]);
-				if (datum + 1) {
-					bad_offset += i;
-					printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);
-				bad: 
-					if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0))
-						jffs2_free_raw_node_ref(marker_ref);
-					kfree(ebuf);
-				bad2:
-					spin_lock(&c->erase_completion_lock);
-					/* Stick it on a list (any list) so
-					   erase_failed can take it right off
-					   again.  Silly, but shouldn't happen
-					   often. */
-					list_add(&jeb->list, &c->erasing_list);
-					spin_unlock(&c->erase_completion_lock);
-					jffs2_erase_failed(c, jeb, bad_offset);
-					return;
-				}
-			}
-			ofs += readlen;
-			cond_resched();
-		}
-		kfree(ebuf);
-	}
-
-	bad_offset = jeb->offset;
 
 	/* Write the erase complete marker */	
 	D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
-	if (jffs2_cleanmarker_oob(c)) {
+	bad_offset = jeb->offset;
 
-		if (jffs2_write_nand_cleanmarker(c, jeb))
-			goto bad2;
-			
+	/* Cleanmarker in oob area or no cleanmarker at all ? */
+	if (jffs2_cleanmarker_oob(c) || c->cleanmarker_size == 0) {
+
+		if (jffs2_cleanmarker_oob(c)) {
+			if (jffs2_write_nand_cleanmarker(c, jeb))
+				goto filebad;
+		}
+
 		jeb->first_node = jeb->last_node = NULL;
-
 		jeb->free_size = c->sector_size;
 		jeb->used_size = 0;
 		jeb->dirty_size = 0;
 		jeb->wasted_size = 0;
-	} else if (c->cleanmarker_size == 0) {
-		jeb->first_node = jeb->last_node = NULL;
 
-		jeb->free_size = c->sector_size;
-		jeb->used_size = 0;
-		jeb->dirty_size = 0;
-		jeb->wasted_size = 0;
 	} else {
+
 		struct kvec vecs[1];
 		struct jffs2_unknown_node marker = {
 			.magic =	cpu_to_je16(JFFS2_MAGIC_BITMASK),
@@ -401,21 +387,28 @@
 			.totlen =	cpu_to_je32(c->cleanmarker_size)
 		};
 
+		marker_ref = jffs2_alloc_raw_node_ref();
+		if (!marker_ref) {
+			printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n");
+			goto refile;
+		}
+
 		marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
 
 		vecs[0].iov_base = (unsigned char *) &marker;
 		vecs[0].iov_len = sizeof(marker);
 		ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);
 		
-		if (ret) {
-			printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
-			       jeb->offset, ret);
-			goto bad2;
-		}
-		if (retlen != sizeof(marker)) {
-			printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
-			       jeb->offset, sizeof(marker), retlen);
-			goto bad2;
+		if (ret || retlen != sizeof(marker)) {
+			if (ret)
+				printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
+				       jeb->offset, ret);
+			else
+				printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",
+				       jeb->offset, sizeof(marker), retlen);
+
+			jffs2_free_raw_node_ref(marker_ref);
+			goto filebad;
 		}
 
 		marker_ref->next_in_ino = NULL;
@@ -444,5 +437,22 @@
 	c->nr_free_blocks++;
 	spin_unlock(&c->erase_completion_lock);
 	wake_up(&c->erase_wait);
-}
+	return;
 
+filebad:
+	spin_lock(&c->erase_completion_lock);
+	/* Stick it on a list (any list) so erase_failed can take it
+	   right off again.  Silly, but shouldn't happen often. */
+	list_add(&jeb->list, &c->erasing_list);
+	spin_unlock(&c->erase_completion_lock);
+	jffs2_erase_failed(c, jeb, bad_offset);
+	return;
+
+refile:
+	/* Stick it back on the list from whence it came and come back later */
+	jffs2_erase_pending_trigger(c);
+	spin_lock(&c->erase_completion_lock);
+	list_add(&jeb->list, &c->erase_complete_list);
+	spin_unlock(&c->erase_completion_lock);
+	return;
+}
diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
index f11771e..dba9f22 100644
--- a/include/asm-ia64/pci.h
+++ b/include/asm-ia64/pci.h
@@ -128,6 +128,7 @@
 	void *acpi_handle;
 	void *iommu;
 	int segment;
+	int node;		/* nearest node with memory or -1 for global allocation */
 
 	unsigned int windows;
 	struct pci_window *window;
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h
index f9b8d21..2b42d9e 100644
--- a/include/asm-ia64/sn/pcibr_provider.h
+++ b/include/asm-ia64/sn/pcibr_provider.h
@@ -128,7 +128,7 @@
 #define pcibr_unlock(pcibus_info, flag)  spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag)
 
 extern int  pcibr_init_provider(void);
-extern void *pcibr_bus_fixup(struct pcibus_bussoft *);
+extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *);
 extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t);
 extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t);
 extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
diff --git a/include/asm-ia64/sn/pcibus_provider_defs.h b/include/asm-ia64/sn/pcibus_provider_defs.h
index 04e27d5..976f5ef 100644
--- a/include/asm-ia64/sn/pcibus_provider_defs.h
+++ b/include/asm-ia64/sn/pcibus_provider_defs.h
@@ -37,6 +37,7 @@
 	struct xwidget_info	*bs_xwidget_info;
 };
 
+struct pci_controller;
 /*
  * SN pci bus indirection
  */
@@ -45,7 +46,7 @@
 	dma_addr_t	(*dma_map)(struct pci_dev *, unsigned long, size_t);
 	dma_addr_t	(*dma_map_consistent)(struct pci_dev *, unsigned long, size_t);
 	void		(*dma_unmap)(struct pci_dev *, dma_addr_t, int);
-	void *		(*bus_fixup)(struct pcibus_bussoft *);
+	void *		(*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
 };
 
 extern struct sn_pcibus_provider *sn_pci_provider[];
diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h
index cf770e2..16a48b5 100644
--- a/include/asm-ia64/sn/simulator.h
+++ b/include/asm-ia64/sn/simulator.h
@@ -13,16 +13,9 @@
 #define SNMAGIC 0xaeeeeeee8badbeefL
 #define IS_MEDUSA()			({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
 
-#ifdef CONFIG_IA64_SGI_SN_SIM
 #define SIMULATOR_SLEEP()		asm("nop.i 0x8beef")
-#define IS_RUNNING_ON_SIMULATOR() 	(sn_prom_type)
+#define IS_RUNNING_ON_SIMULATOR()	(sn_prom_type)
 #define IS_RUNNING_ON_FAKE_PROM()	(sn_prom_type == 2)
 extern int sn_prom_type;		/* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
-#else
-#define IS_RUNNING_ON_SIMULATOR()	(0)
-#define IS_RUNNING_ON_FAKE_PROM()	(0)
-#define SIMULATOR_SLEEP()
-
-#endif
 
 #endif /* _ASM_IA64_SN_SIMULATOR_H */
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index 4e64c2a..399bc29 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -40,6 +40,11 @@
  */
 #define node_to_first_cpu(node) (__ffs(node_to_cpumask(node)))
 
+/*
+ * Determines the node for a given pci bus
+ */
+#define pcibus_to_node(bus) PCI_CONTROLLER(bus)->node
+
 void build_cpu_to_node_map(void);
 
 #define SD_CPU_INIT (struct sched_domain) {		\
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
new file mode 100644
index 0000000..e908439
--- /dev/null
+++ b/include/asm-um/ldt.h
@@ -0,0 +1,5 @@
+#ifndef __UM_LDT_H
+#define __UM_LDT_H
+
+#include "asm/arch/ldt.h"
+#endif
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h
index e24b74b..6213e97 100644
--- a/include/linux/raid/bitmap.h
+++ b/include/linux/raid/bitmap.h
@@ -262,7 +262,7 @@
 int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);
 void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,
 		     int success);
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
 void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
 void bitmap_close_sync(struct bitmap *bitmap);
 
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 1b02be7..4e11a9a 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -26,8 +26,6 @@
 /* this is initialized in init/main.c */
 dev_t ROOT_DEV;
 
-EXPORT_SYMBOL(ROOT_DEV);
-
 static int __init load_ramdisk(char *str)
 {
 	rd_doload = simple_strtol(str,NULL,0) & 3;
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 4553b2c..8c199f5 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -68,13 +68,12 @@
 		if (unlikely(IS_ERR(page))) {
 			if (PTR_ERR(page) == -ENODATA) {
 				/* sparse */
-				page = virt_to_page(empty_zero_page);
+				page = ZERO_PAGE(0);
 			} else {
 				desc->error = PTR_ERR(page);
 				goto out;
 			}
-		} else
-			BUG_ON(!PageUptodate(page));
+		}
 
 		/* If users can be writing to this page using arbitrary
 		 * virtual addresses, take care about potential aliasing
@@ -84,8 +83,7 @@
 			flush_dcache_page(page);
 
 		/*
-		 * Ok, we have the page, and it's up-to-date, so
-		 * now we can copy it to user space...
+		 * Ok, we have the page, so now we can copy it to user space...
 		 *
 		 * The actor routine returns how many bytes were actually used..
 		 * NOTE! This may not be the same as how much of a user buffer
@@ -164,7 +162,7 @@
  * xip_write
  *
  * This function walks all vmas of the address_space and unmaps the
- * empty_zero_page when found at pgoff. Should it go in rmap.c?
+ * ZERO_PAGE when found at pgoff. Should it go in rmap.c?
  */
 static void
 __xip_unmap (struct address_space * mapping,
@@ -187,7 +185,7 @@
 		 * We need the page_table_lock to protect us from page faults,
 		 * munmap, fork, etc...
 		 */
-		pte = page_check_address(virt_to_page(empty_zero_page), mm,
+		pte = page_check_address(ZERO_PAGE(address), mm,
 					 address);
 		if (!IS_ERR(pte)) {
 			/* Nuke the page table entry. */
@@ -230,7 +228,6 @@
 
 	page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);
 	if (!IS_ERR(page)) {
-		BUG_ON(!PageUptodate(page));
 		return page;
 	}
 	if (PTR_ERR(page) != -ENODATA)
@@ -245,12 +242,11 @@
 			pgoff*(PAGE_SIZE/512), 1);
 		if (IS_ERR(page))
 			return NULL;
-		BUG_ON(!PageUptodate(page));
 		/* unmap page at pgoff from all other vmas */
 		__xip_unmap(mapping, pgoff);
 	} else {
-		/* not shared and writable, use empty_zero_page */
-		page = virt_to_page(empty_zero_page);
+		/* not shared and writable, use ZERO_PAGE() */
+		page = ZERO_PAGE(address);
 	}
 
 	return page;
@@ -319,8 +315,6 @@
 			break;
 		}
 
-		BUG_ON(!PageUptodate(page));
-
 		copied = filemap_copy_from_user(page, offset, buf, bytes);
 		flush_dcache_page(page);
 		if (likely(copied > 0)) {
@@ -435,8 +429,7 @@
 			return 0;
 		else
 			return PTR_ERR(page);
-	} else
-		BUG_ON(!PageUptodate(page));
+	}
 	kaddr = kmap_atomic(page, KM_USER0);
 	memset(kaddr + offset, 0, length);
 	kunmap_atomic(kaddr, KM_USER0);