diff -druNp linux-libre-2.6.30-gnu1/arch/alpha/include/asm/percpu.h linux-libre-2.6.30.10-gnu1/arch/alpha/include/asm/percpu.h
--- linux-libre-2.6.30-gnu1/arch/alpha/include/asm/percpu.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/alpha/include/asm/percpu.h	2009-12-04 01:00:07.000000000 -0500
@@ -30,7 +30,7 @@ extern unsigned long __per_cpu_offset[NR
 
 #ifndef MODULE
 #define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
-#define PER_CPU_ATTRIBUTES
+#define PER_CPU_DEF_ATTRIBUTES
 #else
 /*
  * To calculate addresses of locally defined variables, GCC uses 32-bit
@@ -49,7 +49,7 @@ extern unsigned long __per_cpu_offset[NR
 		: "=&r"(__ptr), "=&r"(tmp_gp));		\
 	(typeof(&per_cpu_var(var)))(__ptr + (offset)); })
 
-#define PER_CPU_ATTRIBUTES	__used
+#define PER_CPU_DEF_ATTRIBUTES	__used
 
 #endif /* MODULE */
 
@@ -71,7 +71,7 @@ extern unsigned long __per_cpu_offset[NR
 #define __get_cpu_var(var)		per_cpu_var(var)
 #define __raw_get_cpu_var(var)		per_cpu_var(var)
 
-#define PER_CPU_ATTRIBUTES
+#define PER_CPU_DEF_ATTRIBUTES
 
 #endif /* SMP */
 
diff -druNp linux-libre-2.6.30-gnu1/arch/arm/include/asm/cacheflush.h linux-libre-2.6.30.10-gnu1/arch/arm/include/asm/cacheflush.h
--- linux-libre-2.6.30-gnu1/arch/arm/include/asm/cacheflush.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/arm/include/asm/cacheflush.h	2009-12-04 01:00:07.000000000 -0500
@@ -429,6 +429,14 @@ static inline void flush_anon_page(struc
 		__flush_anon_page(vma, page, vmaddr);
 }
 
+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
+static inline void flush_kernel_dcache_page(struct page *page)
+{
+	/* highmem pages are always flushed upon kunmap already */
+	if ((cache_is_vivt() || cache_is_vipt_aliasing()) && !PageHighMem(page))
+		__cpuc_flush_dcache_page(page_address(page));
+}
+
 #define flush_dcache_mmap_lock(mapping) \
 	spin_lock_irq(&(mapping)->tree_lock)
 #define flush_dcache_mmap_unlock(mapping) \
diff -druNp linux-libre-2.6.30-gnu1/arch/arm/mm/highmem.c linux-libre-2.6.30.10-gnu1/arch/arm/mm/highmem.c
--- linux-libre-2.6.30-gnu1/arch/arm/mm/highmem.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/arm/mm/highmem.c	2009-12-04 01:00:07.000000000 -0500
@@ -40,11 +40,16 @@ void *kmap_atomic(struct page *page, enu
 {
 	unsigned int idx;
 	unsigned long vaddr;
+	void *kmap;
 
 	pagefault_disable();
 	if (!PageHighMem(page))
 		return page_address(page);
 
+	kmap = kmap_high_get(page);
+	if (kmap)
+		return kmap;
+
 	idx = type + KM_TYPE_NR * smp_processor_id();
 	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
 #ifdef CONFIG_DEBUG_HIGHMEM
@@ -80,6 +85,9 @@ void kunmap_atomic(void *kvaddr, enum km
 #else
 		(void) idx;  /* to kill a warning */
 #endif
+	} else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
+		/* this address was obtained through kmap_high_get() */
+		kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
 	}
 	pagefault_enable();
 }
diff -druNp linux-libre-2.6.30-gnu1/arch/blackfin/kernel/irqchip.c linux-libre-2.6.30.10-gnu1/arch/blackfin/kernel/irqchip.c
--- linux-libre-2.6.30-gnu1/arch/blackfin/kernel/irqchip.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/blackfin/kernel/irqchip.c	2009-12-04 01:00:07.000000000 -0500
@@ -38,14 +38,6 @@
 #include <asm/pda.h>
 
 static atomic_t irq_err_count;
-static spinlock_t irq_controller_lock;
-
-/*
- * Dummy mask/unmask handler
- */
-void dummy_mask_unmask_irq(unsigned int irq)
-{
-}
 
 void ack_bad_irq(unsigned int irq)
 {
@@ -53,21 +45,9 @@ void ack_bad_irq(unsigned int irq)
 	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
 }
 
-static struct irq_chip bad_chip = {
-	.ack = dummy_mask_unmask_irq,
-	.mask = dummy_mask_unmask_irq,
-	.unmask = dummy_mask_unmask_irq,
-};
-
 static struct irq_desc bad_irq_desc = {
-	.status = IRQ_DISABLED,
-	.chip = &bad_chip,
 	.handle_irq = handle_bad_irq,
-	.depth = 1,
 	.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
-#ifdef CONFIG_SMP
-	.affinity = CPU_MASK_ALL
-#endif
 };
 
 #ifdef CONFIG_CPUMASK_OFFSTACK
@@ -117,21 +97,13 @@ __attribute__((l1_text))
 #endif
 asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
 {
-	struct pt_regs *old_regs;
-	struct irq_desc *desc = irq_desc + irq;
 #ifndef CONFIG_IPIPE
 	unsigned short pending, other_ints;
 #endif
-	old_regs = set_irq_regs(regs);
-
-	/*
-	 * Some hardware gives randomly wrong interrupts.  Rather
-	 * than crashing, do something sensible.
-	 */
-	if (irq >= NR_IRQS)
-		desc = &bad_irq_desc;
+	struct pt_regs *old_regs = set_irq_regs(regs);
 
 	irq_enter();
+
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	/* Debugging check for stack overflow: is there less than STACK_WARN free? */
 	{
@@ -147,7 +119,15 @@ asmlinkage void asm_do_IRQ(unsigned int
 		}
 	}
 #endif
-	generic_handle_irq(irq);
+
+	/*
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
+	 */
+	if (irq >= NR_IRQS)
+		handle_bad_irq(irq, &bad_irq_desc);
+	else
+		generic_handle_irq(irq);
 
 #ifndef CONFIG_IPIPE
 	/*
@@ -171,14 +151,6 @@ asmlinkage void asm_do_IRQ(unsigned int
 
 void __init init_IRQ(void)
 {
-	struct irq_desc *desc;
-	int irq;
-
-	spin_lock_init(&irq_controller_lock);
-	for (irq = 0, desc = irq_desc; irq < NR_IRQS; irq++, desc++) {
-		*desc = bad_irq_desc;
-	}
-
 	init_arch_irq();
 
 #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
diff -druNp linux-libre-2.6.30-gnu1/arch/blackfin/kernel/setup.c linux-libre-2.6.30.10-gnu1/arch/blackfin/kernel/setup.c
--- linux-libre-2.6.30-gnu1/arch/blackfin/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/blackfin/kernel/setup.c	2009-12-04 01:00:07.000000000 -0500
@@ -831,7 +831,8 @@ void __init setup_arch(char **cmdline_p)
     defined(CONFIG_BF538) || defined(CONFIG_BF539)
 	_bfin_swrst = bfin_read_SWRST();
 #else
-	_bfin_swrst = bfin_read_SYSCR();
+	/* Clear boot mode field */
+	_bfin_swrst = bfin_read_SYSCR() & ~0xf;
 #endif
 
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
diff -druNp linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/head.S linux-libre-2.6.30.10-gnu1/arch/blackfin/mach-common/head.S
--- linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/head.S	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/blackfin/mach-common/head.S	2009-12-04 01:00:07.000000000 -0500
@@ -126,25 +126,25 @@ ENTRY(__start)
 	 * below
 	 */
 	GET_PDA(p0, r0);
-	r7 = [p0 + PDA_RETX];
+	r6 = [p0 + PDA_RETX];
 	p1.l = _init_saved_retx;
 	p1.h = _init_saved_retx;
-	[p1] = r7;
+	[p1] = r6;
 
-	r7 = [p0 + PDA_DCPLB];
+	r6 = [p0 + PDA_DCPLB];
 	p1.l = _init_saved_dcplb_fault_addr;
 	p1.h = _init_saved_dcplb_fault_addr;
-	[p1] = r7;
+	[p1] = r6;
 
-	r7 = [p0 + PDA_ICPLB];
+	r6 = [p0 + PDA_ICPLB];
 	p1.l = _init_saved_icplb_fault_addr;
 	p1.h = _init_saved_icplb_fault_addr;
-	[p1] = r7;
+	[p1] = r6;
 
-	r7 = [p0 + PDA_SEQSTAT];
+	r6 = [p0 + PDA_SEQSTAT];
 	p1.l = _init_saved_seqstat;
 	p1.h = _init_saved_seqstat;
-	[p1] = r7;
+	[p1] = r6;
 #endif
 
 	/* Initialize stack pointer */
diff -druNp linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/smp.c linux-libre-2.6.30.10-gnu1/arch/blackfin/mach-common/smp.c
--- linux-libre-2.6.30-gnu1/arch/blackfin/mach-common/smp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/blackfin/mach-common/smp.c	2009-12-04 01:00:07.000000000 -0500
@@ -139,7 +139,7 @@ static void ipi_call_function(unsigned i
 
 static irqreturn_t ipi_handler(int irq, void *dev_instance)
 {
-	struct ipi_message *msg, *mg;
+	struct ipi_message *msg;
 	struct ipi_message_queue *msg_queue;
 	unsigned int cpu = smp_processor_id();
 
@@ -149,7 +149,8 @@ static irqreturn_t ipi_handler(int irq,
 	msg_queue->count++;
 
 	spin_lock(&msg_queue->lock);
-	list_for_each_entry_safe(msg, mg, &msg_queue->head, list) {
+	while (!list_empty(&msg_queue->head)) {
+		msg = list_entry(msg_queue->head.next, typeof(*msg), list);
 		list_del(&msg->list);
 		switch (msg->type) {
 		case BFIN_IPI_RESCHEDULE:
@@ -216,7 +217,7 @@ int smp_call_function(void (*func)(void
 	for_each_cpu_mask(cpu, callmap) {
 		msg_queue = &per_cpu(ipi_msg_queue, cpu);
 		spin_lock_irqsave(&msg_queue->lock, flags);
-		list_add(&msg->list, &msg_queue->head);
+		list_add_tail(&msg->list, &msg_queue->head);
 		spin_unlock_irqrestore(&msg_queue->lock, flags);
 		platform_send_ipi_cpu(cpu);
 	}
@@ -256,7 +257,7 @@ int smp_call_function_single(int cpuid,
 
 	msg_queue = &per_cpu(ipi_msg_queue, cpu);
 	spin_lock_irqsave(&msg_queue->lock, flags);
-	list_add(&msg->list, &msg_queue->head);
+	list_add_tail(&msg->list, &msg_queue->head);
 	spin_unlock_irqrestore(&msg_queue->lock, flags);
 	platform_send_ipi_cpu(cpu);
 
@@ -287,7 +288,7 @@ void smp_send_reschedule(int cpu)
 
 	msg_queue = &per_cpu(ipi_msg_queue, cpu);
 	spin_lock_irqsave(&msg_queue->lock, flags);
-	list_add(&msg->list, &msg_queue->head);
+	list_add_tail(&msg->list, &msg_queue->head);
 	spin_unlock_irqrestore(&msg_queue->lock, flags);
 	platform_send_ipi_cpu(cpu);
 
@@ -315,7 +316,7 @@ void smp_send_stop(void)
 	for_each_cpu_mask(cpu, callmap) {
 		msg_queue = &per_cpu(ipi_msg_queue, cpu);
 		spin_lock_irqsave(&msg_queue->lock, flags);
-		list_add(&msg->list, &msg_queue->head);
+		list_add_tail(&msg->list, &msg_queue->head);
 		spin_unlock_irqrestore(&msg_queue->lock, flags);
 		platform_send_ipi_cpu(cpu);
 	}
diff -druNp linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-dma.c linux-libre-2.6.30.10-gnu1/arch/ia64/kernel/pci-dma.c
--- linux-libre-2.6.30-gnu1/arch/ia64/kernel/pci-dma.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/ia64/kernel/pci-dma.c	2009-12-04 01:00:07.000000000 -0500
@@ -67,11 +67,6 @@ iommu_dma_init(void)
 
 int iommu_dma_supported(struct device *dev, u64 mask)
 {
-	struct dma_map_ops *ops = platform_dma_get_ops(dev);
-
-	if (ops->dma_supported)
-		return ops->dma_supported(dev, mask);
-
 	/* Copied from i386. Doesn't make much sense, because it will
 	   only work for pci_alloc_coherent.
 	   The caller just has to use GFP_DMA in this case. */
diff -druNp linux-libre-2.6.30-gnu1/arch/parisc/include/asm/system.h linux-libre-2.6.30.10-gnu1/arch/parisc/include/asm/system.h
--- linux-libre-2.6.30-gnu1/arch/parisc/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/parisc/include/asm/system.h	2009-12-04 01:00:07.000000000 -0500
@@ -168,8 +168,8 @@ static inline void set_eiem(unsigned lon
 /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*.  */
 #define __ldcw(a) ({						\
 	unsigned __ret;						\
-	__asm__ __volatile__(__LDCW " 0(%1),%0"			\
-		: "=r" (__ret) : "r" (a));			\
+	__asm__ __volatile__(__LDCW " 0(%2),%0"			\
+		: "=r" (__ret), "+m" (*(a)) : "r" (a));		\
 	__ret;							\
 })
 
diff -druNp linux-libre-2.6.30-gnu1/arch/parisc/include/asm/tlbflush.h linux-libre-2.6.30.10-gnu1/arch/parisc/include/asm/tlbflush.h
--- linux-libre-2.6.30-gnu1/arch/parisc/include/asm/tlbflush.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/parisc/include/asm/tlbflush.h	2009-12-04 01:00:07.000000000 -0500
@@ -12,14 +12,12 @@
  * N class systems, only one PxTLB inter processor broadcast can be
  * active at any one time on the Merced bus.  This tlb purge
  * synchronisation is fairly lightweight and harmless so we activate
- * it on all SMP systems not just the N class.  We also need to have
- * preemption disabled on uniprocessor machines, and spin_lock does that
- * nicely.
+ * it on all systems not just the N class.
  */
 extern spinlock_t pa_tlb_lock;
 
-#define purge_tlb_start(x) spin_lock(&pa_tlb_lock)
-#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock)
+#define purge_tlb_start(flags)	spin_lock_irqsave(&pa_tlb_lock, flags)
+#define purge_tlb_end(flags)	spin_unlock_irqrestore(&pa_tlb_lock, flags)
 
 extern void flush_tlb_all(void);
 extern void flush_tlb_all_local(void *);
@@ -63,14 +61,16 @@ static inline void flush_tlb_mm(struct m
 static inline void flush_tlb_page(struct vm_area_struct *vma,
 	unsigned long addr)
 {
+	unsigned long flags;
+
 	/* For one page, it's not worth testing the split_tlb variable */
 
 	mb();
 	mtsp(vma->vm_mm->context,1);
-	purge_tlb_start();
+	purge_tlb_start(flags);
 	pdtlb(addr);
 	pitlb(addr);
-	purge_tlb_end();
+	purge_tlb_end(flags);
 }
 
 void __flush_tlb_range(unsigned long sid,
diff -druNp linux-libre-2.6.30-gnu1/arch/parisc/kernel/cache.c linux-libre-2.6.30.10-gnu1/arch/parisc/kernel/cache.c
--- linux-libre-2.6.30-gnu1/arch/parisc/kernel/cache.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/parisc/kernel/cache.c	2009-12-04 01:00:07.000000000 -0500
@@ -398,12 +398,13 @@ EXPORT_SYMBOL(flush_kernel_icache_range_
 
 void clear_user_page_asm(void *page, unsigned long vaddr)
 {
+	unsigned long flags;
 	/* This function is implemented in assembly in pacache.S */
 	extern void __clear_user_page_asm(void *page, unsigned long vaddr);
 
-	purge_tlb_start();
+	purge_tlb_start(flags);
 	__clear_user_page_asm(page, vaddr);
-	purge_tlb_end();
+	purge_tlb_end(flags);
 }
 
 #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */
@@ -444,20 +445,24 @@ extern void clear_user_page_asm(void *pa
 
 void clear_user_page(void *page, unsigned long vaddr, struct page *pg)
 {
+	unsigned long flags;
+
 	purge_kernel_dcache_page((unsigned long)page);
-	purge_tlb_start();
+	purge_tlb_start(flags);
 	pdtlb_kernel(page);
-	purge_tlb_end();
+	purge_tlb_end(flags);
 	clear_user_page_asm(page, vaddr);
 }
 EXPORT_SYMBOL(clear_user_page);
 
 void flush_kernel_dcache_page_addr(void *addr)
 {
+	unsigned long flags;
+
 	flush_kernel_dcache_page_asm(addr);
-	purge_tlb_start();
+	purge_tlb_start(flags);
 	pdtlb_kernel(addr);
-	purge_tlb_end();
+	purge_tlb_end(flags);
 }
 EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
 
@@ -490,8 +495,10 @@ void __flush_tlb_range(unsigned long sid
 	if (npages >= 512)  /* 2MB of space: arbitrary, should be tuned */
 		flush_tlb_all();
 	else {
+		unsigned long flags;
+
 		mtsp(sid, 1);
-		purge_tlb_start();
+		purge_tlb_start(flags);
 		if (split_tlb) {
 			while (npages--) {
 				pdtlb(start);
@@ -504,7 +511,7 @@ void __flush_tlb_range(unsigned long sid
 				start += PAGE_SIZE;
 			}
 		}
-		purge_tlb_end();
+		purge_tlb_end(flags);
 	}
 }
 
diff -druNp linux-libre-2.6.30-gnu1/arch/parisc/kernel/pci-dma.c linux-libre-2.6.30.10-gnu1/arch/parisc/kernel/pci-dma.c
--- linux-libre-2.6.30-gnu1/arch/parisc/kernel/pci-dma.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/parisc/kernel/pci-dma.c	2009-12-04 01:00:07.000000000 -0500
@@ -90,12 +90,14 @@ static inline int map_pte_uncached(pte_t
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
 	do {
+		unsigned long flags;
+
 		if (!pte_none(*pte))
 			printk(KERN_ERR "map_pte_uncached: page already exists\n");
 		set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
-		purge_tlb_start();
+		purge_tlb_start(flags);
 		pdtlb_kernel(orig_vaddr);
-		purge_tlb_end();
+		purge_tlb_end(flags);
 		vaddr += PAGE_SIZE;
 		orig_vaddr += PAGE_SIZE;
 		(*paddr_ptr) += PAGE_SIZE;
@@ -168,11 +170,13 @@ static inline void unmap_uncached_pte(pm
 	if (end > PMD_SIZE)
 		end = PMD_SIZE;
 	do {
+		unsigned long flags;
 		pte_t page = *pte;
+
 		pte_clear(&init_mm, vaddr, pte);
-		purge_tlb_start();
+		purge_tlb_start(flags);
 		pdtlb_kernel(orig_vaddr);
-		purge_tlb_end();
+		purge_tlb_end(flags);
 		vaddr += PAGE_SIZE;
 		orig_vaddr += PAGE_SIZE;
 		pte++;
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts
--- linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/asp834x-redboot.dts	2009-12-04 01:00:07.000000000 -0500
@@ -167,7 +167,7 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <39 0x8>;
 			phy_type = "ulpi";
-			port1;
+			port0;
 		};
 		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
 		usb@23000 {
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts
--- linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/mpc8349emitx.dts	2009-12-04 01:00:07.000000000 -0500
@@ -156,7 +156,7 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <39 0x8>;
 			phy_type = "ulpi";
-			port1;
+			port0;
 		};
 
 		usb@23000 {
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts
--- linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/mpc834x_mds.dts	2009-12-04 01:00:07.000000000 -0500
@@ -153,7 +153,7 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <39 0x8>;
 			phy_type = "ulpi";
-			port1;
+			port0;
 		};
 		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
 		usb@23000 {
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8349.dts linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/sbc8349.dts
--- linux-libre-2.6.30-gnu1/arch/powerpc/boot/dts/sbc8349.dts	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/boot/dts/sbc8349.dts	2009-12-04 01:00:07.000000000 -0500
@@ -144,7 +144,7 @@
 			interrupt-parent = <&ipic>;
 			interrupts = <39 0x8>;
 			phy_type = "ulpi";
-			port1;
+			port0;
 		};
 		/* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
 		usb@23000 {
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-hash64.h linux-libre-2.6.30.10-gnu1/arch/powerpc/include/asm/mmu-hash64.h
--- linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/include/asm/mmu-hash64.h	2009-12-04 01:00:07.000000000 -0500
@@ -41,6 +41,7 @@ extern char initial_stab[];
 
 #define SLB_NUM_BOLTED		3
 #define SLB_CACHE_ENTRIES	8
+#define SLB_MIN_SIZE		32
 
 /* Bits in the SLB ESID word */
 #define SLB_ESID_V		ASM_CONST(0x0000000008000000) /* valid */
@@ -296,6 +297,7 @@ extern void slb_flush_and_rebolt(void);
 extern void stab_initialize(unsigned long stab);
 
 extern void slb_vmalloc_update(void);
+extern void slb_set_size(u16 size);
 #endif /* __ASSEMBLY__ */
 
 /*
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-common.h linux-libre-2.6.30.10-gnu1/arch/powerpc/include/asm/pte-common.h
--- linux-libre-2.6.30-gnu1/arch/powerpc/include/asm/pte-common.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/include/asm/pte-common.h	2009-12-04 01:00:07.000000000 -0500
@@ -176,7 +176,7 @@ extern unsigned long bad_call_to_PMD_PAG
 #define HAVE_PAGE_AGP
 
 /* Advertise support for _PAGE_SPECIAL */
-#ifdef _PAGE_SPECIAL
+#if _PAGE_SPECIAL != 0
 #define __HAVE_ARCH_PTE_SPECIAL
 #endif
 
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/kernel/lparcfg.c linux-libre-2.6.30.10-gnu1/arch/powerpc/kernel/lparcfg.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/kernel/lparcfg.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/kernel/lparcfg.c	2009-12-04 01:00:07.000000000 -0500
@@ -35,6 +35,7 @@
 #include <asm/prom.h>
 #include <asm/vdso_datapage.h>
 #include <asm/vio.h>
+#include <asm/mmu.h>
 
 #define MODULE_VERS "1.8"
 #define MODULE_NAME "lparcfg"
@@ -501,6 +502,8 @@ static int pseries_lparcfg_data(struct s
 
 	seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
 
+	seq_printf(m, "slb_size=%d\n", mmu_slb_size);
+
 	return 0;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas.c linux-libre-2.6.30.10-gnu1/arch/powerpc/kernel/rtas.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/kernel/rtas.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/kernel/rtas.c	2009-12-04 01:00:07.000000000 -0500
@@ -38,6 +38,7 @@
 #include <asm/syscalls.h>
 #include <asm/smp.h>
 #include <asm/atomic.h>
+#include <asm/mmu.h>
 
 struct rtas_t rtas = {
 	.lock = SPIN_LOCK_UNLOCKED
@@ -692,6 +693,7 @@ static void rtas_percpu_suspend_me(void
 {
 	long rc = H_SUCCESS;
 	unsigned long msr_save;
+	u16 slb_size = mmu_slb_size;
 	int cpu;
 	struct rtas_suspend_me_data *data =
 		(struct rtas_suspend_me_data *)info;
@@ -714,13 +716,16 @@ static void rtas_percpu_suspend_me(void
 		/* All other cpus are in H_JOIN, this cpu does
 		 * the suspend.
 		 */
+		slb_set_size(SLB_MIN_SIZE);
 		printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
 		       smp_processor_id());
 		data->error = rtas_call(data->token, 0, 1, NULL);
 
-		if (data->error)
+		if (data->error) {
 			printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
 			       data->error);
+			slb_set_size(slb_size);
+		}
 	} else {
 		printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
 		       smp_processor_id(), rc);
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable.c linux-libre-2.6.30.10-gnu1/arch/powerpc/mm/pgtable.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/mm/pgtable.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/mm/pgtable.c	2009-12-04 01:00:07.000000000 -0500
@@ -30,6 +30,8 @@
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 
+#include "mmu_decl.h"
+
 static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
 static unsigned long pte_freelist_forced_free;
 
@@ -119,7 +121,7 @@ void pte_free_finish(void)
 /*
  * Handle i/d cache flushing, called from set_pte_at() or ptep_set_access_flags()
  */
-static pte_t do_dcache_icache_coherency(pte_t pte)
+static pte_t do_dcache_icache_coherency(pte_t pte, unsigned long addr)
 {
 	unsigned long pfn = pte_pfn(pte);
 	struct page *page;
@@ -128,6 +130,17 @@ static pte_t do_dcache_icache_coherency(
 		return pte;
 	page = pfn_to_page(pfn);
 
+#ifdef CONFIG_8xx
+       /* On 8xx, cache control instructions (particularly
+        * "dcbst" from flush_dcache_icache) fault as write
+        * operation if there is an unpopulated TLB entry
+        * for the address in question. To workaround that,
+        * we invalidate the TLB here, thus avoiding dcbst
+        * misbehaviour.
+        */
+       _tlbil_va(addr, 0 /* 8xx doesn't care about PID */);
+#endif
+
 	if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags)) {
 		pr_debug("do_dcache_icache_coherency... flushing\n");
 		flush_dcache_icache_page(page);
@@ -198,7 +211,7 @@ void set_pte_at(struct mm_struct *mm, un
 	 */
 	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
 	if (pte_need_exec_flush(pte, 1))
-		pte = do_dcache_icache_coherency(pte);
+		pte = do_dcache_icache_coherency(pte, addr);
 
 	/* Perform the setting of the PTE */
 	__set_pte_at(mm, addr, ptep, pte, 0);
@@ -216,7 +229,7 @@ int ptep_set_access_flags(struct vm_area
 {
 	int changed;
 	if (!dirty && pte_need_exec_flush(entry, 0))
-		entry = do_dcache_icache_coherency(entry);
+		entry = do_dcache_icache_coherency(entry, address);
 	changed = !pte_same(*(ptep), entry);
 	if (changed) {
 		if (!(vma->vm_flags & VM_HUGETLB))
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/mm/slb.c linux-libre-2.6.30.10-gnu1/arch/powerpc/mm/slb.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/mm/slb.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/mm/slb.c	2009-12-04 01:00:07.000000000 -0500
@@ -247,14 +247,22 @@ void switch_slb(struct task_struct *tsk,
 static inline void patch_slb_encoding(unsigned int *insn_addr,
 				      unsigned int immed)
 {
-	/* Assume the instruction had a "0" immediate value, just
-	 * "or" in the new value
-	 */
-	*insn_addr |= immed;
+	*insn_addr = (*insn_addr & 0xffff0000) | immed;
 	flush_icache_range((unsigned long)insn_addr, 4+
 			   (unsigned long)insn_addr);
 }
 
+void slb_set_size(u16 size)
+{
+	extern unsigned int *slb_compare_rr_to_size;
+
+	if (mmu_slb_size == size)
+		return;
+
+	mmu_slb_size = size;
+	patch_slb_encoding(slb_compare_rr_to_size, mmu_slb_size);
+}
+
 void slb_initialize(void)
 {
 	unsigned long linear_llp, vmalloc_llp, io_llp;
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc83xx.h linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/83xx/mpc83xx.h
--- linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/mpc83xx.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/83xx/mpc83xx.h	2009-12-04 01:00:07.000000000 -0500
@@ -22,8 +22,8 @@
 /* system i/o configuration register low */
 #define MPC83XX_SICRL_OFFS         0x114
 #define MPC834X_SICRL_USB_MASK     0x60000000
-#define MPC834X_SICRL_USB0         0x40000000
-#define MPC834X_SICRL_USB1         0x20000000
+#define MPC834X_SICRL_USB0         0x20000000
+#define MPC834X_SICRL_USB1         0x40000000
 #define MPC831X_SICRL_USB_MASK     0x00000c00
 #define MPC831X_SICRL_USB_ULPI     0x00000800
 #define MPC8315_SICRL_USB_MASK     0x000000fc
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/usb.c linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/83xx/usb.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/platforms/83xx/usb.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/83xx/usb.c	2009-12-04 01:00:07.000000000 -0500
@@ -47,25 +47,25 @@ int mpc834x_usb_cfg(void)
 		sccr |= MPC83XX_SCCR_USB_DRCM_11;  /* 1:3 */
 
 		prop = of_get_property(np, "phy_type", NULL);
+		port1_is_dr = 1;
 		if (prop && (!strcmp(prop, "utmi") ||
 					!strcmp(prop, "utmi_wide"))) {
 			sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
 			sicrh |= MPC834X_SICRH_USB_UTMI;
-			port1_is_dr = 1;
+			port0_is_dr = 1;
 		} else if (prop && !strcmp(prop, "serial")) {
 			dr_mode = of_get_property(np, "dr_mode", NULL);
 			if (dr_mode && !strcmp(dr_mode, "otg")) {
 				sicrl |= MPC834X_SICRL_USB0 | MPC834X_SICRL_USB1;
-				port1_is_dr = 1;
+				port0_is_dr = 1;
 			} else {
-				sicrl |= MPC834X_SICRL_USB0;
+				sicrl |= MPC834X_SICRL_USB1;
 			}
 		} else if (prop && !strcmp(prop, "ulpi")) {
-			sicrl |= MPC834X_SICRL_USB0;
+			sicrl |= MPC834X_SICRL_USB1;
 		} else {
 			printk(KERN_WARNING "834x USB PHY type not supported\n");
 		}
-		port0_is_dr = 1;
 		of_node_put(np);
 	}
 	np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph");
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/time.c linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/ps3/time.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/platforms/ps3/time.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/ps3/time.c	2009-12-04 01:00:07.000000000 -0500
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 
+#include <asm/firmware.h>
 #include <asm/rtc.h>
 #include <asm/lv1call.h>
 #include <asm/ps3.h>
@@ -84,6 +85,9 @@ static int __init ps3_rtc_init(void)
 {
 	struct platform_device *pdev;
 
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
 	pdev = platform_device_register_simple("rtc-ps3", -1, NULL, 0);
 	if (IS_ERR(pdev))
 		return PTR_ERR(pdev);
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/reconfig.c linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/pseries/reconfig.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/platforms/pseries/reconfig.c	2009-12-04 01:00:07.000000000 -0500
@@ -20,6 +20,7 @@
 #include <asm/machdep.h>
 #include <asm/uaccess.h>
 #include <asm/pSeries_reconfig.h>
+#include <asm/mmu.h>
 
 
 
@@ -439,9 +440,15 @@ static int do_update_property(char *buf,
 	if (!newprop)
 		return -ENOMEM;
 
+	if (!strcmp(name, "slb-size") || !strcmp(name, "ibm,slb-size"))
+		slb_set_size(*(int *)value);
+
 	oldprop = of_find_property(np, name,NULL);
-	if (!oldprop)
+	if (!oldprop) {
+		if (strlen(name))
+			return prom_add_property(np, newprop);
 		return -ENODEV;
+	}
 
 	rc = prom_update_property(np, newprop, oldprop);
 	if (rc)
diff -druNp linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/mpic.c linux-libre-2.6.30.10-gnu1/arch/powerpc/sysdev/mpic.c
--- linux-libre-2.6.30-gnu1/arch/powerpc/sysdev/mpic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/powerpc/sysdev/mpic.c	2009-12-04 01:00:07.000000000 -0500
@@ -279,28 +279,29 @@ static void _mpic_map_mmio(struct mpic *
 }
 
 #ifdef CONFIG_PPC_DCR
-static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
+static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node,
+			  struct mpic_reg_bank *rb,
 			  unsigned int offset, unsigned int size)
 {
 	const u32 *dbasep;
 
-	dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL);
+	dbasep = of_get_property(node, "dcr-reg", NULL);
 
-	rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size);
+	rb->dhost = dcr_map(node, *dbasep + offset, size);
 	BUG_ON(!DCR_MAP_OK(rb->dhost));
 }
 
-static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr,
-			    struct mpic_reg_bank *rb, unsigned int offset,
-			    unsigned int size)
+static inline void mpic_map(struct mpic *mpic, struct device_node *node,
+			    phys_addr_t phys_addr, struct mpic_reg_bank *rb,
+			    unsigned int offset, unsigned int size)
 {
 	if (mpic->flags & MPIC_USES_DCR)
-		_mpic_map_dcr(mpic, rb, offset, size);
+		_mpic_map_dcr(mpic, node, rb, offset, size);
 	else
 		_mpic_map_mmio(mpic, phys_addr, rb, offset, size);
 }
 #else /* CONFIG_PPC_DCR */
-#define mpic_map(m,p,b,o,s)	_mpic_map_mmio(m,p,b,o,s)
+#define mpic_map(m,n,p,b,o,s)	_mpic_map_mmio(m,p,b,o,s)
 #endif /* !CONFIG_PPC_DCR */
 
 
@@ -1150,8 +1151,8 @@ struct mpic * __init mpic_alloc(struct d
 	}
 
 	/* Map the global registers */
-	mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
-	mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
+	mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
+	mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
 
 	/* Reset */
 	if (flags & MPIC_WANTS_RESET) {
@@ -1192,7 +1193,7 @@ struct mpic * __init mpic_alloc(struct d
 
 	/* Map the per-CPU registers */
 	for (i = 0; i < mpic->num_cpus; i++) {
-		mpic_map(mpic, paddr, &mpic->cpuregs[i],
+		mpic_map(mpic, node, paddr, &mpic->cpuregs[i],
 			 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
 			 0x1000);
 	}
@@ -1200,7 +1201,7 @@ struct mpic * __init mpic_alloc(struct d
 	/* Initialize main ISU if none provided */
 	if (mpic->isu_size == 0) {
 		mpic->isu_size = mpic->num_sources;
-		mpic_map(mpic, paddr, &mpic->isus[0],
+		mpic_map(mpic, node, paddr, &mpic->isus[0],
 			 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
 	}
 	mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -1254,8 +1255,10 @@ void __init mpic_assign_isu(struct mpic
 
 	BUG_ON(isu_num >= MPIC_MAX_ISU);
 
-	mpic_map(mpic, paddr, &mpic->isus[isu_num], 0,
+	mpic_map(mpic, mpic->irqhost->of_node,
+		 paddr, &mpic->isus[isu_num], 0,
 		 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
+
 	if ((isu_first + mpic->isu_size) > mpic->num_sources)
 		mpic->num_sources = isu_first + mpic->isu_size;
 }
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/include/asm/pgtable_64.h linux-libre-2.6.30.10-gnu1/arch/sparc/include/asm/pgtable_64.h
--- linux-libre-2.6.30-gnu1/arch/sparc/include/asm/pgtable_64.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/include/asm/pgtable_64.h	2009-12-04 01:00:07.000000000 -0500
@@ -726,11 +726,17 @@ extern unsigned long pte_file(pte_t);
 extern pte_t pgoff_to_pte(unsigned long);
 #define PTE_FILE_MAX_BITS	(64UL - PAGE_SHIFT - 1UL)
 
-extern unsigned long *sparc64_valid_addr_bitmap;
+extern unsigned long sparc64_valid_addr_bitmap[];
 
 /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
-#define kern_addr_valid(addr)	\
-	(test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
+static inline bool kern_addr_valid(unsigned long addr)
+{
+	unsigned long paddr = __pa(addr);
+
+	if ((paddr >> 41UL) != 0UL)
+		return false;
+	return test_bit(paddr >> 22, sparc64_valid_addr_bitmap);
+}
 
 extern int page_in_phys_avail(unsigned long paddr);
 
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_64.c linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/irq_64.c
--- linux-libre-2.6.30-gnu1/arch/sparc/kernel/irq_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/irq_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -902,7 +902,7 @@ void notrace init_irqwork_curcpu(void)
  * Therefore you cannot make any OBP calls, not even prom_printf,
  * from these two routines.
  */
-static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
+static void __cpuinit notrace register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
 {
 	unsigned long num_entries = (qmask + 1) / 64;
 	unsigned long status;
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/kernel/ktlb.S linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/ktlb.S
--- linux-libre-2.6.30-gnu1/arch/sparc/kernel/ktlb.S	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/ktlb.S	2009-12-04 01:00:07.000000000 -0500
@@ -151,12 +151,46 @@ kvmap_dtlb_4v:
 	 * Must preserve %g1 and %g6 (TAG).
 	 */
 kvmap_dtlb_tsb4m_miss:
-	sethi		%hi(kpte_linear_bitmap), %g2
-	or		%g2, %lo(kpte_linear_bitmap), %g2
+	/* Clear the PAGE_OFFSET top virtual bits, shift
+	 * down to get PFN, and make sure PFN is in range.
+	 */
+	sllx		%g4, 21, %g5
 
-	/* Clear the PAGE_OFFSET top virtual bits, then shift
-	 * down to get a 256MB physical address index.
+	/* Check to see if we know about valid memory at the 4MB
+	 * chunk this physical address will reside within.
 	 */
+	srlx		%g5, 21 + 41, %g2
+	brnz,pn		%g2, kvmap_dtlb_longpath
+	 nop
+
+	/* This unconditional branch and delay-slot nop gets patched
+	 * by the sethi sequence once the bitmap is properly setup.
+	 */
+	.globl		valid_addr_bitmap_insn
+valid_addr_bitmap_insn:
+	ba,pt		%xcc, 2f
+	 nop
+	.subsection	2
+	.globl		valid_addr_bitmap_patch
+valid_addr_bitmap_patch:
+	sethi		%hi(sparc64_valid_addr_bitmap), %g7
+	or		%g7, %lo(sparc64_valid_addr_bitmap), %g7
+	.previous
+
+	srlx		%g5, 21 + 22, %g2
+	srlx		%g2, 6, %g5
+	and		%g2, 63, %g2
+	sllx		%g5, 3, %g5
+	ldx		[%g7 + %g5], %g5
+	mov		1, %g7
+	sllx		%g7, %g2, %g7
+	andcc		%g5, %g7, %g0
+	be,pn		%xcc, kvmap_dtlb_longpath
+
+2:	 sethi		%hi(kpte_linear_bitmap), %g2
+	or		%g2, %lo(kpte_linear_bitmap), %g2
+
+	/* Get the 256MB physical address index. */
 	sllx		%g4, 21, %g5
 	mov		1, %g7
 	srlx		%g5, 21 + 28, %g5
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/kernel/nmi.c linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/nmi.c
--- linux-libre-2.6.30-gnu1/arch/sparc/kernel/nmi.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/nmi.c	2009-12-04 01:00:07.000000000 -0500
@@ -103,7 +103,7 @@ notrace __kprobes void perfctr_irq(int i
 	}
 	if (!touched && __get_cpu_var(last_irq_sum) == sum) {
 		local_inc(&__get_cpu_var(alert_counter));
-		if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz)
+		if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz)
 			die_nmi("BUG: NMI Watchdog detected LOCKUP",
 				regs, panic_on_timeout);
 	} else {
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/kernel/sys32.S linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/sys32.S
--- linux-libre-2.6.30-gnu1/arch/sparc/kernel/sys32.S	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/kernel/sys32.S	2009-12-04 01:00:07.000000000 -0500
@@ -134,7 +134,7 @@ SIGN1(sys32_getpeername, sys_getpeername
 SIGN1(sys32_getsockname, sys_getsockname, %o0)
 SIGN2(sys32_ioprio_get, sys_ioprio_get, %o0, %o1)
 SIGN3(sys32_ioprio_set, sys_ioprio_set, %o0, %o1, %o2)
-SIGN2(sys32_splice, sys_splice, %o0, %o1)
+SIGN2(sys32_splice, sys_splice, %o0, %o2)
 SIGN2(sys32_sync_file_range, compat_sync_file_range, %o0, %o5)
 SIGN2(sys32_tee, sys_tee, %o0, %o1)
 SIGN1(sys32_vmsplice, compat_sys_vmsplice, %o0)
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.c linux-libre-2.6.30.10-gnu1/arch/sparc/mm/init_64.c
--- linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/mm/init_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -145,7 +145,8 @@ static void __init read_obp_memory(const
 	     cmp_p64, NULL);
 }
 
-unsigned long *sparc64_valid_addr_bitmap __read_mostly;
+unsigned long sparc64_valid_addr_bitmap[VALID_ADDR_BITMAP_BYTES /
+					sizeof(unsigned long)];
 EXPORT_SYMBOL(sparc64_valid_addr_bitmap);
 
 /* Kernel physical address base and size in bytes.  */
@@ -1876,7 +1877,7 @@ static int pavail_rescan_ents __initdata
  * memory list again, and make sure it provides at least as much
  * memory as 'pavail' does.
  */
-static void __init setup_valid_addr_bitmap_from_pavail(void)
+static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap)
 {
 	int i;
 
@@ -1899,8 +1900,7 @@ static void __init setup_valid_addr_bitm
 
 				if (new_start <= old_start &&
 				    new_end >= (old_start + PAGE_SIZE)) {
-					set_bit(old_start >> 22,
-						sparc64_valid_addr_bitmap);
+					set_bit(old_start >> 22, bitmap);
 					goto do_next_page;
 				}
 			}
@@ -1921,20 +1921,21 @@ static void __init setup_valid_addr_bitm
 	}
 }
 
+static void __init patch_tlb_miss_handler_bitmap(void)
+{
+	extern unsigned int valid_addr_bitmap_insn[];
+	extern unsigned int valid_addr_bitmap_patch[];
+
+	valid_addr_bitmap_insn[1] = valid_addr_bitmap_patch[1];
+	mb();
+	valid_addr_bitmap_insn[0] = valid_addr_bitmap_patch[0];
+	flushi(&valid_addr_bitmap_insn[0]);
+}
+
 void __init mem_init(void)
 {
 	unsigned long codepages, datapages, initpages;
 	unsigned long addr, last;
-	int i;
-
-	i = last_valid_pfn >> ((22 - PAGE_SHIFT) + 6);
-	i += 1;
-	sparc64_valid_addr_bitmap = (unsigned long *) alloc_bootmem(i << 3);
-	if (sparc64_valid_addr_bitmap == NULL) {
-		prom_printf("mem_init: Cannot alloc valid_addr_bitmap.\n");
-		prom_halt();
-	}
-	memset(sparc64_valid_addr_bitmap, 0, i << 3);
 
 	addr = PAGE_OFFSET + kern_base;
 	last = PAGE_ALIGN(kern_size) + addr;
@@ -1943,15 +1944,19 @@ void __init mem_init(void)
 		addr += PAGE_SIZE;
 	}
 
-	setup_valid_addr_bitmap_from_pavail();
+	setup_valid_addr_bitmap_from_pavail(sparc64_valid_addr_bitmap);
+	patch_tlb_miss_handler_bitmap();
 
 	high_memory = __va(last_valid_pfn << PAGE_SHIFT);
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
-	for_each_online_node(i) {
-		if (NODE_DATA(i)->node_spanned_pages != 0) {
-			totalram_pages +=
-				free_all_bootmem_node(NODE_DATA(i));
+	{
+		int i;
+		for_each_online_node(i) {
+			if (NODE_DATA(i)->node_spanned_pages != 0) {
+				totalram_pages +=
+					free_all_bootmem_node(NODE_DATA(i));
+			}
 		}
 	}
 #else
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.h linux-libre-2.6.30.10-gnu1/arch/sparc/mm/init_64.h
--- linux-libre-2.6.30-gnu1/arch/sparc/mm/init_64.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/mm/init_64.h	2009-12-04 01:00:07.000000000 -0500
@@ -5,10 +5,13 @@
  * marked non-static so that assembler code can get at them.
  */
 
-#define MAX_PHYS_ADDRESS	(1UL << 42UL)
-#define KPTE_BITMAP_CHUNK_SZ	(256UL * 1024UL * 1024UL)
+#define MAX_PHYS_ADDRESS	(1UL << 41UL)
+#define KPTE_BITMAP_CHUNK_SZ		(256UL * 1024UL * 1024UL)
 #define KPTE_BITMAP_BYTES	\
 	((MAX_PHYS_ADDRESS / KPTE_BITMAP_CHUNK_SZ) / 8)
+#define VALID_ADDR_BITMAP_CHUNK_SZ	(4UL * 1024UL * 1024UL)
+#define VALID_ADDR_BITMAP_BYTES	\
+	((MAX_PHYS_ADDRESS / VALID_ADDR_BITMAP_CHUNK_SZ) / 8)
 
 extern unsigned long kern_linear_pte_xor[2];
 extern unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)];
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/prom/misc_64.c linux-libre-2.6.30.10-gnu1/arch/sparc/prom/misc_64.c
--- linux-libre-2.6.30-gnu1/arch/sparc/prom/misc_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/prom/misc_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -88,7 +88,7 @@ void prom_cmdline(void)
 /* Drop into the prom, but completely terminate the program.
  * No chance of continuing.
  */
-void prom_halt(void)
+void notrace prom_halt(void)
 {
 #ifdef CONFIG_SUN_LDOMS
 	if (ldom_domaining_enabled)
diff -druNp linux-libre-2.6.30-gnu1/arch/sparc/prom/printf.c linux-libre-2.6.30.10-gnu1/arch/sparc/prom/printf.c
--- linux-libre-2.6.30-gnu1/arch/sparc/prom/printf.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/sparc/prom/printf.c	2009-12-04 01:00:07.000000000 -0500
@@ -14,14 +14,14 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/compiler.h>
 
 #include <asm/openprom.h>
 #include <asm/oplib.h>
 
 static char ppbuf[1024];
 
-void
-prom_write(const char *buf, unsigned int n)
+void notrace prom_write(const char *buf, unsigned int n)
 {
 	char ch;
 
@@ -33,8 +33,7 @@ prom_write(const char *buf, unsigned int
 	}
 }
 
-void
-prom_printf(const char *fmt, ...)
+void notrace prom_printf(const char *fmt, ...)
 {
 	va_list args;
 	int i;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/boot/video-vga.c linux-libre-2.6.30.10-gnu1/arch/x86/boot/video-vga.c
--- linux-libre-2.6.30-gnu1/arch/x86/boot/video-vga.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/boot/video-vga.c	2009-12-04 01:00:07.000000000 -0500
@@ -45,8 +45,10 @@ static u8 vga_set_basic_mode(void)
 
 #ifdef CONFIG_VIDEO_400_HACK
 	if (adapter >= ADAPTER_VGA) {
+		ax = 0x1202;
 		asm volatile(INT10
-			     : : "a" (0x1202), "b" (0x0030)
+			     : "+a" (ax)
+			     : "b" (0x0030)
 			     : "ecx", "edx", "esi", "edi");
 	}
 #endif
@@ -81,44 +83,59 @@ static u8 vga_set_basic_mode(void)
 
 static void vga_set_8font(void)
 {
+	u16 ax;
+
 	/* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
 
 	/* Set 8x8 font */
-	asm volatile(INT10 : : "a" (0x1112), "b" (0));
+	ax = 0x1112;
+	asm volatile(INT10 : "+a" (ax) : "b" (0));
 
 	/* Use alternate print screen */
-	asm volatile(INT10 : : "a" (0x1200), "b" (0x20));
+	ax = 0x1200;
+	asm volatile(INT10 : "+a" (ax) : "b" (0x20));
 
 	/* Turn off cursor emulation */
-	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+	ax = 0x1201;
+	asm volatile(INT10 : "+a" (ax) : "b" (0x34));
 
 	/* Cursor is scan lines 6-7 */
-	asm volatile(INT10 : : "a" (0x0100), "c" (0x0607));
+	ax = 0x0100;
+	asm volatile(INT10 : "+a" (ax) : "c" (0x0607));
 }
 
 static void vga_set_14font(void)
 {
+	u16 ax;
+
 	/* Set 9x14 font - 80x28 on VGA */
 
 	/* Set 9x14 font */
-	asm volatile(INT10 : : "a" (0x1111), "b" (0));
+	ax = 0x1111;
+	asm volatile(INT10 : "+a" (ax) : "b" (0));
 
 	/* Turn off cursor emulation */
-	asm volatile(INT10 : : "a" (0x1201), "b" (0x34));
+	ax = 0x1201;
+	asm volatile(INT10 : "+a" (ax) : "b" (0x34));
 
 	/* Cursor is scan lines 11-12 */
-	asm volatile(INT10 : : "a" (0x0100), "c" (0x0b0c));
+	ax = 0x0100;
+	asm volatile(INT10 : "+a" (ax) : "c" (0x0b0c));
 }
 
 static void vga_set_80x43(void)
 {
+	u16 ax;
+
 	/* Set 80x43 mode on VGA (not EGA) */
 
 	/* Set 350 scans */
-	asm volatile(INT10 : : "a" (0x1201), "b" (0x30));
+	ax = 0x1201;
+	asm volatile(INT10 : "+a" (ax) : "b" (0x30));
 
 	/* Reset video mode */
-	asm volatile(INT10 : : "a" (0x0003));
+	ax = 0x0003;
+	asm volatile(INT10 : "+a" (ax));
 
 	vga_set_8font();
 }
@@ -225,7 +242,7 @@ static int vga_set_mode(struct mode_info
  */
 static int vga_probe(void)
 {
-	u16 ega_bx;
+	u16 ax, ega_bx;
 
 	static const char *card_name[] = {
 		"CGA/MDA/HGC", "EGA", "VGA"
@@ -242,9 +259,10 @@ static int vga_probe(void)
 	};
 	u8 vga_flag;
 
+	ax = 0x1200;
 	asm(INT10
-	    : "=b" (ega_bx)
-	    : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
+	    : "+a" (ax), "=b" (ega_bx)
+	    : "b" (0x10) /* Check EGA/VGA */
 	    : "ecx", "edx", "esi", "edi");
 
 #ifndef _WAKEUP
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_asm.S linux-libre-2.6.30.10-gnu1/arch/x86/crypto/aesni-intel_asm.S
--- linux-libre-2.6.30-gnu1/arch/x86/crypto/aesni-intel_asm.S	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/crypto/aesni-intel_asm.S	2009-12-04 01:00:07.000000000 -0500
@@ -845,7 +845,7 @@ ENTRY(aesni_cbc_enc)
  */
 ENTRY(aesni_cbc_dec)
 	cmp $16, LEN
-	jb .Lcbc_dec_ret
+	jb .Lcbc_dec_just_ret
 	mov 480(KEYP), KLEN
 	add $240, KEYP
 	movups (IVP), IV
@@ -891,6 +891,7 @@ ENTRY(aesni_cbc_dec)
 	add $16, OUTP
 	cmp $16, LEN
 	jge .Lcbc_dec_loop1
-	movups IV, (IVP)
 .Lcbc_dec_ret:
+	movups IV, (IVP)
+.Lcbc_dec_just_ret:
 	ret
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/apic.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/apic.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/apic.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/apic.h	2009-12-04 01:00:07.000000000 -0500
@@ -410,7 +410,7 @@ static inline unsigned default_get_apic_
 {
 	unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
 
-	if (APIC_XAPIC(ver))
+	if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
 		return (x >> 24) & 0xFF;
 	else
 		return (x >> 24) & 0x0F;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpufeature.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/cpufeature.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/cpufeature.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/cpufeature.h	2009-12-04 01:00:07.000000000 -0500
@@ -94,6 +94,7 @@
 #define X86_FEATURE_TSC_RELIABLE (3*32+23) /* TSC is known to be reliable */
 #define X86_FEATURE_NONSTOP_TSC	(3*32+24) /* TSC does not stop in C states */
 #define X86_FEATURE_CLFLUSH_MONITOR (3*32+25) /* "" clflush reqd with monitor */
+#define X86_FEATURE_EXTD_APICID	(3*32+26) /* has extended APICID (8 bits) */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3	(4*32+ 0) /* "pni" SSE-3 */
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/fixmap.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/fixmap.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/fixmap.h	2009-12-04 01:00:07.000000000 -0500
@@ -111,12 +111,9 @@ enum fixed_addresses {
 #ifdef CONFIG_PARAVIRT
 	FIX_PARAVIRT_BOOTMAP,
 #endif
-	FIX_TEXT_POKE0,	/* reserve 2 pages for text_poke() */
-	FIX_TEXT_POKE1,
+	FIX_TEXT_POKE1,	/* reserve 2 pages for text_poke() */
+	FIX_TEXT_POKE0, /* first page is last, because allocation is backward */
 	__end_of_permanent_fixed_addresses,
-#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
-	FIX_OHCI1394_BASE,
-#endif
 	/*
 	 * 256 temporary boot-time mappings, used by early_ioremap(),
 	 * before ioremap() is functional.
@@ -129,6 +126,9 @@ enum fixed_addresses {
 	FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
 			(__end_of_permanent_fixed_addresses & 255),
 	FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_SLOTS - 1,
+#ifdef CONFIG_PROVIDE_OHCI1394_DMA_INIT
+	FIX_OHCI1394_BASE,
+#endif
 #ifdef CONFIG_X86_32
 	FIX_WP_TEST,
 #endif
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_apic.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/io_apic.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/io_apic.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/io_apic.h	2009-12-04 01:00:07.000000000 -0500
@@ -160,6 +160,7 @@ extern int io_apic_set_pci_routing(int i
 
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_init_mappings(void);
+extern void ioapic_insert_resources(void);
 
 #ifdef CONFIG_X86_64
 extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
@@ -183,6 +184,7 @@ extern void ioapic_write_entry(int apic,
 #define io_apic_assign_pci_irqs 0
 static const int timer_through_8259 = 0;
 static inline void ioapic_init_mappings(void)	{ }
+static inline void ioapic_insert_resources(void) { }
 
 static inline void probe_nr_irqs_gsi(void)	{ }
 #endif
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/irqflags.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/irqflags.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/irqflags.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/irqflags.h	2009-12-04 01:00:07.000000000 -0500
@@ -12,9 +12,15 @@ static inline unsigned long native_save_
 {
 	unsigned long flags;
 
+	/*
+	 * Note: this needs to be "=r" not "=rm", because we have the
+	 * stack offset from what gcc expects at the time the "pop" is
+	 * executed, and so a memory reference with respect to the stack
+	 * would end up using the wrong address.
+	 */
 	asm volatile("# __raw_save_flags\n\t"
 		     "pushf ; pop %0"
-		     : "=g" (flags)
+		     : "=r" (flags)
 		     : /* no input */
 		     : "memory");
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_host.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/kvm_host.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/kvm_host.h	2009-12-04 01:00:07.000000000 -0500
@@ -185,6 +185,7 @@ union kvm_mmu_page_role {
 		unsigned access:3;
 		unsigned invalid:1;
 		unsigned cr4_pge:1;
+		unsigned nxe:1;
 	};
 };
 
@@ -371,6 +372,8 @@ struct kvm_vcpu_arch {
 	unsigned long dr6;
 	unsigned long dr7;
 	unsigned long eff_db[KVM_NR_DB_REGS];
+
+	u32 exit_reason;
 };
 
 struct kvm_mem_alias {
@@ -511,6 +514,8 @@ struct kvm_x86_ops {
 	void (*run)(struct kvm_vcpu *vcpu, struct kvm_run *run);
 	int (*handle_exit)(struct kvm_run *run, struct kvm_vcpu *vcpu);
 	void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
+	void (*set_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
+	u32 (*get_interrupt_shadow)(struct kvm_vcpu *vcpu, int mask);
 	void (*patch_hypercall)(struct kvm_vcpu *vcpu,
 				unsigned char *hypercall_addr);
 	int (*get_irq)(struct kvm_vcpu *vcpu);
@@ -615,6 +620,7 @@ void kvm_queue_exception(struct kvm_vcpu
 void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
 void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
 			   u32 error_code);
+bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl);
 
 int kvm_pic_set_irq(void *opaque, int irq, int level);
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_x86_emulate.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/kvm_x86_emulate.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/kvm_x86_emulate.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/kvm_x86_emulate.h	2009-12-04 01:00:07.000000000 -0500
@@ -143,6 +143,9 @@ struct decode_cache {
 	struct fetch_cache fetch;
 };
 
+#define X86_SHADOW_INT_MOV_SS  1
+#define X86_SHADOW_INT_STI     2
+
 struct x86_emulate_ctxt {
 	/* Register state before/after emulation. */
 	struct kvm_vcpu *vcpu;
@@ -152,6 +155,9 @@ struct x86_emulate_ctxt {
 	int mode;
 	u32 cs_base;
 
+	/* interruptibility state, as a result of execution of STI or MOV SS */
+	int interruptibility;
+
 	/* decode cache */
 	struct decode_cache decode;
 };
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/mce.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/mce.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/mce.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/mce.h	2009-12-04 01:00:07.000000000 -0500
@@ -153,5 +153,7 @@ extern void mcheck_init(struct cpuinfo_x
 
 extern void (*mce_threshold_vector)(void);
 
+extern void (*machine_check_vector)(struct pt_regs *, long error_code);
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_X86_MCE_H */
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/pci.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/pci.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/pci.h	2009-12-04 01:00:07.000000000 -0500
@@ -91,7 +91,7 @@ extern void pci_iommu_alloc(void);
 
 #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_DMA_API_DEBUG)
+#if defined(CONFIG_X86_64) || defined(CONFIG_DMAR) || defined(CONFIG_DMA_API_DEBUG)
 
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)       \
 	        dma_addr_t ADDR_NAME;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/processor.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/processor.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/processor.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/processor.h	2009-12-04 01:00:07.000000000 -0500
@@ -402,7 +402,17 @@ extern unsigned long kernel_eflags;
 extern asmlinkage void ignore_sysret(void);
 #else	/* X86_64 */
 #ifdef CONFIG_CC_STACKPROTECTOR
-DECLARE_PER_CPU(unsigned long, stack_canary);
+/*
+ * Make sure stack canary segment base is cached-aligned:
+ *   "For Intel Atom processors, avoid non zero segment base address
+ *    that is not aligned to cache line boundary at all cost."
+ * (Optim Ref Manual Assembly/Compiler Coding Rule 15.)
+ */
+struct stack_canary {
+	char __pad[20];		/* canary at %gs:20 */
+	unsigned long canary;
+};
+DECLARE_PER_CPU(struct stack_canary, stack_canary) ____cacheline_aligned;
 #endif
 #endif	/* X86_64 */
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/stackprotector.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/stackprotector.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/stackprotector.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/stackprotector.h	2009-12-04 01:00:07.000000000 -0500
@@ -78,14 +78,14 @@ static __always_inline void boot_init_st
 #ifdef CONFIG_X86_64
 	percpu_write(irq_stack_union.stack_canary, canary);
 #else
-	percpu_write(stack_canary, canary);
+	percpu_write(stack_canary.canary, canary);
 #endif
 }
 
 static inline void setup_stack_canary_segment(int cpu)
 {
 #ifdef CONFIG_X86_32
-	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu) - 20;
+	unsigned long canary = (unsigned long)&per_cpu(stack_canary, cpu);
 	struct desc_struct *gdt_table = get_cpu_gdt_table(cpu);
 	struct desc_struct desc;
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/system.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/system.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/system.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/system.h	2009-12-04 01:00:07.000000000 -0500
@@ -31,7 +31,7 @@ void __switch_to_xtra(struct task_struct
 	"movl %P[task_canary](%[next]), %%ebx\n\t"			\
 	"movl %%ebx, "__percpu_arg([stack_canary])"\n\t"
 #define __switch_canary_oparam						\
-	, [stack_canary] "=m" (per_cpu_var(stack_canary))
+	, [stack_canary] "=m" (per_cpu_var(stack_canary.canary))
 #define __switch_canary_iparam						\
 	, [task_canary] "i" (offsetof(struct task_struct, stack_canary))
 #else	/* CC_STACKPROTECTOR */
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess_64.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uaccess_64.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess_64.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uaccess_64.h	2009-12-04 01:00:07.000000000 -0500
@@ -88,11 +88,11 @@ int __copy_to_user(void __user *dst, con
 			      ret, "l", "k", "ir", 4);
 		return ret;
 	case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
-			      ret, "q", "", "ir", 8);
+			      ret, "q", "", "er", 8);
 		return ret;
 	case 10:
 		__put_user_asm(*(u64 *)src, (u64 __user *)dst,
-			       ret, "q", "", "ir", 10);
+			       ret, "q", "", "er", 10);
 		if (unlikely(ret))
 			return ret;
 		asm("":::"memory");
@@ -101,12 +101,12 @@ int __copy_to_user(void __user *dst, con
 		return ret;
 	case 16:
 		__put_user_asm(*(u64 *)src, (u64 __user *)dst,
-			       ret, "q", "", "ir", 16);
+			       ret, "q", "", "er", 16);
 		if (unlikely(ret))
 			return ret;
 		asm("":::"memory");
 		__put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
-			       ret, "q", "", "ir", 8);
+			       ret, "q", "", "er", 8);
 		return ret;
 	default:
 		return copy_user_generic((__force void *)dst, src, size);
@@ -157,7 +157,7 @@ int __copy_in_user(void __user *dst, con
 			       ret, "q", "", "=r", 8);
 		if (likely(!ret))
 			__put_user_asm(tmp, (u64 __user *)dst,
-				       ret, "q", "", "ir", 8);
+				       ret, "q", "", "er", 8);
 		return ret;
 	}
 	default:
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uaccess.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/uaccess.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uaccess.h	2009-12-04 01:00:07.000000000 -0500
@@ -212,9 +212,9 @@ extern int __get_user_bad(void);
 		     : "A" ((typeof(*(ptr)))(x)), "c" (ptr) : "ebx")
 #else
 #define __put_user_asm_u64(x, ptr, retval, errret) \
-	__put_user_asm(x, ptr, retval, "q", "", "Zr", errret)
+	__put_user_asm(x, ptr, retval, "q", "", "er", errret)
 #define __put_user_asm_ex_u64(x, addr)	\
-	__put_user_asm_ex(x, addr, "q", "", "Zr")
+	__put_user_asm_ex(x, addr, "q", "", "er")
 #define __put_user_x8(x, ptr, __ret_pu) __put_user_x(8, x, ptr, __ret_pu)
 #endif
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_bau.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uv/uv_bau.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_bau.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uv/uv_bau.h	2009-12-04 01:00:07.000000000 -0500
@@ -37,7 +37,7 @@
 #define UV_CPUS_PER_ACT_STATUS		32
 #define UV_ACT_STATUS_MASK		0x3
 #define UV_ACT_STATUS_SIZE		2
-#define UV_ACTIVATION_DESCRIPTOR_SIZE	32
+#define UV_ADP_SIZE			32
 #define UV_DISTRIBUTION_SIZE		256
 #define UV_SW_ACK_NPENDING		8
 #define UV_NET_ENDPOINT_INTD		0x38
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_hub.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uv/uv_hub.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/uv/uv_hub.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/uv/uv_hub.h	2009-12-04 01:00:07.000000000 -0500
@@ -133,6 +133,7 @@ struct uv_scir_s {
 struct uv_hub_info_s {
 	unsigned long		global_mmr_base;
 	unsigned long		gpa_mask;
+	unsigned int		gnode_extra;
 	unsigned long		gnode_upper;
 	unsigned long		lowmem_remap_top;
 	unsigned long		lowmem_remap_base;
@@ -159,7 +160,8 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __
  * 		p -  PNODE (local part of nsids, right shifted 1)
  */
 #define UV_NASID_TO_PNODE(n)		(((n) >> 1) & uv_hub_info->pnode_mask)
-#define UV_PNODE_TO_NASID(p)		(((p) << 1) | uv_hub_info->gnode_upper)
+#define UV_PNODE_TO_GNODE(p)		((p) |uv_hub_info->gnode_extra)
+#define UV_PNODE_TO_NASID(p)		(UV_PNODE_TO_GNODE(p) << 1)
 
 #define UV_LOCAL_MMR_BASE		0xf4000000UL
 #define UV_GLOBAL_MMR32_BASE		0xf8000000UL
@@ -173,7 +175,7 @@ DECLARE_PER_CPU(struct uv_hub_info_s, __
 #define UV_GLOBAL_MMR32_PNODE_BITS(p)	((p) << (UV_GLOBAL_MMR32_PNODE_SHIFT))
 
 #define UV_GLOBAL_MMR64_PNODE_BITS(p)					\
-	((unsigned long)(p) << UV_GLOBAL_MMR64_PNODE_SHIFT)
+	((unsigned long)(UV_PNODE_TO_GNODE(p)) << UV_GLOBAL_MMR64_PNODE_SHIFT)
 
 #define UV_APIC_PNODE_SHIFT	6
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/include/asm/vmx.h linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/vmx.h
--- linux-libre-2.6.30-gnu1/arch/x86/include/asm/vmx.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/include/asm/vmx.h	2009-12-04 01:00:07.000000000 -0500
@@ -247,6 +247,7 @@ enum vmcs_field {
 #define EXIT_REASON_MSR_READ            31
 #define EXIT_REASON_MSR_WRITE           32
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
+#define EXIT_REASON_MCE_DURING_VMENTRY	 41
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
 #define EXIT_REASON_APIC_ACCESS         44
 #define EXIT_REASON_EPT_VIOLATION       48
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/es7000_32.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/es7000_32.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/es7000_32.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/es7000_32.c	2009-12-04 01:00:07.000000000 -0500
@@ -167,7 +167,7 @@ static int es7000_apic_is_cluster(void)
 {
 	/* MPENTIUMIII */
 	if (boot_cpu_data.x86 == 6 &&
-	    (boot_cpu_data.x86_model >= 7 || boot_cpu_data.x86_model <= 11))
+	    (boot_cpu_data.x86_model >= 7 && boot_cpu_data.x86_model <= 11))
 		return 1;
 
 	return 0;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/io_apic.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/io_apic.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/io_apic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/io_apic.c	2009-12-04 01:00:07.000000000 -0500
@@ -4182,28 +4182,20 @@ fake_ioapic_page:
 	}
 }
 
-static int __init ioapic_insert_resources(void)
+void __init ioapic_insert_resources(void)
 {
 	int i;
 	struct resource *r = ioapic_resources;
 
 	if (!r) {
-		if (nr_ioapics > 0) {
+		if (nr_ioapics > 0)
 			printk(KERN_ERR
 				"IO APIC resources couldn't be allocated.\n");
-			return -1;
-		}
-		return 0;
+		return;
 	}
 
 	for (i = 0; i < nr_ioapics; i++) {
 		insert_resource(&iomem_resource, r);
 		r++;
 	}
-
-	return 0;
 }
-
-/* Insert the IO APIC resources after PCI initialization has occured to handle
- * IO APICS that are mapped in on a BAR in PCI space. */
-late_initcall(ioapic_insert_resources);
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/ipi.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/ipi.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/ipi.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/ipi.c	2009-12-04 01:00:07.000000000 -0500
@@ -106,6 +106,9 @@ void default_send_IPI_mask_logical(const
 	unsigned long mask = cpumask_bits(cpumask)[0];
 	unsigned long flags;
 
+	if (WARN_ONCE(!mask, "empty IPI mask"))
+		return;
+
 	local_irq_save(flags);
 	WARN_ON(mask & ~cpumask_bits(cpu_online_mask)[0]);
 	__default_send_IPI_dest_field(mask, vector, apic->dest_logical);
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/apic/x2apic_uv_x.c	2009-12-04 01:00:07.000000000 -0500
@@ -562,7 +562,7 @@ void __init uv_system_init(void)
 	union uvh_node_id_u node_id;
 	unsigned long gnode_upper, lowmem_redir_base, lowmem_redir_size;
 	int bytes, nid, cpu, lcpu, pnode, blade, i, j, m_val, n_val;
-	int max_pnode = 0;
+	int gnode_extra, max_pnode = 0;
 	unsigned long mmr_base, present, paddr;
 	unsigned short pnode_mask;
 
@@ -574,6 +574,13 @@ void __init uv_system_init(void)
 	mmr_base =
 	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
 	    ~UV_MMR_ENABLE;
+	pnode_mask = (1 << n_val) - 1;
+	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
+	gnode_extra = (node_id.s.node_id & ~((1 << n_val) - 1)) >> 1;
+	gnode_upper = ((unsigned long)gnode_extra  << m_val);
+	printk(KERN_DEBUG "UV: N %d, M %d, gnode_upper 0x%lx, gnode_extra 0x%x\n",
+			n_val, m_val, gnode_upper, gnode_extra);
+
 	printk(KERN_DEBUG "UV: global MMR base 0x%lx\n", mmr_base);
 
 	for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++)
@@ -607,11 +614,6 @@ void __init uv_system_init(void)
 		}
 	}
 
-	pnode_mask = (1 << n_val) - 1;
-	node_id.v = uv_read_local_mmr(UVH_NODE_ID);
-	gnode_upper = (((unsigned long)node_id.s.node_id) &
-		       ~((1 << n_val) - 1)) << m_val;
-
 	uv_bios_init();
 	uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
 			    &sn_coherency_id, &sn_region_size);
@@ -634,6 +636,7 @@ void __init uv_system_init(void)
 		uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
 		uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
 		uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
+		uv_cpu_hub_info(cpu)->gnode_extra = gnode_extra;
 		uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
 		uv_cpu_hub_info(cpu)->coherency_domain_number = sn_coherency_id;
 		uv_cpu_hub_info(cpu)->scir.offset = SCIR_LOCAL_MMR_BASE + lcpu;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/amd.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/amd.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/amd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/amd.c	2009-12-04 01:00:07.000000000 -0500
@@ -6,6 +6,7 @@
 #include <asm/processor.h>
 #include <asm/apic.h>
 #include <asm/cpu.h>
+#include <asm/pci-direct.h>
 
 #ifdef CONFIG_X86_64
 # include <asm/numa_64.h>
@@ -257,13 +258,15 @@ static void __cpuinit amd_detect_cmp(str
 {
 #ifdef CONFIG_X86_HT
 	unsigned bits;
+	int cpu = smp_processor_id();
 
 	bits = c->x86_coreid_bits;
-
 	/* Low order bits define the core id (index of core in socket) */
 	c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
 	/* Convert the initial APIC ID into the socket ID */
 	c->phys_proc_id = c->initial_apicid >> bits;
+	/* use socket ID also for last level cache */
+	per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
 #endif
 }
 
@@ -351,6 +354,15 @@ static void __cpuinit early_init_amd(str
 		    (c->x86_model == 8 && c->x86_mask >= 8))
 			set_cpu_cap(c, X86_FEATURE_K6_MTRR);
 #endif
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
+	/* check CPU config space for extended APIC ID */
+	if (cpu_has_apic && c->x86 >= 0xf) {
+		unsigned int val;
+		val = read_pci_config(0, 24, 0, 0x68);
+		if ((val & ((1 << 17) | (1 << 18))) == ((1 << 17) | (1 << 18)))
+			set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
+	}
+#endif
 }
 
 static void __cpuinit init_amd(struct cpuinfo_x86 *c)
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/common.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/common.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/common.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/common.c	2009-12-04 01:00:07.000000000 -0500
@@ -1033,7 +1033,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
 #else	/* CONFIG_X86_64 */
 
 #ifdef CONFIG_CC_STACKPROTECTOR
-DEFINE_PER_CPU(unsigned long, stack_canary);
+DEFINE_PER_CPU(struct stack_canary, stack_canary) ____cacheline_aligned;
 #endif
 
 /* Make sure %fs and %gs are initialized properly in idle threads */
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2009-12-04 01:00:07.000000000 -0500
@@ -618,9 +618,10 @@ static int check_pst_table(struct powern
 	return 0;
 }
 
-static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry)
+static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
+		unsigned int entry)
 {
-	data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
 }
 
 static void print_basics(struct powernow_k8_data *data)
@@ -926,13 +927,13 @@ static int fill_powernow_table_pstate(st
 					"bad value %d.\n", i, index);
 			printk(KERN_ERR PFX "Please report to BIOS "
 					"manufacturer\n");
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 		rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
 		if (!(hi & HW_PSTATE_VALID_MASK)) {
 			dprintk("invalid pstate %d, ignoring\n", index);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
@@ -982,7 +983,7 @@ static int fill_powernow_table_fidvid(st
 		/* verify frequency is OK */
 		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
 			dprintk("invalid freq %u kHz, ignoring\n", freq);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
@@ -990,7 +991,7 @@ static int fill_powernow_table_fidvid(st
 		 * BIOSs are using "off" to indicate invalid */
 		if (vid == VID_OFF) {
 			dprintk("invalid vid %u, ignoring\n", vid);
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 
@@ -1021,7 +1022,7 @@ static int fill_powernow_table_fidvid(st
 				(unsigned int)
 				(data->acpi_data.states[i].core_frequency
 				 * 1000));
-			invalidate_entry(data, i);
+			invalidate_entry(powernow_table, i);
 			continue;
 		}
 	}
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/mcheck/mce_32.c	2009-12-04 01:00:07.000000000 -0500
@@ -29,6 +29,7 @@ static void unexpected_machine_check(str
 
 /* Call the installed machine check handler for this CPU setup. */
 void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
+EXPORT_SYMBOL_GPL(machine_check_vector);
 
 /* This has to be run for each processor */
 void mcheck_init(struct cpuinfo_x86 *c)
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/cpu/mcheck/mce_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -420,6 +420,7 @@ void do_machine_check(struct pt_regs * r
  out2:
 	atomic_dec(&mce_entry);
 }
+EXPORT_SYMBOL_GPL(do_machine_check);
 
 #ifdef CONFIG_X86_MCE_INTEL
 /***
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/head_32.S linux-libre-2.6.30.10-gnu1/arch/x86/kernel/head_32.S
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/head_32.S	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/head_32.S	2009-12-04 01:00:07.000000000 -0500
@@ -442,7 +442,6 @@ is386:	movl $2,%ecx		# set MP
 	jne 1f
 	movl $per_cpu__gdt_page,%eax
 	movl $per_cpu__stack_canary,%ecx
-	subl $20, %ecx
 	movw %cx, 8 * GDT_ENTRY_STACK_CANARY + 2(%eax)
 	shrl $16, %ecx
 	movb %cl, 8 * GDT_ENTRY_STACK_CANARY + 4(%eax)
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/hpet.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/hpet.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/hpet.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/hpet.c	2009-12-04 01:00:07.000000000 -0500
@@ -510,7 +510,8 @@ static int hpet_setup_irq(struct hpet_de
 {
 
 	if (request_irq(dev->irq, hpet_interrupt_handler,
-			IRQF_DISABLED|IRQF_NOBALANCING, dev->name, dev))
+			IRQF_TIMER | IRQF_DISABLED | IRQF_NOBALANCING,
+			dev->name, dev))
 		return -1;
 
 	disable_irq(dev->irq);
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/kvmclock.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/kvmclock.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/kvmclock.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/kvmclock.c	2009-12-04 01:00:07.000000000 -0500
@@ -50,8 +50,8 @@ static unsigned long kvm_get_wallclock(v
 	struct timespec ts;
 	int low, high;
 
-	low = (int)__pa(&wall_clock);
-	high = ((u64)__pa(&wall_clock) >> 32);
+	low = (int)__pa_symbol(&wall_clock);
+	high = ((u64)__pa_symbol(&wall_clock) >> 32);
 	native_write_msr(MSR_KVM_WALL_CLOCK, low, high);
 
 	vcpu_time = &get_cpu_var(hv_clock);
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/mfgpt_32.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/mfgpt_32.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/mfgpt_32.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/mfgpt_32.c	2009-12-04 01:00:07.000000000 -0500
@@ -347,7 +347,7 @@ static irqreturn_t mfgpt_tick(int irq, v
 
 static struct irqaction mfgptirq  = {
 	.handler = mfgpt_tick,
-	.flags = IRQF_DISABLED | IRQF_NOBALANCING,
+	.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
 	.name = "mfgpt-timer"
 };
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-gart_64.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/pci-gart_64.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/pci-gart_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/pci-gart_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -688,8 +688,6 @@ static __init int init_k8_gatt(struct ag
 
 	agp_gatt_table = gatt;
 
-	enable_gart_translations();
-
 	error = sysdev_class_register(&gart_sysdev_class);
 	if (!error)
 		error = sysdev_register(&device_gart);
@@ -847,6 +845,14 @@ void __init gart_iommu_init(void)
 	wbinvd();
 
 	/*
+	 * Now all caches are flushed and we can safely enable
+	 * GART hardware.  Doing it early leaves the possibility
+	 * of stale cache entries that can lead to GART PTE
+	 * errors.
+	 */
+	enable_gart_translations();
+
+	/*
 	 * Try to workaround a bug (thanks to BenH):
 	 * Set unmapped entries to a scratch page instead of 0.
 	 * Any prefetches that hit unmapped entries won't get an bus abort
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/reboot.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/reboot.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/reboot.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/reboot.c	2009-12-04 01:00:07.000000000 -0500
@@ -192,6 +192,15 @@ static struct dmi_system_id __initdata r
 			DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
 		},
 	},
+	{   /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
+		.callback = set_bios_reboot,
+		.ident = "Dell OptiPlex 360",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"),
+			DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
+		},
+	},
 	{	/* Handle problems with rebooting on Dell 2400's */
 		.callback = set_bios_reboot,
 		.ident = "Dell PowerEdge 2400",
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/setup.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/setup.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/setup.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/setup.c	2009-12-04 01:00:07.000000000 -0500
@@ -293,15 +293,13 @@ static void __init reserve_brk(void)
 
 #ifdef CONFIG_BLK_DEV_INITRD
 
-#ifdef CONFIG_X86_32
-
 #define MAX_MAP_CHUNK	(NR_FIX_BTMAPS << PAGE_SHIFT)
 static void __init relocate_initrd(void)
 {
 
 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
-	u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
+	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 	u64 ramdisk_here;
 	unsigned long slop, clen, mapaddr;
 	char *p, *q;
@@ -357,14 +355,13 @@ static void __init relocate_initrd(void)
 		ramdisk_image, ramdisk_image + ramdisk_size - 1,
 		ramdisk_here, ramdisk_here + ramdisk_size - 1);
 }
-#endif
 
 static void __init reserve_initrd(void)
 {
 	u64 ramdisk_image = boot_params.hdr.ramdisk_image;
 	u64 ramdisk_size  = boot_params.hdr.ramdisk_size;
 	u64 ramdisk_end   = ramdisk_image + ramdisk_size;
-	u64 end_of_lowmem = max_low_pfn << PAGE_SHIFT;
+	u64 end_of_lowmem = max_low_pfn_mapped << PAGE_SHIFT;
 
 	if (!boot_params.hdr.type_of_loader ||
 	    !ramdisk_image || !ramdisk_size)
@@ -394,14 +391,8 @@ static void __init reserve_initrd(void)
 		return;
 	}
 
-#ifdef CONFIG_X86_32
 	relocate_initrd();
-#else
-	printk(KERN_ERR "initrd extends beyond end of memory "
-	       "(0x%08llx > 0x%08llx)\ndisabling initrd\n",
-	       ramdisk_end, end_of_lowmem);
-	initrd_start = 0;
-#endif
+
 	free_early(ramdisk_image, ramdisk_end);
 }
 #else
@@ -659,6 +650,19 @@ static struct dmi_system_id __initdata b
 			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies"),
 		},
 	},
+	{
+	/*
+	 * AMI BIOS with low memory corruption was found on Intel DG45ID board.
+	 * It hase different DMI_BIOS_VENDOR = "Intel Corp.", for now we will
+	 * match only DMI_BOARD_NAME and see if there is more bad products
+	 * with this vendor.
+	 */
+		.callback = dmi_low_memory_corruption,
+		.ident = "AMI BIOS",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "DG45ID"),
+		},
+	},
 #endif
 	{}
 };
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_uv.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/tlb_uv.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/tlb_uv.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/tlb_uv.c	2009-12-04 01:00:07.000000000 -0500
@@ -711,25 +711,31 @@ uv_activation_descriptor_init(int node,
 	unsigned long pa;
 	unsigned long m;
 	unsigned long n;
-	unsigned long mmr_image;
 	struct bau_desc *adp;
 	struct bau_desc *ad2;
 
-	adp = (struct bau_desc *)kmalloc_node(16384, GFP_KERNEL, node);
+	/*
+	 * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
+	 * per cpu; and up to 32 (UV_ADP_SIZE) cpu's per blade
+	 */
+	adp = (struct bau_desc *)kmalloc_node(sizeof(struct bau_desc)*
+		UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
 	BUG_ON(!adp);
 
 	pa = uv_gpa(adp); /* need the real nasid*/
 	n = pa >> uv_nshift;
 	m = pa & uv_mmask;
 
-	mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE);
-	if (mmr_image) {
-		uv_write_global_mmr64(pnode, (unsigned long)
-				      UVH_LB_BAU_SB_DESCRIPTOR_BASE,
-				      (n << UV_DESC_BASE_PNODE_SHIFT | m));
-	}
+	uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
+			      (n << UV_DESC_BASE_PNODE_SHIFT | m));
 
-	for (i = 0, ad2 = adp; i < UV_ACTIVATION_DESCRIPTOR_SIZE; i++, ad2++) {
+	/*
+	 * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each
+	 * cpu even though we only use the first one; one descriptor can
+	 * describe a broadcast to 256 nodes.
+	 */
+	for (i = 0, ad2 = adp; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
+		i++, ad2++) {
 		memset(ad2, 0, sizeof(struct bau_desc));
 		ad2->header.sw_ack_flag = 1;
 		/*
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/tsc.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/tsc.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/tsc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/tsc.c	2009-12-04 01:00:07.000000000 -0500
@@ -710,7 +710,16 @@ static cycle_t read_tsc(struct clocksour
 #ifdef CONFIG_X86_64
 static cycle_t __vsyscall_fn vread_tsc(void)
 {
-	cycle_t ret = (cycle_t)vget_cycles();
+	cycle_t ret;
+
+	/*
+	 * Surround the RDTSC by barriers, to make sure it's not
+	 * speculated to outside the seqlock critical section and
+	 * does not cause time warps:
+	 */
+	rdtsc_barrier();
+	ret = (cycle_t)vget_cycles();
+	rdtsc_barrier();
 
 	return ret >= __vsyscall_gtod_data.clock.cycle_last ?
 		ret : __vsyscall_gtod_data.clock.cycle_last;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/vm86_32.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vm86_32.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/vm86_32.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vm86_32.c	2009-12-04 01:00:07.000000000 -0500
@@ -287,10 +287,9 @@ static void do_sys_vm86(struct kernel_vm
 	info->regs.pt.ds = 0;
 	info->regs.pt.es = 0;
 	info->regs.pt.fs = 0;
-
-/* we are clearing gs later just before "jmp resume_userspace",
- * because it is not saved/restored.
- */
+#ifndef CONFIG_X86_32_LAZY_GS
+	info->regs.pt.gs = 0;
+#endif
 
 /*
  * The flags register is also special: we cannot trust that the user
@@ -343,7 +342,9 @@ static void do_sys_vm86(struct kernel_vm
 	__asm__ __volatile__(
 		"movl %0,%%esp\n\t"
 		"movl %1,%%ebp\n\t"
+#ifdef CONFIG_X86_32_LAZY_GS
 		"mov  %2, %%gs\n\t"
+#endif
 		"jmp resume_userspace"
 		: /* no outputs */
 		:"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0));
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/vmi_32.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vmi_32.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/vmi_32.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vmi_32.c	2009-12-04 01:00:07.000000000 -0500
@@ -441,7 +441,7 @@ vmi_startup_ipi_hook(int phys_apicid, un
 	ap.ds = __USER_DS;
 	ap.es = __USER_DS;
 	ap.fs = __KERNEL_PERCPU;
-	ap.gs = 0;
+	ap.gs = __KERNEL_STACK_CANARY;
 
 	ap.eflags = 0;
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kernel/vsyscall_64.c linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vsyscall_64.c
--- linux-libre-2.6.30-gnu1/arch/x86/kernel/vsyscall_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kernel/vsyscall_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -132,15 +132,7 @@ static __always_inline void do_vgettimeo
 			return;
 		}
 
-		/*
-		 * Surround the RDTSC by barriers, to make sure it's not
-		 * speculated to outside the seqlock critical section and
-		 * does not cause time warps:
-		 */
-		rdtsc_barrier();
 		now = vread();
-		rdtsc_barrier();
-
 		base = __vsyscall_gtod_data.clock.cycle_last;
 		mask = __vsyscall_gtod_data.clock.mask;
 		mult = __vsyscall_gtod_data.clock.mult;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/lapic.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/lapic.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/lapic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/lapic.c	2009-12-04 01:00:07.000000000 -0500
@@ -635,6 +635,15 @@ static void start_apic_timer(struct kvm_
 
 	if (!apic->timer.period)
 		return;
+	/*
+	 * Do not allow the guest to program periodic timers with small
+	 * interval, since the hrtimers are not throttled by the host
+	 * scheduler.
+	 */
+	if (apic_lvtt_period(apic)) {
+		if (apic->timer.period < NSEC_PER_MSEC/2)
+			apic->timer.period = NSEC_PER_MSEC/2;
+	}
 
 	hrtimer_start(&apic->timer.dev,
 		      ktime_add_ns(now, apic->timer.period),
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/mmu.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/mmu.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/mmu.c	2009-12-04 01:00:07.000000000 -0500
@@ -490,16 +490,20 @@ static unsigned long *gfn_to_rmap(struct
  *
  * If rmapp bit zero is one, (then rmap & ~1) points to a struct kvm_rmap_desc
  * containing more mappings.
+ *
+ * Returns the number of rmap entries before the spte was added or zero if
+ * the spte was not added.
+ *
  */
-static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage)
+static int rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage)
 {
 	struct kvm_mmu_page *sp;
 	struct kvm_rmap_desc *desc;
 	unsigned long *rmapp;
-	int i;
+	int i, count = 0;
 
 	if (!is_rmap_pte(*spte))
-		return;
+		return count;
 	gfn = unalias_gfn(vcpu->kvm, gfn);
 	sp = page_header(__pa(spte));
 	sp->gfns[spte - sp->spt] = gfn;
@@ -516,8 +520,10 @@ static void rmap_add(struct kvm_vcpu *vc
 	} else {
 		rmap_printk("rmap_add: %p %llx many->many\n", spte, *spte);
 		desc = (struct kvm_rmap_desc *)(*rmapp & ~1ul);
-		while (desc->shadow_ptes[RMAP_EXT-1] && desc->more)
+		while (desc->shadow_ptes[RMAP_EXT-1] && desc->more) {
 			desc = desc->more;
+			count += RMAP_EXT;
+		}
 		if (desc->shadow_ptes[RMAP_EXT-1]) {
 			desc->more = mmu_alloc_rmap_desc(vcpu);
 			desc = desc->more;
@@ -526,6 +532,7 @@ static void rmap_add(struct kvm_vcpu *vc
 			;
 		desc->shadow_ptes[i] = spte;
 	}
+	return count;
 }
 
 static void rmap_desc_remove_entry(unsigned long *rmapp,
@@ -755,6 +762,19 @@ static int kvm_age_rmapp(struct kvm *kvm
 	return young;
 }
 
+#define RMAP_RECYCLE_THRESHOLD 1000
+
+static void rmap_recycle(struct kvm_vcpu *vcpu, gfn_t gfn, int lpage)
+{
+	unsigned long *rmapp;
+
+	gfn = unalias_gfn(vcpu->kvm, gfn);
+	rmapp = gfn_to_rmap(vcpu->kvm, gfn, lpage);
+
+	kvm_unmap_rmapp(vcpu->kvm, rmapp);
+	kvm_flush_remote_tlbs(vcpu->kvm);
+}
+
 int kvm_age_hva(struct kvm *kvm, unsigned long hva)
 {
 	return kvm_handle_hva(kvm, hva, kvm_age_rmapp);
@@ -1417,24 +1437,25 @@ static int kvm_mmu_zap_page(struct kvm *
  */
 void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages)
 {
+	int used_pages;
+
+	used_pages = kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages;
+	used_pages = max(0, used_pages);
+
 	/*
 	 * If we set the number of mmu pages to be smaller be than the
 	 * number of actived pages , we must to free some mmu pages before we
 	 * change the value
 	 */
 
-	if ((kvm->arch.n_alloc_mmu_pages - kvm->arch.n_free_mmu_pages) >
-	    kvm_nr_mmu_pages) {
-		int n_used_mmu_pages = kvm->arch.n_alloc_mmu_pages
-				       - kvm->arch.n_free_mmu_pages;
-
-		while (n_used_mmu_pages > kvm_nr_mmu_pages) {
+	if (used_pages > kvm_nr_mmu_pages) {
+		while (used_pages > kvm_nr_mmu_pages) {
 			struct kvm_mmu_page *page;
 
 			page = container_of(kvm->arch.active_mmu_pages.prev,
 					    struct kvm_mmu_page, link);
 			kvm_mmu_zap_page(kvm, page);
-			n_used_mmu_pages--;
+			used_pages--;
 		}
 		kvm->arch.n_free_mmu_pages = 0;
 	}
@@ -1770,6 +1791,7 @@ static void mmu_set_spte(struct kvm_vcpu
 {
 	int was_rmapped = 0;
 	int was_writeble = is_writeble_pte(*shadow_pte);
+	int rmap_count;
 
 	pgprintk("%s: spte %llx access %x write_fault %d"
 		 " user_fault %d gfn %lx\n",
@@ -1811,9 +1833,11 @@ static void mmu_set_spte(struct kvm_vcpu
 
 	page_header_update_slot(vcpu->kvm, shadow_pte, gfn);
 	if (!was_rmapped) {
-		rmap_add(vcpu, shadow_pte, gfn, largepage);
+		rmap_count = rmap_add(vcpu, shadow_pte, gfn, largepage);
 		if (!is_rmap_pte(*shadow_pte))
 			kvm_release_pfn_clean(pfn);
+		if (rmap_count > RMAP_RECYCLE_THRESHOLD)
+			rmap_recycle(vcpu, gfn, largepage);
 	} else {
 		if (was_writeble)
 			kvm_release_pfn_dirty(pfn);
@@ -1942,7 +1966,19 @@ static void mmu_free_roots(struct kvm_vc
 	vcpu->arch.mmu.root_hpa = INVALID_PAGE;
 }
 
-static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
+static int mmu_check_root(struct kvm_vcpu *vcpu, gfn_t root_gfn)
+{
+	int ret = 0;
+
+	if (!kvm_is_visible_gfn(vcpu->kvm, root_gfn)) {
+		set_bit(KVM_REQ_TRIPLE_FAULT, &vcpu->requests);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int mmu_alloc_roots(struct kvm_vcpu *vcpu)
 {
 	int i;
 	gfn_t root_gfn;
@@ -1957,13 +1993,15 @@ static void mmu_alloc_roots(struct kvm_v
 		ASSERT(!VALID_PAGE(root));
 		if (tdp_enabled)
 			direct = 1;
+		if (mmu_check_root(vcpu, root_gfn))
+			return 1;
 		sp = kvm_mmu_get_page(vcpu, root_gfn, 0,
 				      PT64_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
 		root = __pa(sp->spt);
 		++sp->root_count;
 		vcpu->arch.mmu.root_hpa = root;
-		return;
+		return 0;
 	}
 	direct = !is_paging(vcpu);
 	if (tdp_enabled)
@@ -1980,6 +2018,8 @@ static void mmu_alloc_roots(struct kvm_v
 			root_gfn = vcpu->arch.pdptrs[i] >> PAGE_SHIFT;
 		} else if (vcpu->arch.mmu.root_level == 0)
 			root_gfn = 0;
+		if (mmu_check_root(vcpu, root_gfn))
+			return 1;
 		sp = kvm_mmu_get_page(vcpu, root_gfn, i << 30,
 				      PT32_ROOT_LEVEL, direct,
 				      ACC_ALL, NULL);
@@ -1988,6 +2028,7 @@ static void mmu_alloc_roots(struct kvm_v
 		vcpu->arch.mmu.pae_root[i] = root | PT_PRESENT_MASK;
 	}
 	vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
+	return 0;
 }
 
 static void mmu_sync_roots(struct kvm_vcpu *vcpu)
@@ -2006,7 +2047,7 @@ static void mmu_sync_roots(struct kvm_vc
 	for (i = 0; i < 4; ++i) {
 		hpa_t root = vcpu->arch.mmu.pae_root[i];
 
-		if (root) {
+		if (root && VALID_PAGE(root)) {
 			root &= PT64_BASE_ADDR_MASK;
 			sp = page_header(root);
 			mmu_sync_children(vcpu, sp);
@@ -2290,9 +2331,11 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
 		goto out;
 	spin_lock(&vcpu->kvm->mmu_lock);
 	kvm_mmu_free_some_pages(vcpu);
-	mmu_alloc_roots(vcpu);
+	r = mmu_alloc_roots(vcpu);
 	mmu_sync_roots(vcpu);
 	spin_unlock(&vcpu->kvm->mmu_lock);
+	if (r)
+		goto out;
 	kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
 	kvm_mmu_flush_tlb(vcpu);
 out:
@@ -2569,7 +2612,8 @@ EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page
 
 void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {
-	while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES) {
+	while (vcpu->kvm->arch.n_free_mmu_pages < KVM_REFILL_PAGES &&
+	       !list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
 		struct kvm_mmu_page *sp;
 
 		sp = container_of(vcpu->kvm->arch.active_mmu_pages.prev,
@@ -2638,14 +2682,6 @@ EXPORT_SYMBOL_GPL(kvm_disable_tdp);
 
 static void free_mmu_pages(struct kvm_vcpu *vcpu)
 {
-	struct kvm_mmu_page *sp;
-
-	while (!list_empty(&vcpu->kvm->arch.active_mmu_pages)) {
-		sp = container_of(vcpu->kvm->arch.active_mmu_pages.next,
-				  struct kvm_mmu_page, link);
-		kvm_mmu_zap_page(vcpu->kvm, sp);
-		cond_resched();
-	}
 	free_page((unsigned long)vcpu->arch.mmu.pae_root);
 }
 
@@ -2656,12 +2692,6 @@ static int alloc_mmu_pages(struct kvm_vc
 
 	ASSERT(vcpu);
 
-	if (vcpu->kvm->arch.n_requested_mmu_pages)
-		vcpu->kvm->arch.n_free_mmu_pages =
-					vcpu->kvm->arch.n_requested_mmu_pages;
-	else
-		vcpu->kvm->arch.n_free_mmu_pages =
-					vcpu->kvm->arch.n_alloc_mmu_pages;
 	/*
 	 * When emulating 32-bit mode, cr3 is only 32 bits even on x86_64.
 	 * Therefore we need to allocate shadow page tables in the first
@@ -2710,7 +2740,6 @@ void kvm_mmu_slot_remove_write_access(st
 {
 	struct kvm_mmu_page *sp;
 
-	spin_lock(&kvm->mmu_lock);
 	list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link) {
 		int i;
 		u64 *pt;
@@ -2725,7 +2754,6 @@ void kvm_mmu_slot_remove_write_access(st
 				pt[i] &= ~PT_WRITABLE_MASK;
 	}
 	kvm_flush_remote_tlbs(kvm);
-	spin_unlock(&kvm->mmu_lock);
 }
 
 void kvm_mmu_zap_all(struct kvm *kvm)
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/svm.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/svm.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/svm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/svm.c	2009-12-04 01:00:07.000000000 -0500
@@ -227,6 +227,27 @@ static int is_external_interrupt(u32 inf
 	return info == (SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR);
 }
 
+static u32 svm_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	u32 ret = 0;
+
+	if (svm->vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK)
+		ret |= X86_SHADOW_INT_STI | X86_SHADOW_INT_MOV_SS;
+	return ret & mask;
+}
+
+static void svm_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+
+	if (mask == 0)
+		svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
+	else
+		svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK;
+
+}
+
 static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -240,7 +261,7 @@ static void skip_emulated_instruction(st
 		       __func__, kvm_rip_read(vcpu), svm->next_rip);
 
 	kvm_rip_write(vcpu, svm->next_rip);
-	svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
+	svm_set_interrupt_shadow(vcpu, 0);
 
 	vcpu->arch.interrupt_window_open = (svm->vcpu.arch.hflags & HF_GIF_MASK);
 }
@@ -715,6 +736,7 @@ static void svm_vcpu_load(struct kvm_vcp
 		svm->vmcb->control.tsc_offset += delta;
 		vcpu->cpu = cpu;
 		kvm_migrate_timers(vcpu);
+		svm->asid_generation = 0;
 	}
 
 	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
@@ -1025,7 +1047,6 @@ static void new_asid(struct vcpu_svm *sv
 		svm->vmcb->control.tlb_ctl = TLB_CONTROL_FLUSH_ALL_ASID;
 	}
 
-	svm->vcpu.cpu = svm_data->cpu;
 	svm->asid_generation = svm_data->asid_generation;
 	svm->vmcb->control.asid = svm_data->next_asid++;
 }
@@ -2237,8 +2258,8 @@ static void pre_svm_run(struct vcpu_svm
 	struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
 
 	svm->vmcb->control.tlb_ctl = TLB_CONTROL_DO_NOTHING;
-	if (svm->vcpu.cpu != cpu ||
-	    svm->asid_generation != svm_data->asid_generation)
+	/* FIXME: handle wraparound of asid_generation */
+	if (svm->asid_generation != svm_data->asid_generation)
 		new_asid(svm, svm_data);
 }
 
@@ -2667,6 +2688,8 @@ static struct kvm_x86_ops svm_x86_ops =
 	.run = svm_vcpu_run,
 	.handle_exit = handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
+	.set_interrupt_shadow = svm_set_interrupt_shadow,
+	.get_interrupt_shadow = svm_get_interrupt_shadow,
 	.patch_hypercall = svm_patch_hypercall,
 	.get_irq = svm_get_irq,
 	.set_irq = svm_set_irq,
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/vmx.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/vmx.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/vmx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/vmx.c	2009-12-04 01:00:07.000000000 -0500
@@ -32,6 +32,7 @@
 #include <asm/desc.h>
 #include <asm/vmx.h>
 #include <asm/virtext.h>
+#include <asm/mce.h>
 
 #define __ex(x) __kvm_handle_fault_on_reboot(x)
 
@@ -97,6 +98,8 @@ struct vcpu_vmx {
 	int soft_vnmi_blocked;
 	ktime_t entry_time;
 	s64 vnmi_blocked_time;
+
+	u32 exit_reason;
 };
 
 static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -478,7 +481,7 @@ static void update_exception_bitmap(stru
 {
 	u32 eb;
 
-	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR);
+	eb = (1u << PF_VECTOR) | (1u << UD_VECTOR) | (1u << MC_VECTOR);
 	if (!vcpu->fpu_active)
 		eb |= 1u << NM_VECTOR;
 	if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
@@ -729,23 +732,45 @@ static void vmx_set_rflags(struct kvm_vc
 	vmcs_writel(GUEST_RFLAGS, rflags);
 }
 
+static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+	int ret = 0;
+
+	if (interruptibility & GUEST_INTR_STATE_STI)
+		ret |= X86_SHADOW_INT_STI;
+	if (interruptibility & GUEST_INTR_STATE_MOV_SS)
+		ret |= X86_SHADOW_INT_MOV_SS;
+
+	return ret & mask;
+}
+
+static void vmx_set_interrupt_shadow(struct kvm_vcpu *vcpu, int mask)
+{
+	u32 interruptibility_old = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
+	u32 interruptibility = interruptibility_old;
+
+	interruptibility &= ~(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS);
+
+	if (mask & X86_SHADOW_INT_MOV_SS)
+		interruptibility |= GUEST_INTR_STATE_MOV_SS;
+	if (mask & X86_SHADOW_INT_STI)
+		interruptibility |= GUEST_INTR_STATE_STI;
+
+	if ((interruptibility != interruptibility_old))
+		vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, interruptibility);
+}
+
 static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
 {
 	unsigned long rip;
-	u32 interruptibility;
 
 	rip = kvm_rip_read(vcpu);
 	rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 	kvm_rip_write(vcpu, rip);
 
-	/*
-	 * We emulated an instruction, so temporary interrupt blocking
-	 * should be removed, if set.
-	 */
-	interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
-	if (interruptibility & 3)
-		vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
-			     interruptibility & ~3);
+	/* skipping an emulated instruction also counts */
+	vmx_set_interrupt_shadow(vcpu, 0);
 	vcpu->arch.interrupt_window_open = 1;
 }
 
@@ -1181,12 +1206,9 @@ static __init int setup_vmcs_config(stru
 	if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
 		/* CR3 accesses and invlpg don't need to cause VM Exits when EPT
 		   enabled */
-		min &= ~(CPU_BASED_CR3_LOAD_EXITING |
-			 CPU_BASED_CR3_STORE_EXITING |
-			 CPU_BASED_INVLPG_EXITING);
-		if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
-					&_cpu_based_exec_control) < 0)
-			return -EIO;
+		_cpu_based_exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING |
+					     CPU_BASED_CR3_STORE_EXITING |
+					     CPU_BASED_INVLPG_EXITING);
 		rdmsr(MSR_IA32_VMX_EPT_VPID_CAP,
 		      vmx_capability.ept, vmx_capability.vpid);
 	}
@@ -2585,6 +2607,35 @@ static int handle_rmode_exception(struct
 	return 0;
 }
 
+/*
+ * Trigger machine check on the host. We assume all the MSRs are already set up
+ * by the CPU and that we still run on the same CPU as the MCE occurred on.
+ * We pass a fake environment to the machine check handler because we want
+ * the guest to be always treated like user space, no matter what context
+ * it used internally.
+ */
+static void kvm_machine_check(void)
+{
+#ifdef CONFIG_X86_MCE
+	struct pt_regs regs = {
+		.cs = 3, /* Fake ring 3 no matter what the guest ran on */
+		.flags = X86_EFLAGS_IF,
+	};
+
+#ifdef CONFIG_X86_64
+	do_machine_check(&regs, 0);
+#else
+	machine_check_vector(&regs, 0);
+#endif
+#endif
+}
+
+static int handle_machine_check(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+	/* already handled by vcpu_run */
+	return 1;
+}
+
 static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -2596,6 +2647,10 @@ static int handle_exception(struct kvm_v
 	vect_info = vmx->idt_vectoring_info;
 	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
 
+	ex_no = intr_info & INTR_INFO_VECTOR_MASK;
+	if (ex_no == MC_VECTOR)
+		return handle_machine_check(vcpu, kvm_run);
+
 	if ((vect_info & VECTORING_INFO_VALID_MASK) &&
 						!is_page_fault(intr_info))
 		printk(KERN_ERR "%s: unexpected, vectoring info 0x%x "
@@ -2648,7 +2703,6 @@ static int handle_exception(struct kvm_v
 		return 1;
 	}
 
-	ex_no = intr_info & INTR_INFO_VECTOR_MASK;
 	switch (ex_no) {
 	case DB_VECTOR:
 		dr6 = vmcs_readl(EXIT_QUALIFICATION);
@@ -2808,6 +2862,8 @@ static int handle_dr(struct kvm_vcpu *vc
 	unsigned long val;
 	int dr, reg;
 
+	if (!kvm_require_cpl(vcpu, 0))
+		return 1;
 	dr = vmcs_readl(GUEST_DR7);
 	if (dr & DR7_GD) {
 		/*
@@ -2978,6 +3034,12 @@ static int handle_vmcall(struct kvm_vcpu
 	return 1;
 }
 
+static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+	kvm_queue_exception(vcpu, UD_VECTOR);
+	return 1;
+}
+
 static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	u64 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
@@ -3145,11 +3207,21 @@ static int (*kvm_vmx_exit_handlers[])(st
 	[EXIT_REASON_HLT]                     = handle_halt,
 	[EXIT_REASON_INVLPG]		      = handle_invlpg,
 	[EXIT_REASON_VMCALL]                  = handle_vmcall,
+	[EXIT_REASON_VMCLEAR]	              = handle_vmx_insn,
+	[EXIT_REASON_VMLAUNCH]                = handle_vmx_insn,
+	[EXIT_REASON_VMPTRLD]                 = handle_vmx_insn,
+	[EXIT_REASON_VMPTRST]                 = handle_vmx_insn,
+	[EXIT_REASON_VMREAD]                  = handle_vmx_insn,
+	[EXIT_REASON_VMRESUME]                = handle_vmx_insn,
+	[EXIT_REASON_VMWRITE]                 = handle_vmx_insn,
+	[EXIT_REASON_VMOFF]                   = handle_vmx_insn,
+	[EXIT_REASON_VMON]                    = handle_vmx_insn,
 	[EXIT_REASON_TPR_BELOW_THRESHOLD]     = handle_tpr_below_threshold,
 	[EXIT_REASON_APIC_ACCESS]             = handle_apic_access,
 	[EXIT_REASON_WBINVD]                  = handle_wbinvd,
 	[EXIT_REASON_TASK_SWITCH]             = handle_task_switch,
 	[EXIT_REASON_EPT_VIOLATION]	      = handle_ept_violation,
+	[EXIT_REASON_MCE_DURING_VMENTRY]      = handle_machine_check,
 };
 
 static const int kvm_vmx_max_exit_handlers =
@@ -3161,8 +3233,8 @@ static const int kvm_vmx_max_exit_handle
  */
 static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
-	u32 exit_reason = vmcs_read32(VM_EXIT_REASON);
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	u32 exit_reason = vmx->exit_reason;
 	u32 vectoring_info = vmx->idt_vectoring_info;
 
 	KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
@@ -3512,6 +3584,13 @@ static void vmx_vcpu_run(struct kvm_vcpu
 
 	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
 
+	vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
+
+	/* Handle machine checks before interrupts are enabled */
+	if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY) ||
+		(intr_info & INTR_INFO_VECTOR_MASK) == MC_VECTOR)
+		kvm_machine_check();
+
 	/* We need to handle NMIs before interrupts are enabled */
 	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
 	    (intr_info & INTR_INFO_VALID_MASK)) {
@@ -3680,6 +3759,8 @@ static struct kvm_x86_ops vmx_x86_ops =
 	.run = vmx_vcpu_run,
 	.handle_exit = kvm_handle_exit,
 	.skip_emulated_instruction = skip_emulated_instruction,
+	.set_interrupt_shadow = vmx_set_interrupt_shadow,
+	.get_interrupt_shadow = vmx_get_interrupt_shadow,
 	.patch_hypercall = vmx_patch_hypercall,
 	.get_irq = vmx_get_irq,
 	.set_irq = vmx_inject_irq,
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/x86.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/x86.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/x86.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/x86.c	2009-12-04 01:00:07.000000000 -0500
@@ -217,6 +217,19 @@ static void __queue_exception(struct kvm
 }
 
 /*
+ * Checks if cpl <= required_cpl; if true, return true.  Otherwise queue
+ * a #GP and return false.
+ */
+bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
+{
+	if (kvm_x86_ops->get_cpl(vcpu) <= required_cpl)
+		return true;
+	kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
+	return false;
+}
+EXPORT_SYMBOL_GPL(kvm_require_cpl);
+
+/*
  * Load the pae pdptrs.  Return true is they are all valid.
  */
 int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
@@ -523,6 +536,9 @@ static void set_efer(struct kvm_vcpu *vc
 	efer |= vcpu->arch.shadow_efer & EFER_LMA;
 
 	vcpu->arch.shadow_efer = efer;
+
+	vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled;
+	kvm_mmu_reset_context(vcpu);
 }
 
 void kvm_enable_efer_bits(u64 mask)
@@ -634,10 +650,12 @@ static void kvm_write_guest_time(struct
 	if ((!vcpu->time_page))
 		return;
 
+	preempt_disable();
 	if (unlikely(vcpu->hv_clock_tsc_khz != __get_cpu_var(cpu_tsc_khz))) {
 		kvm_set_time_scale(__get_cpu_var(cpu_tsc_khz), &vcpu->hv_clock);
 		vcpu->hv_clock_tsc_khz = __get_cpu_var(cpu_tsc_khz);
 	}
+	preempt_enable();
 
 	/* Keep irq disabled to prevent changes to the clock */
 	local_irq_save(flags);
@@ -701,11 +719,48 @@ static bool msr_mtrr_valid(unsigned msr)
 	return false;
 }
 
+static bool valid_pat_type(unsigned t)
+{
+	return t < 8 && (1 << t) & 0xf3; /* 0, 1, 4, 5, 6, 7 */
+}
+
+static bool valid_mtrr_type(unsigned t)
+{
+	return t < 8 && (1 << t) & 0x73; /* 0, 1, 4, 5, 6 */
+}
+
+static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+{
+	int i;
+
+	if (!msr_mtrr_valid(msr))
+		return false;
+
+	if (msr == MSR_IA32_CR_PAT) {
+		for (i = 0; i < 8; i++)
+			if (!valid_pat_type((data >> (i * 8)) & 0xff))
+				return false;
+		return true;
+	} else if (msr == MSR_MTRRdefType) {
+		if (data & ~0xcff)
+			return false;
+		return valid_mtrr_type(data & 0xff);
+	} else if (msr >= MSR_MTRRfix64K_00000 && msr <= MSR_MTRRfix4K_F8000) {
+		for (i = 0; i < 8 ; i++)
+			if (!valid_mtrr_type((data >> (i * 8)) & 0xff))
+				return false;
+		return true;
+	}
+
+	/* variable MTRRs */
+	return valid_mtrr_type(data & 0xff);
+}
+
 static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
 {
 	u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
 
-	if (!msr_mtrr_valid(msr))
+	if (!mtrr_valid(vcpu, msr, data))
 		return 1;
 
 	if (msr == MSR_MTRRdefType) {
@@ -893,6 +948,9 @@ int kvm_get_msr_common(struct kvm_vcpu *
 	case MSR_IA32_LASTINTFROMIP:
 	case MSR_IA32_LASTINTTOIP:
 	case MSR_VM_HSAVE_PA:
+	case MSR_P6_EVNTSEL0:
+	case MSR_P6_EVNTSEL1:
+	case MSR_K7_EVNTSEL0:
 		data = 0;
 		break;
 	case MSR_MTRRcap:
@@ -1072,14 +1130,13 @@ long kvm_arch_dev_ioctl(struct file *fil
 		if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list))
 			goto out;
 		r = -E2BIG;
-		if (n < num_msrs_to_save)
+		if (n < msr_list.nmsrs)
 			goto out;
 		r = -EFAULT;
 		if (copy_to_user(user_msr_list->indices, &msrs_to_save,
 				 num_msrs_to_save * sizeof(u32)))
 			goto out;
-		if (copy_to_user(user_msr_list->indices
-				 + num_msrs_to_save * sizeof(u32),
+		if (copy_to_user(user_msr_list->indices + num_msrs_to_save,
 				 &emulated_msrs,
 				 ARRAY_SIZE(emulated_msrs) * sizeof(u32)))
 			goto out;
@@ -1248,9 +1305,12 @@ static void do_cpuid_ent(struct kvm_cpui
 		bit(X86_FEATURE_VME) | bit(X86_FEATURE_DE) |
 		bit(X86_FEATURE_PSE) | bit(X86_FEATURE_TSC) |
 		bit(X86_FEATURE_MSR) | bit(X86_FEATURE_PAE) |
+		bit(X86_FEATURE_MCE) |
 		bit(X86_FEATURE_CX8) | bit(X86_FEATURE_APIC) |
-		bit(X86_FEATURE_SEP) | bit(X86_FEATURE_PGE) |
-		bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PSE36) |
+		bit(X86_FEATURE_SEP) | bit(X86_FEATURE_MTRR) |
+		bit(X86_FEATURE_PGE) | bit(X86_FEATURE_MCA) |
+		bit(X86_FEATURE_CMOV) | bit(X86_FEATURE_PAT) |
+		bit(X86_FEATURE_PSE36) |
 		bit(X86_FEATURE_CLFLSH) | bit(X86_FEATURE_MMX) |
 		bit(X86_FEATURE_FXSR) | bit(X86_FEATURE_XMM) |
 		bit(X86_FEATURE_XMM2) | bit(X86_FEATURE_SELFSNOOP);
@@ -1378,6 +1438,10 @@ static int kvm_dev_ioctl_get_supported_c
 	for (func = 0x80000001; func <= limit && nent < cpuid->nent; ++func)
 		do_cpuid_ent(&cpuid_entries[nent], func, 0,
 			     &nent, cpuid->nent);
+	r = -E2BIG;
+	if (nent >= cpuid->nent)
+		goto out_free;
+
 	r = -EFAULT;
 	if (copy_to_user(entries, cpuid_entries,
 			 nent * sizeof(struct kvm_cpuid_entry2)))
@@ -1606,10 +1670,12 @@ static int kvm_vm_ioctl_set_nr_mmu_pages
 		return -EINVAL;
 
 	down_write(&kvm->slots_lock);
+	spin_lock(&kvm->mmu_lock);
 
 	kvm_mmu_change_mmu_pages(kvm, kvm_nr_mmu_pages);
 	kvm->arch.n_requested_mmu_pages = kvm_nr_mmu_pages;
 
+	spin_unlock(&kvm->mmu_lock);
 	up_write(&kvm->slots_lock);
 	return 0;
 }
@@ -1785,7 +1851,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kv
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (is_dirty) {
+		spin_lock(&kvm->mmu_lock);
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
+		spin_unlock(&kvm->mmu_lock);
 		kvm_flush_remote_tlbs(kvm);
 		memslot = &kvm->memslots[log->slot];
 		n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
@@ -2360,7 +2428,7 @@ int emulate_instruction(struct kvm_vcpu
 			u16 error_code,
 			int emulation_type)
 {
-	int r;
+	int r, shadow_mask;
 	struct decode_cache *c;
 
 	kvm_clear_exception_queue(vcpu);
@@ -2409,6 +2477,10 @@ int emulate_instruction(struct kvm_vcpu
 	}
 
 	r = x86_emulate_insn(&vcpu->arch.emulate_ctxt, &emulate_ops);
+	shadow_mask = vcpu->arch.emulate_ctxt.interruptibility;
+
+	if (r == 0)
+		kvm_x86_ops->set_interrupt_shadow(vcpu, shadow_mask);
 
 	if (vcpu->arch.pio.string)
 		return EMULATE_DO_MMIO;
@@ -2830,6 +2902,11 @@ int kvm_emulate_hypercall(struct kvm_vcp
 		a3 &= 0xFFFFFFFF;
 	}
 
+	if (kvm_x86_ops->get_cpl(vcpu) != 0) {
+		ret = -KVM_EPERM;
+		goto out;
+	}
+
 	switch (nr) {
 	case KVM_HC_VAPIC_POLL_IRQ:
 		ret = 0;
@@ -2841,6 +2918,7 @@ int kvm_emulate_hypercall(struct kvm_vcp
 		ret = -KVM_ENOSYS;
 		break;
 	}
+out:
 	kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
 	++vcpu->stat.hypercalls;
 	return r;
@@ -4411,12 +4489,14 @@ int kvm_arch_set_memory_region(struct kv
 		}
 	}
 
+	spin_lock(&kvm->mmu_lock);
 	if (!kvm->arch.n_requested_mmu_pages) {
 		unsigned int nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm);
 		kvm_mmu_change_mmu_pages(kvm, nr_mmu_pages);
 	}
 
 	kvm_mmu_slot_remove_write_access(kvm, mem->slot);
+	spin_unlock(&kvm->mmu_lock);
 	kvm_flush_remote_tlbs(kvm);
 
 	return 0;
@@ -4425,6 +4505,7 @@ int kvm_arch_set_memory_region(struct kv
 void kvm_arch_flush_shadow(struct kvm *kvm)
 {
 	kvm_mmu_zap_all(kvm);
+	kvm_reload_remote_mmus(kvm);
 }
 
 int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/kvm/x86_emulate.c linux-libre-2.6.30.10-gnu1/arch/x86/kvm/x86_emulate.c
--- linux-libre-2.6.30-gnu1/arch/x86/kvm/x86_emulate.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/kvm/x86_emulate.c	2009-12-04 01:00:07.000000000 -0500
@@ -1349,6 +1349,20 @@ static inline int writeback(struct x86_e
 	return 0;
 }
 
+void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask)
+{
+	u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask);
+	/*
+	 * an sti; sti; sequence only disable interrupts for the first
+	 * instruction. So, if the last instruction, be it emulated or
+	 * not, left the system with the INT_STI flag enabled, it
+	 * means that the last instruction is an sti. We should not
+	 * leave the flag on in this case. The same goes for mov ss
+	 */
+	if (!(int_shadow & mask))
+		ctxt->interruptibility = mask;
+}
+
 int
 x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
 {
@@ -1360,6 +1374,8 @@ x86_emulate_insn(struct x86_emulate_ctxt
 	int io_dir_in;
 	int rc = 0;
 
+	ctxt->interruptibility = 0;
+
 	/* Shadow copy of register state. Committed on successful emulation.
 	 * NOTE: we can copy them from vcpu as x86_decode_insn() doesn't
 	 * modify them.
@@ -1609,6 +1625,9 @@ special_insn:
 		int err;
 
 		sel = c->src.val;
+		if (c->modrm_reg == VCPU_SREG_SS)
+			toggle_interruptibility(ctxt, X86_SHADOW_INT_MOV_SS);
+
 		if (c->modrm_reg <= 5) {
 			type_bits = (c->modrm_reg == 1) ? 9 : 1;
 			err = kvm_load_segment_descriptor(ctxt->vcpu, sel,
@@ -1865,6 +1884,7 @@ special_insn:
 		c->dst.type = OP_NONE;	/* Disable writeback. */
 		break;
 	case 0xfb: /* sti */
+		toggle_interruptibility(ctxt, X86_SHADOW_INT_STI);
 		ctxt->eflags |= X86_EFLAGS_IF;
 		c->dst.type = OP_NONE;	/* Disable writeback. */
 		break;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/mm/gup.c linux-libre-2.6.30.10-gnu1/arch/x86/mm/gup.c
--- linux-libre-2.6.30-gnu1/arch/x86/mm/gup.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/mm/gup.c	2009-12-04 01:00:07.000000000 -0500
@@ -247,11 +247,16 @@ int get_user_pages_fast(unsigned long st
 	start &= PAGE_MASK;
 	addr = start;
 	len = (unsigned long) nr_pages << PAGE_SHIFT;
+
 	end = start + len;
-	if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
-					(void __user *)start, len)))
+	if (end < start)
 		goto slow_irqon;
 
+#ifdef CONFIG_X86_64
+	if (end >> 47)
+		goto slow_irqon;
+#endif
+
 	/*
 	 * XXX: batch / limit 'nr', to avoid large irq off latency
 	 * needs some instrumenting to determine the common sizes used by
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/mm/memtest.c linux-libre-2.6.30.10-gnu1/arch/x86/mm/memtest.c
--- linux-libre-2.6.30-gnu1/arch/x86/mm/memtest.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/mm/memtest.c	2009-12-04 01:00:07.000000000 -0500
@@ -40,23 +40,23 @@ static void __init reserve_bad_mem(u64 p
 
 static void __init memtest(u64 pattern, u64 start_phys, u64 size)
 {
-	u64 i, count;
-	u64 *start;
+	u64 *p;
+	void *start, *end;
 	u64 start_bad, last_bad;
 	u64 start_phys_aligned;
 	size_t incr;
 
 	incr = sizeof(pattern);
 	start_phys_aligned = ALIGN(start_phys, incr);
-	count = (size - (start_phys_aligned - start_phys))/incr;
 	start = __va(start_phys_aligned);
+	end = start + size - (start_phys_aligned - start_phys);
 	start_bad = 0;
 	last_bad = 0;
 
-	for (i = 0; i < count; i++)
-		start[i] = pattern;
-	for (i = 0; i < count; i++, start++, start_phys_aligned += incr) {
-		if (*start == pattern)
+	for (p = start; p < end; p++)
+		*p = pattern;
+	for (p = start; p < end; p++, start_phys_aligned += incr) {
+		if (*p == pattern)
 			continue;
 		if (start_phys_aligned == last_bad + incr) {
 			last_bad += incr;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/mm/pageattr.c linux-libre-2.6.30.10-gnu1/arch/x86/mm/pageattr.c
--- linux-libre-2.6.30-gnu1/arch/x86/mm/pageattr.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/mm/pageattr.c	2009-12-04 01:00:07.000000000 -0500
@@ -590,9 +590,12 @@ static int __change_page_attr(struct cpa
 	unsigned int level;
 	pte_t *kpte, old_pte;
 
-	if (cpa->flags & CPA_PAGES_ARRAY)
-		address = (unsigned long)page_address(cpa->pages[cpa->curpage]);
-	else if (cpa->flags & CPA_ARRAY)
+	if (cpa->flags & CPA_PAGES_ARRAY) {
+		struct page *page = cpa->pages[cpa->curpage];
+		if (unlikely(PageHighMem(page)))
+			return 0;
+		address = (unsigned long)page_address(page);
+	} else if (cpa->flags & CPA_ARRAY)
 		address = cpa->vaddr[cpa->curpage];
 	else
 		address = *cpa->vaddr;
@@ -695,9 +698,12 @@ static int cpa_process_alias(struct cpa_
 	 * No need to redo, when the primary call touched the direct
 	 * mapping already:
 	 */
-	if (cpa->flags & CPA_PAGES_ARRAY)
-		vaddr = (unsigned long)page_address(cpa->pages[cpa->curpage]);
-	else if (cpa->flags & CPA_ARRAY)
+	if (cpa->flags & CPA_PAGES_ARRAY) {
+		struct page *page = cpa->pages[cpa->curpage];
+		if (unlikely(PageHighMem(page)))
+			return 0;
+		vaddr = (unsigned long)page_address(page);
+	} else if (cpa->flags & CPA_ARRAY)
 		vaddr = cpa->vaddr[cpa->curpage];
 	else
 		vaddr = *cpa->vaddr;
@@ -801,6 +807,7 @@ static int change_page_attr_set_clr(unsi
 {
 	struct cpa_data cpa;
 	int ret, cache, checkalias;
+	unsigned long baddr = 0;
 
 	/*
 	 * Check, if we are requested to change a not supported
@@ -832,6 +839,11 @@ static int change_page_attr_set_clr(unsi
 			 */
 			WARN_ON_ONCE(1);
 		}
+		/*
+		 * Save address for cache flush. *addr is modified in the call
+		 * to __change_page_attr_set_clr() below.
+		 */
+		baddr = *addr;
 	}
 
 	/* Must avoid aliasing mappings in the highmem code */
@@ -886,7 +898,7 @@ static int change_page_attr_set_clr(unsi
 			cpa_flush_array(addr, numpages, cache,
 					cpa.flags, pages);
 		} else
-			cpa_flush_range(*addr, numpages, cache);
+			cpa_flush_range(baddr, numpages, cache);
 	} else
 		cpa_flush_all(cache);
 
@@ -996,12 +1008,15 @@ EXPORT_SYMBOL(set_memory_array_uc);
 int _set_memory_wc(unsigned long addr, int numpages)
 {
 	int ret;
+	unsigned long addr_copy = addr;
+
 	ret = change_page_attr_set(&addr, numpages,
 				    __pgprot(_PAGE_CACHE_UC_MINUS), 0);
-
 	if (!ret) {
-		ret = change_page_attr_set(&addr, numpages,
-				    __pgprot(_PAGE_CACHE_WC), 0);
+		ret = change_page_attr_set_clr(&addr_copy, numpages,
+					       __pgprot(_PAGE_CACHE_WC),
+					       __pgprot(_PAGE_CACHE_MASK),
+					       0, 0, NULL);
 	}
 	return ret;
 }
@@ -1118,7 +1133,9 @@ int set_pages_array_uc(struct page **pag
 	int free_idx;
 
 	for (i = 0; i < addrinarray; i++) {
-		start = (unsigned long)page_address(pages[i]);
+		if (PageHighMem(pages[i]))
+			continue;
+		start = page_to_pfn(pages[i]) << PAGE_SHIFT;
 		end = start + PAGE_SIZE;
 		if (reserve_memtype(start, end, _PAGE_CACHE_UC_MINUS, NULL))
 			goto err_out;
@@ -1131,7 +1148,9 @@ int set_pages_array_uc(struct page **pag
 err_out:
 	free_idx = i;
 	for (i = 0; i < free_idx; i++) {
-		start = (unsigned long)page_address(pages[i]);
+		if (PageHighMem(pages[i]))
+			continue;
+		start = page_to_pfn(pages[i]) << PAGE_SHIFT;
 		end = start + PAGE_SIZE;
 		free_memtype(start, end);
 	}
@@ -1160,7 +1179,9 @@ int set_pages_array_wb(struct page **pag
 		return retval;
 
 	for (i = 0; i < addrinarray; i++) {
-		start = (unsigned long)page_address(pages[i]);
+		if (PageHighMem(pages[i]))
+			continue;
+		start = page_to_pfn(pages[i]) << PAGE_SHIFT;
 		end = start + PAGE_SIZE;
 		free_memtype(start, end);
 	}
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/mm/srat_64.c linux-libre-2.6.30.10-gnu1/arch/x86/mm/srat_64.c
--- linux-libre-2.6.30-gnu1/arch/x86/mm/srat_64.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/mm/srat_64.c	2009-12-04 01:00:07.000000000 -0500
@@ -89,8 +89,10 @@ static __init void bad_srat(void)
 	found_add_area = 0;
 	for (i = 0; i < MAX_LOCAL_APIC; i++)
 		apicid_to_node[i] = NUMA_NO_NODE;
-	for (i = 0; i < MAX_NUMNODES; i++)
-		nodes_add[i].start = nodes[i].end = 0;
+	for (i = 0; i < MAX_NUMNODES; i++) {
+		nodes[i].start = nodes[i].end = 0;
+		nodes_add[i].start = nodes_add[i].end = 0;
+	}
 	remove_all_active_ranges();
 }
 
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/mm/tlb.c linux-libre-2.6.30.10-gnu1/arch/x86/mm/tlb.c
--- linux-libre-2.6.30-gnu1/arch/x86/mm/tlb.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/mm/tlb.c	2009-12-04 01:00:07.000000000 -0500
@@ -183,18 +183,17 @@ static void flush_tlb_others_ipi(const s
 
 	f->flush_mm = mm;
 	f->flush_va = va;
-	cpumask_andnot(to_cpumask(f->flush_cpumask),
-		       cpumask, cpumask_of(smp_processor_id()));
-
-	/*
-	 * We have to send the IPI only to
-	 * CPUs affected.
-	 */
-	apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
-		      INVALIDATE_TLB_VECTOR_START + sender);
+	if (cpumask_andnot(to_cpumask(f->flush_cpumask), cpumask, cpumask_of(smp_processor_id()))) {
+		/*
+		 * We have to send the IPI only to
+		 * CPUs affected.
+		 */
+		apic->send_IPI_mask(to_cpumask(f->flush_cpumask),
+			      INVALIDATE_TLB_VECTOR_START + sender);
 
-	while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
-		cpu_relax();
+		while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
+			cpu_relax();
+	}
 
 	f->flush_mm = NULL;
 	f->flush_va = 0;
diff -druNp linux-libre-2.6.30-gnu1/arch/x86/pci/i386.c linux-libre-2.6.30.10-gnu1/arch/x86/pci/i386.c
--- linux-libre-2.6.30-gnu1/arch/x86/pci/i386.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/arch/x86/pci/i386.c	2009-12-04 01:00:07.000000000 -0500
@@ -35,6 +35,7 @@
 #include <asm/pat.h>
 #include <asm/e820.h>
 #include <asm/pci_x86.h>
+#include <asm/io_apic.h>
 
 
 static int
@@ -230,6 +231,12 @@ void __init pcibios_resource_survey(void
 	pcibios_allocate_resources(1);
 
 	e820_reserve_resources_late();
+	/*
+	 * Insert the IO APIC resources after PCI initialization has
+	 * occured to handle IO APICS that are mapped in on a BAR in
+	 * PCI space, but before trying to assign unassigned pci res.
+	 */
+	ioapic_insert_resources();
 }
 
 /**
diff -druNp linux-libre-2.6.30-gnu1/block/blk-core.c linux-libre-2.6.30.10-gnu1/block/blk-core.c
--- linux-libre-2.6.30-gnu1/block/blk-core.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/block/blk-core.c	2009-12-04 01:00:07.000000000 -0500
@@ -1158,6 +1158,11 @@ static int __make_request(struct request
 
 	nr_sectors = bio_sectors(bio);
 
+	if (bio_barrier(bio) && bio_has_data(bio) &&
+	    (q->next_ordered == QUEUE_ORDERED_NONE)) {
+		bio_endio(bio, -EOPNOTSUPP);
+		return 0;
+	}
 	/*
 	 * low level driver can indicate that it wants pages above a
 	 * certain limit bounced to low memory (ie for highmem, or even
@@ -1461,11 +1466,6 @@ static inline void __generic_make_reques
 			err = -EOPNOTSUPP;
 			goto end_io;
 		}
-		if (bio_barrier(bio) && bio_has_data(bio) &&
-		    (q->next_ordered == QUEUE_ORDERED_NONE)) {
-			err = -EOPNOTSUPP;
-			goto end_io;
-		}
 
 		ret = q->make_request_fn(q, bio);
 	} while (ret);
diff -druNp linux-libre-2.6.30-gnu1/block/Kconfig linux-libre-2.6.30.10-gnu1/block/Kconfig
--- linux-libre-2.6.30-gnu1/block/Kconfig	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/block/Kconfig	2009-12-04 01:00:07.000000000 -0500
@@ -45,9 +45,9 @@ config LBD
 	  If unsure, say N.
 
 config BLK_DEV_BSG
-	bool "Block layer SG support v4 (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	---help---
+	bool "Block layer SG support v4"
+	default y
+	help
 	  Saying Y here will enable generic SG (SCSI generic) v4 support
 	  for any block device.
 
@@ -57,7 +57,10 @@ config BLK_DEV_BSG
 	  protocols (e.g. Task Management Functions and SMP in Serial
 	  Attached SCSI).
 
-	  If unsure, say N.
+	  This option is required by recent UDEV versions to properly
+	  access device serial numbers, etc.
+
+	  If unsure, say Y.
 
 config BLK_DEV_INTEGRITY
 	bool "Block layer data integrity support"
diff -druNp linux-libre-2.6.30-gnu1/Documentation/RCU/rculist_nulls.txt linux-libre-2.6.30.10-gnu1/Documentation/RCU/rculist_nulls.txt
--- linux-libre-2.6.30-gnu1/Documentation/RCU/rculist_nulls.txt	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/Documentation/RCU/rculist_nulls.txt	2009-12-04 01:00:07.000000000 -0500
@@ -83,11 +83,12 @@ not detect it missed following items in
 obj = kmem_cache_alloc(...);
 lock_chain(); // typically a spin_lock()
 obj->key = key;
-atomic_inc(&obj->refcnt);
 /*
  * we need to make sure obj->key is updated before obj->next
+ * or obj->refcnt
  */
 smp_wmb();
+atomic_set(&obj->refcnt, 1);
 hlist_add_head_rcu(&obj->obj_node, list);
 unlock_chain(); // typically a spin_unlock()
 
@@ -159,6 +160,10 @@ out:
 obj = kmem_cache_alloc(cachep);
 lock_chain(); // typically a spin_lock()
 obj->key = key;
+/*
+ * changes to obj->key must be visible before refcnt one
+ */
+smp_wmb();
 atomic_set(&obj->refcnt, 1);
 /*
  * insert obj in RCU way (readers might be traversing chain)
diff -druNp linux-libre-2.6.30-gnu1/Documentation/sysctl/vm.txt linux-libre-2.6.30.10-gnu1/Documentation/sysctl/vm.txt
--- linux-libre-2.6.30-gnu1/Documentation/sysctl/vm.txt	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/Documentation/sysctl/vm.txt	2009-12-04 01:00:07.000000000 -0500
@@ -314,10 +314,14 @@ min_unmapped_ratio:
 
 This is available only on NUMA kernels.
 
-A percentage of the total pages in each zone.  Zone reclaim will only
-occur if more than this percentage of pages are file backed and unmapped.
-This is to insure that a minimal amount of local pages is still available for
-file I/O even if the node is overallocated.
+This is a percentage of the total pages in each zone. Zone reclaim will
+only occur if more than this percentage of pages are in a state that
+zone_reclaim_mode allows to be reclaimed.
+
+If zone_reclaim_mode has the value 4 OR'd, then the percentage is compared
+against all file-backed unmapped pages including swapcache pages and tmpfs
+files. Otherwise, only unmapped pages backed by normal files but not tmpfs
+files and similar are considered.
 
 The default is 1 percent.
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/acpi/pci_slot.c linux-libre-2.6.30.10-gnu1/drivers/acpi/pci_slot.c
--- linux-libre-2.6.30-gnu1/drivers/acpi/pci_slot.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/acpi/pci_slot.c	2009-12-04 01:00:07.000000000 -0500
@@ -57,7 +57,7 @@ ACPI_MODULE_NAME("pci_slot");
 				MY_NAME , ## arg);		\
 	} while (0)
 
-#define SLOT_NAME_SIZE 20		/* Inspired by #define in acpiphp.h */
+#define SLOT_NAME_SIZE 21		/* Inspired by #define in acpiphp.h */
 
 struct acpi_pci_slot {
 	acpi_handle root_handle;	/* handle of the root bridge */
@@ -149,7 +149,7 @@ register_slot(acpi_handle handle, u32 lv
 		return AE_OK;
 	}
 
-	snprintf(name, sizeof(name), "%u", (u32)sun);
+	snprintf(name, sizeof(name), "%llu", sun);
 	pci_slot = pci_create_slot(pci_bus, device, name, NULL);
 	if (IS_ERR(pci_slot)) {
 		err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot));
diff -druNp linux-libre-2.6.30-gnu1/drivers/acpi/processor_thermal.c linux-libre-2.6.30.10-gnu1/drivers/acpi/processor_thermal.c
--- linux-libre-2.6.30-gnu1/drivers/acpi/processor_thermal.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/acpi/processor_thermal.c	2009-12-04 01:00:07.000000000 -0500
@@ -66,7 +66,7 @@ static int acpi_processor_apply_limit(st
 		if (pr->limit.thermal.tx > tx)
 			tx = pr->limit.thermal.tx;
 
-		result = acpi_processor_set_throttling(pr, tx);
+		result = acpi_processor_set_throttling(pr, tx, false);
 		if (result)
 			goto end;
 	}
@@ -421,12 +421,12 @@ processor_set_cur_state(struct thermal_c
 
 	if (state <= max_pstate) {
 		if (pr->flags.throttling && pr->throttling.state)
-			result = acpi_processor_set_throttling(pr, 0);
+			result = acpi_processor_set_throttling(pr, 0, false);
 		cpufreq_set_cur_state(pr->id, state);
 	} else {
 		cpufreq_set_cur_state(pr->id, max_pstate);
 		result = acpi_processor_set_throttling(pr,
-				state - max_pstate);
+				state - max_pstate, false);
 	}
 	return result;
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/acpi/processor_throttling.c linux-libre-2.6.30.10-gnu1/drivers/acpi/processor_throttling.c
--- linux-libre-2.6.30-gnu1/drivers/acpi/processor_throttling.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/acpi/processor_throttling.c	2009-12-04 01:00:07.000000000 -0500
@@ -62,7 +62,8 @@ struct throttling_tstate {
 #define THROTTLING_POSTCHANGE      (2)
 
 static int acpi_processor_get_throttling(struct acpi_processor *pr);
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+						int state, bool force);
 
 static int acpi_processor_update_tsd_coord(void)
 {
@@ -361,7 +362,7 @@ int acpi_processor_tstate_has_changed(st
 		 */
 		target_state = throttling_limit;
 	}
-	return acpi_processor_set_throttling(pr, target_state);
+	return acpi_processor_set_throttling(pr, target_state, false);
 }
 
 /*
@@ -842,7 +843,7 @@ static int acpi_processor_get_throttling
 			ACPI_WARNING((AE_INFO,
 				"Invalid throttling state, reset"));
 			state = 0;
-			ret = acpi_processor_set_throttling(pr, state);
+			ret = acpi_processor_set_throttling(pr, state, true);
 			if (ret)
 				return ret;
 		}
@@ -915,7 +916,7 @@ static int acpi_processor_get_fadt_info(
 }
 
 static int acpi_processor_set_throttling_fadt(struct acpi_processor *pr,
-					      int state)
+					      int state, bool force)
 {
 	u32 value = 0;
 	u32 duty_mask = 0;
@@ -930,7 +931,7 @@ static int acpi_processor_set_throttling
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (state == pr->throttling.state)
+	if (!force && (state == pr->throttling.state))
 		return 0;
 
 	if (state < pr->throttling_platform_limit)
@@ -988,7 +989,7 @@ static int acpi_processor_set_throttling
 }
 
 static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
-					     int state)
+					     int state, bool force)
 {
 	int ret;
 	acpi_integer value;
@@ -1002,7 +1003,7 @@ static int acpi_processor_set_throttling
 	if (!pr->flags.throttling)
 		return -ENODEV;
 
-	if (state == pr->throttling.state)
+	if (!force && (state == pr->throttling.state))
 		return 0;
 
 	if (state < pr->throttling_platform_limit)
@@ -1018,7 +1019,8 @@ static int acpi_processor_set_throttling
 	return 0;
 }
 
-int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
+int acpi_processor_set_throttling(struct acpi_processor *pr,
+						int state, bool force)
 {
 	cpumask_var_t saved_mask;
 	int ret = 0;
@@ -1070,7 +1072,7 @@ int acpi_processor_set_throttling(struct
 		/* FIXME: use work_on_cpu() */
 		set_cpus_allowed_ptr(current, cpumask_of(pr->id));
 		ret = p_throttling->acpi_processor_set_throttling(pr,
-						t_state.target_state);
+						t_state.target_state, force);
 	} else {
 		/*
 		 * When the T-state coordination is SW_ALL or HW_ALL,
@@ -1103,7 +1105,7 @@ int acpi_processor_set_throttling(struct
 			set_cpus_allowed_ptr(current, cpumask_of(i));
 			ret = match_pr->throttling.
 				acpi_processor_set_throttling(
-				match_pr, t_state.target_state);
+				match_pr, t_state.target_state, force);
 		}
 	}
 	/*
@@ -1201,7 +1203,7 @@ int acpi_processor_get_throttling_info(s
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Disabling throttling (was T%d)\n",
 				  pr->throttling.state));
-		result = acpi_processor_set_throttling(pr, 0);
+		result = acpi_processor_set_throttling(pr, 0, false);
 		if (result)
 			goto end;
 	}
@@ -1307,7 +1309,7 @@ static ssize_t acpi_processor_write_thro
 	if (strcmp(tmpbuf, charp) != 0)
 		return -EINVAL;
 
-	result = acpi_processor_set_throttling(pr, state_val);
+	result = acpi_processor_set_throttling(pr, state_val, false);
 	if (result)
 		return result;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/acpi/sleep.c linux-libre-2.6.30.10-gnu1/drivers/acpi/sleep.c
--- linux-libre-2.6.30-gnu1/drivers/acpi/sleep.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/acpi/sleep.c	2009-12-04 01:00:07.000000000 -0500
@@ -397,6 +397,14 @@ static struct dmi_system_id __initdata a
 		},
 	},
 	{
+	.callback = init_set_sci_en_on_resume,
+	.ident = "Hewlett-Packard HP G7000 Notebook PC",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "HP G7000 Notebook PC"),
+		},
+	},
+	{
 	.callback = init_old_suspend_ordering,
 	.ident = "Panasonic CF51-2L",
 	.matches = {
diff -druNp linux-libre-2.6.30-gnu1/drivers/ata/ahci.c linux-libre-2.6.30.10-gnu1/drivers/ata/ahci.c
--- linux-libre-2.6.30-gnu1/drivers/ata/ahci.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ata/ahci.c	2009-12-04 01:00:07.000000000 -0500
@@ -2744,8 +2744,8 @@ static int ahci_init_one(struct pci_dev
 	if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
 		hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
 
-	if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
-		pci_enable_msi(pdev);
+	if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
+		pci_intx(pdev, 1);
 
 	/* save initial config */
 	ahci_save_initial_config(pdev, hpriv);
diff -druNp linux-libre-2.6.30-gnu1/drivers/ata/libata-core.c linux-libre-2.6.30.10-gnu1/drivers/ata/libata-core.c
--- linux-libre-2.6.30-gnu1/drivers/ata/libata-core.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ata/libata-core.c	2009-12-04 01:00:07.000000000 -0500
@@ -709,7 +709,13 @@ u64 ata_tf_read_block(struct ata_taskfil
 		head = tf->device & 0xf;
 		sect = tf->lbal;
 
-		block = (cyl * dev->heads + head) * dev->sectors + sect;
+		if (!sect) {
+			ata_dev_printk(dev, KERN_WARNING, "device reported "
+				       "invalid CHS sector 0\n");
+			sect = 1; /* oh well */
+		}
+
+		block = (cyl * dev->heads + head) * dev->sectors + sect - 1;
 	}
 
 	return block;
@@ -4271,6 +4277,9 @@ static const struct ata_blacklist_entry
 	{ "WDC WD2500JD-00HBB0", "WD-WMAL71490727", ATA_HORKAGE_BROKEN_HPA },
 	{ "MAXTOR 6L080L4",	"A93.0500",	ATA_HORKAGE_BROKEN_HPA },
 
+	/* this one allows HPA unlocking but fails IOs on the area */
+	{ "OCZ-VERTEX",		    "1.30",	ATA_HORKAGE_BROKEN_HPA },
+
 	/* Devices which report 1 sector over size HPA */
 	{ "ST340823A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
 	{ "ST320413A",		NULL,		ATA_HORKAGE_HPA_SIZE, },
diff -druNp linux-libre-2.6.30-gnu1/drivers/ata/libata-eh.c linux-libre-2.6.30.10-gnu1/drivers/ata/libata-eh.c
--- linux-libre-2.6.30-gnu1/drivers/ata/libata-eh.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ata/libata-eh.c	2009-12-04 01:00:07.000000000 -0500
@@ -2517,6 +2517,10 @@ int ata_eh_reset(struct ata_link *link,
 
 			ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
 			rc = ata_do_reset(link, reset, classes, deadline, true);
+			if (rc) {
+				failed_link = link;
+				goto fail;
+			}
 		}
 	} else {
 		if (verbose)
diff -druNp linux-libre-2.6.30-gnu1/drivers/block/floppy.c linux-libre-2.6.30.10-gnu1/drivers/block/floppy.c
--- linux-libre-2.6.30-gnu1/drivers/block/floppy.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/block/floppy.c	2009-12-04 01:00:07.000000000 -0500
@@ -3327,7 +3327,10 @@ static inline int set_geometry(unsigned
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
 		mutex_lock(&open_lock);
-		LOCK_FDC(drive, 1);
+		if (lock_fdc(drive, 1)) {
+			mutex_unlock(&open_lock);
+			return -EINTR;
+		}
 		floppy_type[type] = *g;
 		floppy_type[type].name = "user format";
 		for (cnt = type << 2; cnt < (type << 2) + 4; cnt++)
diff -druNp linux-libre-2.6.30-gnu1/drivers/block/virtio_blk.c linux-libre-2.6.30.10-gnu1/drivers/block/virtio_blk.c
--- linux-libre-2.6.30-gnu1/drivers/block/virtio_blk.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/block/virtio_blk.c	2009-12-04 01:00:07.000000000 -0500
@@ -308,6 +308,9 @@ static int virtblk_probe(struct virtio_d
 	else
 		blk_queue_max_segment_size(vblk->disk->queue, -1U);
 
+	/* No need to bounce any requests */
+	blk_queue_bounce_limit(vblk->disk->queue, BLK_BOUNCE_ANY);
+
 	/* Host can optionally specify the block size of the device */
 	err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE,
 				offsetof(struct virtio_blk_config, blk_size),
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/agp/intel-agp.c linux-libre-2.6.30.10-gnu1/drivers/char/agp/intel-agp.c
--- linux-libre-2.6.30-gnu1/drivers/char/agp/intel-agp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/agp/intel-agp.c	2009-12-04 01:00:07.000000000 -0500
@@ -2299,15 +2299,6 @@ static int agp_intel_resume(struct pci_d
 	struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
 	int ret_val;
 
-	pci_restore_state(pdev);
-
-	/* We should restore our graphics device's config space,
-	 * as host bridge (00:00) resumes before graphics device (02:00),
-	 * then our access to its pci space can work right.
-	 */
-	if (intel_private.pcidev)
-		pci_restore_state(intel_private.pcidev);
-
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
 	else if (bridge->driver == &intel_850_driver)
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/epca.c linux-libre-2.6.30.10-gnu1/drivers/char/epca.c
--- linux-libre-2.6.30-gnu1/drivers/char/epca.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/epca.c	2009-12-04 01:00:07.000000000 -0500
@@ -1518,7 +1518,7 @@ static void doevent(int crd)
 		if (event & MODEMCHG_IND) {
 			/* A modem signal change has been indicated */
 			ch->imodem = mstat;
-			if (test_bit(ASYNC_CHECK_CD, &ch->port.flags)) {
+			if (test_bit(ASYNCB_CHECK_CD, &ch->port.flags)) {
 				/* We are now receiving dcd */
 				if (mstat & ch->dcd)
 					wake_up_interruptible(&ch->port.open_wait);
@@ -1765,9 +1765,9 @@ static void epcaparam(struct tty_struct
 		 * that the driver will wait on carrier detect.
 		 */
 		if (ts->c_cflag & CLOCAL)
-			clear_bit(ASYNC_CHECK_CD, &ch->port.flags);
+			clear_bit(ASYNCB_CHECK_CD, &ch->port.flags);
 		else
-			set_bit(ASYNC_CHECK_CD, &ch->port.flags);
+			set_bit(ASYNCB_CHECK_CD, &ch->port.flags);
 		mval = ch->m_dtr | ch->m_rts;
 	} /* End CBAUD not detected */
 	iflag = termios2digi_i(ch, ts->c_iflag);
@@ -2244,7 +2244,8 @@ static void do_softint(struct work_struc
 			if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
 				tty_hangup(tty);
 				wake_up_interruptible(&ch->port.open_wait);
-				clear_bit(ASYNC_NORMAL_ACTIVE, &ch->port.flags);
+				clear_bit(ASYNCB_NORMAL_ACTIVE,
+						&ch->port.flags);
 			}
 		}
 		tty_kref_put(tty);
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/moxa.c linux-libre-2.6.30.10-gnu1/drivers/char/moxa.c
--- linux-libre-2.6.30-gnu1/drivers/char/moxa.c	2013-05-03 16:44:03.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/moxa.c	2013-05-03 17:22:55.000000000 -0400
@@ -1184,6 +1184,11 @@ static int moxa_open(struct tty_struct *
 		return -ENODEV;
 	}
 
+	if (port % MAX_PORTS_PER_BOARD >= brd->numPorts) {
+		retval = -ENODEV;
+		goto out_unlock;
+	}
+
 	ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
 	ch->port.count++;
 	tty->driver_data = ch;
@@ -1208,8 +1213,8 @@ static int moxa_open(struct tty_struct *
 				moxa_close_port(tty);
 	} else
 		ch->port.flags |= ASYNC_NORMAL_ACTIVE;
+out_unlock:
 	mutex_unlock(&moxa_openlock);
-
 	return retval;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/n_r3964.c linux-libre-2.6.30.10-gnu1/drivers/char/n_r3964.c
--- linux-libre-2.6.30-gnu1/drivers/char/n_r3964.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/n_r3964.c	2009-12-04 01:00:07.000000000 -0500
@@ -1062,7 +1062,7 @@ static ssize_t r3964_read(struct tty_str
 	struct r3964_client_info *pClient;
 	struct r3964_message *pMsg;
 	struct r3964_client_message theMsg;
-	int count;
+	int ret;
 
 	TRACE_L("read()");
 
@@ -1074,8 +1074,8 @@ static ssize_t r3964_read(struct tty_str
 		if (pMsg == NULL) {
 			/* no messages available. */
 			if (file->f_flags & O_NONBLOCK) {
-				unlock_kernel();
-				return -EAGAIN;
+				ret = -EAGAIN;
+				goto unlock;
 			}
 			/* block until there is a message: */
 			wait_event_interruptible(pInfo->read_wait,
@@ -1085,29 +1085,31 @@ static ssize_t r3964_read(struct tty_str
 		/* If we still haven't got a message, we must have been signalled */
 
 		if (!pMsg) {
-			unlock_kernel();
-			return -EINTR;
+			ret = -EINTR;
+			goto unlock;
 		}
 
 		/* deliver msg to client process: */
 		theMsg.msg_id = pMsg->msg_id;
 		theMsg.arg = pMsg->arg;
 		theMsg.error_code = pMsg->error_code;
-		count = sizeof(struct r3964_client_message);
+		ret = sizeof(struct r3964_client_message);
 
 		kfree(pMsg);
 		TRACE_M("r3964_read - msg kfree %p", pMsg);
 
-		if (copy_to_user(buf, &theMsg, count)) {
-			unlock_kernel();
-			return -EFAULT;
+		if (copy_to_user(buf, &theMsg, ret)) {
+			ret = -EFAULT;
+			goto unlock;
 		}
 
-		TRACE_PS("read - return %d", count);
-		return count;
+		TRACE_PS("read - return %d", ret);
+		goto unlock;
 	}
+	ret = -EPERM;
+unlock:
 	unlock_kernel();
-	return -EPERM;
+	return ret;
 }
 
 static ssize_t r3964_write(struct tty_struct *tty, struct file *file,
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/pcmcia/cm4000_cs.c linux-libre-2.6.30.10-gnu1/drivers/char/pcmcia/cm4000_cs.c
--- linux-libre-2.6.30-gnu1/drivers/char/pcmcia/cm4000_cs.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/pcmcia/cm4000_cs.c	2009-12-04 01:00:07.000000000 -0500
@@ -1575,7 +1575,8 @@ static long cmm_ioctl(struct file *filp,
 		clear_bit(LOCK_IO, &dev->flags);
 		wake_up_interruptible(&dev->ioq);
 
-		return 0;
+		rc = 0;
+		break;
 	case CM_IOCSPTS:
 		{
 			struct ptsreq krnptsreq;
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/rocket.c linux-libre-2.6.30.10-gnu1/drivers/char/rocket.c
--- linux-libre-2.6.30-gnu1/drivers/char/rocket.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/rocket.c	2009-12-04 01:00:07.000000000 -0500
@@ -934,7 +934,7 @@ static int rp_open(struct tty_struct *tt
 	/*
 	 * Info->count is now 1; so it's safe to sleep now.
 	 */
-	if (!test_bit(ASYNC_INITIALIZED, &port->flags)) {
+	if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {
 		cp = &info->channel;
 		sSetRxTrigger(cp, TRIG_1);
 		if (sGetChanStatus(cp) & CD_ACT)
@@ -958,7 +958,7 @@ static int rp_open(struct tty_struct *tt
 		sEnRxFIFO(cp);
 		sEnTransmit(cp);
 
-		set_bit(ASYNC_INITIALIZED, &info->port.flags);
+		set_bit(ASYNCB_INITIALIZED, &info->port.flags);
 
 		/*
 		 * Set up the tty->alt_speed kludge
@@ -1641,7 +1641,7 @@ static int rp_write(struct tty_struct *t
 	/*  Write remaining data into the port's xmit_buf */
 	while (1) {
 		/* Hung up ? */
-		if (!test_bit(ASYNC_NORMAL_ACTIVE, &info->port.flags))
+		if (!test_bit(ASYNCB_NORMAL_ACTIVE, &info->port.flags))
 			goto end;
 		c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
 		c = min(c, XMIT_BUF_SIZE - info->xmit_head);
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_tis.c linux-libre-2.6.30.10-gnu1/drivers/char/tpm/tpm_tis.c
--- linux-libre-2.6.30-gnu1/drivers/char/tpm/tpm_tis.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/tpm/tpm_tis.c	2009-12-04 01:00:07.000000000 -0500
@@ -450,6 +450,12 @@ static int tpm_tis_init(struct device *d
 		goto out_err;
 	}
 
+	/* Default timeouts */
+	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
+	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+
 	if (request_locality(chip, 0) != 0) {
 		rc = -ENODEV;
 		goto out_err;
@@ -457,12 +463,6 @@ static int tpm_tis_init(struct device *d
 
 	vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
 
-	/* Default timeouts */
-	chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-	chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
-	chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-	chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
-
 	dev_info(dev,
 		 "1.2 TPM (device-id 0x%X, rev-id %d)\n",
 		 vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/vc_screen.c linux-libre-2.6.30.10-gnu1/drivers/char/vc_screen.c
--- linux-libre-2.6.30-gnu1/drivers/char/vc_screen.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/vc_screen.c	2009-12-04 01:00:07.000000000 -0500
@@ -495,11 +495,15 @@ void vcs_remove_sysfs(int index)
 
 int __init vcs_init(void)
 {
+	unsigned int i;
+
 	if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
 		panic("unable to get major %d for vcs device", VCS_MAJOR);
 	vc_class = class_create(THIS_MODULE, "vc");
 
 	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
 	device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+	for (i = 0; i < MIN_NR_CONSOLES; i++)
+		vcs_make_sysfs(i);
 	return 0;
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/char/vt_ioctl.c linux-libre-2.6.30.10-gnu1/drivers/char/vt_ioctl.c
--- linux-libre-2.6.30-gnu1/drivers/char/vt_ioctl.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/char/vt_ioctl.c	2009-12-04 01:00:07.000000000 -0500
@@ -396,7 +396,8 @@ int vt_ioctl(struct tty_struct *tty, str
 	kbd = kbd_table + console;
 	switch (cmd) {
 	case TIOCLINUX:
-		return tioclinux(tty, arg);
+		ret = tioclinux(tty, arg);
+		break;
 	case KIOCSOUND:
 		if (!perm)
 			goto eperm;
diff -druNp linux-libre-2.6.30-gnu1/drivers/edac/x38_edac.c linux-libre-2.6.30.10-gnu1/drivers/edac/x38_edac.c
--- linux-libre-2.6.30-gnu1/drivers/edac/x38_edac.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/edac/x38_edac.c	2009-12-04 01:00:07.000000000 -0500
@@ -30,7 +30,7 @@
 /* Intel X38 register addresses - device 0 function 0 - DRAM Controller */
 
 #define X38_MCHBAR_LOW	0x48	/* MCH Memory Mapped Register BAR */
-#define X38_MCHBAR_HIGH	0x4b
+#define X38_MCHBAR_HIGH	0x4c
 #define X38_MCHBAR_MASK	0xfffffc000ULL	/* bits 35:14 */
 #define X38_MMR_WINDOW_SIZE	16384
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/firewire/fw-sbp2.c linux-libre-2.6.30.10-gnu1/drivers/firewire/fw-sbp2.c
--- linux-libre-2.6.30-gnu1/drivers/firewire/fw-sbp2.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/firewire/fw-sbp2.c	2009-12-04 01:00:07.000000000 -0500
@@ -190,6 +190,12 @@ struct sbp2_target {
 #define SBP2_CYCLE_LIMIT		(0xc8 << 12)	/* 200 125us cycles */
 
 /*
+ * There is no transport protocol limit to the CDB length,  but we implement
+ * a fixed length only.  16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE		16
+
+/*
  * The default maximum s/g segment size of a FireWire controller is
  * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
  * be quadlet-aligned, we set the length limit to 0xffff & ~3.
@@ -301,7 +307,7 @@ struct sbp2_command_orb {
 		struct sbp2_pointer next;
 		struct sbp2_pointer data_descriptor;
 		__be32 misc;
-		u8 command_block[12];
+		u8 command_block[SBP2_MAX_CDB_SIZE];
 	} request;
 	struct scsi_cmnd *cmd;
 	scsi_done_fn_t done;
@@ -1135,6 +1141,8 @@ static int sbp2_probe(struct device *dev
 	if (fw_device_enable_phys_dma(device) < 0)
 		goto fail_shost_put;
 
+	shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
+
 	if (scsi_add_host(shost, &unit->device) < 0)
 		goto fail_shost_put;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/firmware/memmap.c linux-libre-2.6.30.10-gnu1/drivers/firmware/memmap.c
--- linux-libre-2.6.30-gnu1/drivers/firmware/memmap.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/firmware/memmap.c	2009-12-04 01:00:07.000000000 -0500
@@ -31,8 +31,12 @@
  * information is necessary as for the resource tree.
  */
 struct firmware_map_entry {
-	resource_size_t		start;	/* start of the memory range */
-	resource_size_t		end;	/* end of the memory range (incl.) */
+	/*
+	 * start and end must be u64 rather than resource_size_t, because e820
+	 * resources can lie at addresses above 4G.
+	 */
+	u64			start;	/* start of the memory range */
+	u64			end;	/* end of the memory range (incl.) */
 	const char		*type;	/* type of the memory range */
 	struct list_head	list;	/* entry for the linked list */
 	struct kobject		kobj;   /* kobject for each entry */
@@ -101,7 +105,7 @@ static LIST_HEAD(map_entries);
  * Common implementation of firmware_map_add() and firmware_map_add_early()
  * which expects a pre-allocated struct firmware_map_entry.
  **/
-static int firmware_map_add_entry(resource_size_t start, resource_size_t end,
+static int firmware_map_add_entry(u64 start, u64 end,
 				  const char *type,
 				  struct firmware_map_entry *entry)
 {
@@ -132,8 +136,7 @@ static int firmware_map_add_entry(resour
  *
  * Returns 0 on success, or -ENOMEM if no memory could be allocated.
  **/
-int firmware_map_add(resource_size_t start, resource_size_t end,
-		     const char *type)
+int firmware_map_add(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
@@ -157,8 +160,7 @@ int firmware_map_add(resource_size_t sta
  *
  * Returns 0 on success, or -ENOMEM if no memory could be allocated.
  **/
-int __init firmware_map_add_early(resource_size_t start, resource_size_t end,
-				  const char *type)
+int __init firmware_map_add_early(u64 start, u64 end, const char *type)
 {
 	struct firmware_map_entry *entry;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_dma.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_dma.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_dma.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_dma.c	2009-12-04 01:00:07.000000000 -0500
@@ -1153,8 +1153,11 @@ int i915_driver_load(struct drm_device *
 #endif
 
 	dev->driver->get_vblank_counter = i915_get_vblank_counter;
-	if (IS_GM45(dev))
+	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+	if (IS_G4X(dev)) {
+		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
 		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+	}
 
 	i915_gem_load(dev);
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_drv.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_drv.c	2009-12-04 01:00:07.000000000 -0500
@@ -67,8 +67,6 @@ static int i915_suspend(struct drm_devic
 
 	pci_save_state(dev->pdev);
 
-	i915_save_state(dev);
-
 	/* If KMS is active, we do the leavevt stuff here */
 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
 		if (i915_gem_idle(dev))
@@ -77,6 +75,8 @@ static int i915_suspend(struct drm_devic
 		drm_irq_uninstall(dev);
 	}
 
+	i915_save_state(dev);
+
 	intel_opregion_free(dev, 1);
 
 	if (state.event == PM_EVENT_SUSPEND) {
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.h linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_drv.h
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_drv.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_drv.h	2009-12-04 01:00:07.000000000 -0500
@@ -285,6 +285,13 @@ typedef struct drm_i915_private {
 	u8 saveDACMASK;
 	u8 saveCR[37];
 	uint64_t saveFENCE[16];
+	u32 saveCURACNTR;
+	u32 saveCURAPOS;
+	u32 saveCURABASE;
+	u32 saveCURBCNTR;
+	u32 saveCURBPOS;
+	u32 saveCURBBASE;
+	u32 saveCURSIZE;
 
 	struct {
 		struct drm_mm gtt_space;
@@ -642,6 +649,7 @@ void i915_gem_detach_phys_object(struct
 void i915_gem_free_all_phys_object(struct drm_device *dev);
 int i915_gem_object_get_pages(struct drm_gem_object *obj);
 void i915_gem_object_put_pages(struct drm_gem_object *obj);
+void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv);
 
 /* i915_gem_tiling.c */
 void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_gem.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_gem.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_gem.c	2009-12-04 01:00:07.000000000 -0500
@@ -4154,6 +4154,7 @@ i915_gem_lastclose(struct drm_device *de
 void
 i915_gem_load(struct drm_device *dev)
 {
+	int i;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	spin_lock_init(&dev_priv->mm.active_list_lock);
@@ -4173,6 +4174,18 @@ i915_gem_load(struct drm_device *dev)
 	else
 		dev_priv->num_fence_regs = 8;
 
+	/* Initialize fence registers to zero */
+	if (IS_I965G(dev)) {
+		for (i = 0; i < 16; i++)
+			I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0);
+	} else {
+		for (i = 0; i < 8; i++)
+			I915_WRITE(FENCE_REG_830_0 + (i * 4), 0);
+		if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
+			for (i = 0; i < 8; i++)
+				I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
+	}
+
 	i915_gem_detect_bit_6_swizzle(dev);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_irq.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_irq.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_irq.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_irq.c	2009-12-04 01:00:07.000000000 -0500
@@ -572,8 +572,6 @@ int i915_driver_irq_postinstall(struct d
 
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
-	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-
 	/* Unmask the interrupts that we always want on. */
 	dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_suspend.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_suspend.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/i915_suspend.c	2009-12-04 01:00:07.000000000 -0500
@@ -295,6 +295,16 @@ int i915_save_state(struct drm_device *d
 	i915_save_palette(dev, PIPE_B);
 	dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
 
+	/* Cursor state */
+	dev_priv->saveCURACNTR = I915_READ(CURACNTR);
+	dev_priv->saveCURAPOS = I915_READ(CURAPOS);
+	dev_priv->saveCURABASE = I915_READ(CURABASE);
+	dev_priv->saveCURBCNTR = I915_READ(CURBCNTR);
+	dev_priv->saveCURBPOS = I915_READ(CURBPOS);
+	dev_priv->saveCURBBASE = I915_READ(CURBBASE);
+	if (!IS_I9XX(dev))
+		dev_priv->saveCURSIZE = I915_READ(CURSIZE);
+
 	/* CRT state */
 	dev_priv->saveADPA = I915_READ(ADPA);
 
@@ -480,6 +490,16 @@ int i915_restore_state(struct drm_device
 	I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
 	I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
 
+	/* Cursor state */
+	I915_WRITE(CURAPOS, dev_priv->saveCURAPOS);
+	I915_WRITE(CURACNTR, dev_priv->saveCURACNTR);
+	I915_WRITE(CURABASE, dev_priv->saveCURABASE);
+	I915_WRITE(CURBPOS, dev_priv->saveCURBPOS);
+	I915_WRITE(CURBCNTR, dev_priv->saveCURBCNTR);
+	I915_WRITE(CURBBASE, dev_priv->saveCURBBASE);
+	if (!IS_I9XX(dev))
+		I915_WRITE(CURSIZE, dev_priv->saveCURSIZE);
+
 	/* CRT state */
 	I915_WRITE(ADPA, dev_priv->saveADPA);
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_bios.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_bios.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_bios.c	2009-12-04 01:00:07.000000000 -0500
@@ -185,10 +185,12 @@ parse_general_features(struct drm_i915_p
 		dev_priv->lvds_use_ssc = general->enable_ssc;
 
 		if (dev_priv->lvds_use_ssc) {
-		  if (IS_I855(dev_priv->dev))
-		    dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48;
-		  else
-		    dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96;
+			if (IS_I85X(dev_priv->dev))
+				dev_priv->lvds_ssc_freq =
+					general->ssc_freq ? 66 : 48;
+			else
+				dev_priv->lvds_ssc_freq =
+					general->ssc_freq ? 100 : 96;
 		}
 	}
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_display.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_display.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_display.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_display.c	2009-12-04 01:00:07.000000000 -0500
@@ -1590,6 +1590,7 @@ struct drm_crtc *intel_get_load_detect_p
 	}
 
 	encoder->crtc = crtc;
+	intel_output->base.encoder = encoder;
 	intel_output->load_detect_temp = true;
 
 	intel_crtc = to_intel_crtc(crtc);
@@ -1625,6 +1626,7 @@ void intel_release_load_detect_pipe(stru
 
 	if (intel_output->load_detect_temp) {
 		encoder->crtc = NULL;
+		intel_output->base.encoder = NULL;
 		intel_output->load_detect_temp = false;
 		crtc->enabled = drm_helper_crtc_in_use(crtc);
 		drm_helper_disable_unused_functions(dev);
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_fb.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_fb.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_fb.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_fb.c	2009-12-04 01:00:07.000000000 -0500
@@ -857,9 +857,15 @@ void intelfb_restore(void)
 	drm_crtc_helper_set_config(&kernelfb_mode);
 }
 
+static void intelfb_restore_work_fn(struct work_struct *ignored)
+{
+	intelfb_restore();
+}
+static DECLARE_WORK(intelfb_restore_work, intelfb_restore_work_fn);
+
 static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3)
 {
-        intelfb_restore();
+        schedule_work(&intelfb_restore_work);
 }
 
 static struct sysrq_key_op sysrq_intelfb_restore_op = {
diff -druNp linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_lvds.c linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_lvds.c
--- linux-libre-2.6.30-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/gpu/drm/i915/intel_lvds.c	2009-12-04 01:00:07.000000000 -0500
@@ -420,8 +420,21 @@ static const struct dmi_system_id intel_
 			DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
 		},
 	},
-
-	/* FIXME: add a check for the Aopen Mini PC */
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "AOpen Mini PC",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "AOpen"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "i965GMx-IF"),
+		},
+	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Aopen i945GTt-VFA",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_VERSION, "AO00001JW"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
diff -druNp linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hiddev.c linux-libre-2.6.30.10-gnu1/drivers/hid/usbhid/hiddev.c
--- linux-libre-2.6.30-gnu1/drivers/hid/usbhid/hiddev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/hid/usbhid/hiddev.c	2009-12-04 01:00:07.000000000 -0500
@@ -527,8 +527,10 @@ static noinline int hiddev_ioctl_usage(s
 			goto goodreturn;
 
 		case HIDIOCGCOLLECTIONINDEX:
+			i = field->usage[uref->usage_index].collection_index;
+			unlock_kernel();
 			kfree(uref_multi);
-			return field->usage[uref->usage_index].collection_index;
+			return i;
 		case HIDIOCGUSAGES:
 			for (i = 0; i < uref_multi->num_values; i++)
 				uref_multi->values[i] =
diff -druNp linux-libre-2.6.30-gnu1/drivers/hwmon/asus_atk0110.c linux-libre-2.6.30.10-gnu1/drivers/hwmon/asus_atk0110.c
--- linux-libre-2.6.30-gnu1/drivers/hwmon/asus_atk0110.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/hwmon/asus_atk0110.c	2009-12-04 01:00:07.000000000 -0500
@@ -593,7 +593,11 @@ static int atk_add_sensor(struct atk_dat
 	sensor->data = data;
 	sensor->id = flags->integer.value;
 	sensor->limit1 = limit1->integer.value;
-	sensor->limit2 = limit2->integer.value;
+	if (data->old_interface)
+		sensor->limit2 = limit2->integer.value;
+	else
+		/* The upper limit is expressed as delta from lower limit */
+		sensor->limit2 = sensor->limit1 + limit2->integer.value;
 
 	snprintf(sensor->input_attr_name, ATTR_NAME_SIZE,
 			"%s%d_input", base_name, start + *num);
diff -druNp linux-libre-2.6.30-gnu1/drivers/hwmon/max6650.c linux-libre-2.6.30.10-gnu1/drivers/hwmon/max6650.c
--- linux-libre-2.6.30-gnu1/drivers/hwmon/max6650.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/hwmon/max6650.c	2009-12-04 01:00:07.000000000 -0500
@@ -407,6 +407,7 @@ static ssize_t set_div(struct device *de
 		data->count = 3;
 		break;
 	default:
+		mutex_unlock(&data->update_lock);
 		dev_err(&client->dev,
 			"illegal value for fan divider (%d)\n", div);
 		return -EINVAL;
diff -druNp linux-libre-2.6.30-gnu1/drivers/hwmon/smsc47m1.c linux-libre-2.6.30.10-gnu1/drivers/hwmon/smsc47m1.c
--- linux-libre-2.6.30-gnu1/drivers/hwmon/smsc47m1.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/hwmon/smsc47m1.c	2009-12-04 01:00:07.000000000 -0500
@@ -86,6 +86,7 @@ superio_exit(void)
 #define SUPERIO_REG_ACT		0x30
 #define SUPERIO_REG_BASE	0x60
 #define SUPERIO_REG_DEVID	0x20
+#define SUPERIO_REG_DEVREV	0x21
 
 /* Logical device registers */
 
@@ -429,6 +430,9 @@ static int __init smsc47m1_find(unsigned
 	 * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
 	 * supports a 3rd fan, and the pin configuration registers are
 	 * unfortunately different.
+	 * The LPC47M233 has the same device id (0x6B) but is not compatible.
+	 * We check the high bit of the device revision register to
+	 * differentiate them.
 	 */
 	switch (val) {
 	case 0x51:
@@ -448,6 +452,13 @@ static int __init smsc47m1_find(unsigned
 		sio_data->type = smsc47m1;
 		break;
 	case 0x6B:
+		if (superio_inb(SUPERIO_REG_DEVREV) & 0x80) {
+			pr_debug(DRVNAME ": "
+				 "Found SMSC LPC47M233, unsupported\n");
+			superio_exit();
+			return -ENODEV;
+		}
+
 		pr_info(DRVNAME ": Found SMSC LPC47M292\n");
 		sio_data->type = smsc47m2;
 		break;
diff -druNp linux-libre-2.6.30-gnu1/drivers/i2c/chips/tsl2550.c linux-libre-2.6.30.10-gnu1/drivers/i2c/chips/tsl2550.c
--- linux-libre-2.6.30-gnu1/drivers/i2c/chips/tsl2550.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/i2c/chips/tsl2550.c	2009-12-04 01:00:07.000000000 -0500
@@ -27,7 +27,7 @@
 #include <linux/delay.h>
 
 #define TSL2550_DRV_NAME	"tsl2550"
-#define DRIVER_VERSION		"1.1.1"
+#define DRIVER_VERSION		"1.1.2"
 
 /*
  * Defines
@@ -189,13 +189,16 @@ static int tsl2550_calculate_lux(u8 ch0,
 	u8 r = 128;
 
 	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
-	if (c0 && (c1 <= c0))
-		r = c1 * 128 / c0;
-	else
-		return -1;
+	if (c1 <= c0)
+		if (c0) {
+			r = c1 * 128 / c0;
 
-	/* Calculate LUX */
-	lux = ((c0 - c1) * ratio_lut[r]) / 256;
+			/* Calculate LUX */
+			lux = ((c0 - c1) * ratio_lut[r]) / 256;
+		} else
+			lux = 0;
+	else
+		return -EAGAIN;
 
 	/* LUX range check */
 	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
diff -druNp linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.c linux-libre-2.6.30.10-gnu1/drivers/ide/ide-cd.c
--- linux-libre-2.6.30-gnu1/drivers/ide/ide-cd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ide/ide-cd.c	2009-12-04 01:00:07.000000000 -0500
@@ -758,7 +758,7 @@ out_end:
 				rq->errors = -EIO;
 		}
 
-		if (uptodate == 0)
+		if (uptodate == 0 && rq->bio)
 			ide_cd_error_cmd(drive, cmd);
 
 		/* make sure it's fully ended */
diff -druNp linux-libre-2.6.30-gnu1/drivers/ide/ide-disk.c linux-libre-2.6.30.10-gnu1/drivers/ide/ide-disk.c
--- linux-libre-2.6.30-gnu1/drivers/ide/ide-disk.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ide/ide-disk.c	2009-12-04 01:00:07.000000000 -0500
@@ -413,6 +413,7 @@ static void idedisk_prepare_flush(struct
 	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
 	rq->cmd_flags |= REQ_SOFTBARRIER;
 	rq->special = cmd;
+	cmd->rq = rq;
 }
 
 ide_devset_get(multcount, mult_count);
diff -druNp linux-libre-2.6.30-gnu1/drivers/ide/ide-dma.c linux-libre-2.6.30.10-gnu1/drivers/ide/ide-dma.c
--- linux-libre-2.6.30-gnu1/drivers/ide/ide-dma.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ide/ide-dma.c	2009-12-04 01:00:07.000000000 -0500
@@ -362,9 +362,6 @@ static int ide_tune_dma(ide_drive_t *dri
 	if (__ide_dma_bad_drive(drive))
 		return 0;
 
-	if (ide_id_dma_bug(drive))
-		return 0;
-
 	if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
 		return config_drive_for_dma(drive);
 
@@ -395,24 +392,6 @@ static int ide_dma_check(ide_drive_t *dr
 	return -1;
 }
 
-int ide_id_dma_bug(ide_drive_t *drive)
-{
-	u16 *id = drive->id;
-
-	if (id[ATA_ID_FIELD_VALID] & 4) {
-		if ((id[ATA_ID_UDMA_MODES] >> 8) &&
-		    (id[ATA_ID_MWDMA_MODES] >> 8))
-			goto err_out;
-	} else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
-		   (id[ATA_ID_SWDMA_MODES] >> 8))
-		goto err_out;
-
-	return 0;
-err_out:
-	printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
-	return 1;
-}
-
 int ide_set_dma(ide_drive_t *drive)
 {
 	int rc;
diff -druNp linux-libre-2.6.30-gnu1/drivers/ide/ide-iops.c linux-libre-2.6.30.10-gnu1/drivers/ide/ide-iops.c
--- linux-libre-2.6.30-gnu1/drivers/ide/ide-iops.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ide/ide-iops.c	2009-12-04 01:00:07.000000000 -0500
@@ -306,9 +306,6 @@ int ide_driveid_update(ide_drive_t *driv
 
 	kfree(id);
 
-	if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive))
-		ide_dma_off(drive);
-
 	return 1;
 out_err:
 	SELECT_MASK(drive, 0);
diff -druNp linux-libre-2.6.30-gnu1/drivers/ide/ide-probe.c linux-libre-2.6.30.10-gnu1/drivers/ide/ide-probe.c
--- linux-libre-2.6.30-gnu1/drivers/ide/ide-probe.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ide/ide-probe.c	2009-12-04 01:00:07.000000000 -0500
@@ -830,6 +830,24 @@ static int ide_port_setup_devices(ide_hw
 	return j;
 }
 
+static void ide_host_enable_irqs(struct ide_host *host)
+{
+	ide_hwif_t *hwif;
+	int i;
+
+	ide_host_for_each_port(i, hwif, host) {
+		if (hwif == NULL)
+			continue;
+
+		/* clear any pending IRQs */
+		hwif->tp_ops->read_status(hwif);
+
+		/* unmask IRQs */
+		if (hwif->io_ports.ctl_addr)
+			hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
+	}
+}
+
 /*
  * This routine sets up the IRQ for an IDE interface.
  */
@@ -843,9 +861,6 @@ static int init_irq (ide_hwif_t *hwif)
 	if (irq_handler == NULL)
 		irq_handler = ide_intr;
 
-	if (io_ports->ctl_addr)
-		hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
-
 	if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
 		goto out_up;
 
@@ -1389,6 +1404,8 @@ int ide_host_register(struct ide_host *h
 			ide_port_tune_devices(hwif);
 	}
 
+	ide_host_enable_irqs(host);
+
 	ide_host_for_each_port(i, hwif, host) {
 		if (hwif == NULL)
 			continue;
diff -druNp linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.c linux-libre-2.6.30.10-gnu1/drivers/ieee1394/sbp2.c
--- linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ieee1394/sbp2.c	2009-12-04 01:00:07.000000000 -0500
@@ -880,6 +880,7 @@ static struct sbp2_lu *sbp2_alloc_device
 	}
 
 	shost->hostdata[0] = (unsigned long)lu;
+	shost->max_cmd_len = SBP2_MAX_CDB_SIZE;
 
 	if (!scsi_add_host(shost, &ud->device)) {
 		lu->shost = shost;
diff -druNp linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.h linux-libre-2.6.30.10-gnu1/drivers/ieee1394/sbp2.h
--- linux-libre-2.6.30-gnu1/drivers/ieee1394/sbp2.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ieee1394/sbp2.h	2009-12-04 01:00:07.000000000 -0500
@@ -25,6 +25,12 @@
 #define SBP2_DEVICE_NAME		"sbp2"
 
 /*
+ * There is no transport protocol limit to the CDB length,  but we implement
+ * a fixed length only.  16 bytes is enough for disks larger than 2 TB.
+ */
+#define SBP2_MAX_CDB_SIZE		16
+
+/*
  * SBP-2 specific definitions
  */
 
@@ -51,7 +57,7 @@ struct sbp2_command_orb {
 	u32 data_descriptor_hi;
 	u32 data_descriptor_lo;
 	u32 misc;
-	u8 cdb[12];
+	u8 cdb[SBP2_MAX_CDB_SIZE];
 } __attribute__((packed));
 
 #define SBP2_LOGIN_REQUEST		0x0
diff -druNp linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/qp.c linux-libre-2.6.30.10-gnu1/drivers/infiniband/hw/mlx4/qp.c
--- linux-libre-2.6.30-gnu1/drivers/infiniband/hw/mlx4/qp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/infiniband/hw/mlx4/qp.c	2009-12-04 01:00:07.000000000 -0500
@@ -1585,12 +1585,16 @@ int mlx4_ib_post_send(struct ib_qp *ibqp
 				break;
 
 			case IB_WR_LOCAL_INV:
+				ctrl->srcrb_flags |=
+					cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
 				set_local_inv_seg(wqe, wr->ex.invalidate_rkey);
 				wqe  += sizeof (struct mlx4_wqe_local_inval_seg);
 				size += sizeof (struct mlx4_wqe_local_inval_seg) / 16;
 				break;
 
 			case IB_WR_FAST_REG_MR:
+				ctrl->srcrb_flags |=
+					cpu_to_be32(MLX4_WQE_CTRL_STRONG_ORDER);
 				set_fmr_seg(wqe, wr);
 				wqe  += sizeof (struct mlx4_wqe_fmr_seg);
 				size += sizeof (struct mlx4_wqe_fmr_seg) / 16;
diff -druNp linux-libre-2.6.30-gnu1/drivers/input/joydev.c linux-libre-2.6.30.10-gnu1/drivers/input/joydev.c
--- linux-libre-2.6.30-gnu1/drivers/input/joydev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/input/joydev.c	2009-12-04 01:00:07.000000000 -0500
@@ -457,8 +457,11 @@ static int joydev_ioctl_common(struct jo
 				unsigned int cmd, void __user *argp)
 {
 	struct input_dev *dev = joydev->handle.dev;
+	size_t len;
 	int i, j;
+	const char *name;
 
+	/* Process fixed-sized commands. */
 	switch (cmd) {
 
 	case JS_SET_CAL:
@@ -500,9 +503,22 @@ static int joydev_ioctl_common(struct jo
 		return copy_to_user(argp, joydev->corr,
 			sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
 
-	case JSIOCSAXMAP:
-		if (copy_from_user(joydev->abspam, argp,
-				   sizeof(__u8) * (ABS_MAX + 1)))
+	}
+
+	/*
+	 * Process variable-sized commands (the axis and button map commands
+	 * are considered variable-sized to decouple them from the values of
+	 * ABS_MAX and KEY_MAX).
+	 */
+	switch (cmd & ~IOCSIZE_MASK) {
+
+	case (JSIOCSAXMAP & ~IOCSIZE_MASK):
+		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+		/*
+		 * FIXME: we should not copy into our axis map before
+		 * validating the data.
+		 */
+		if (copy_from_user(joydev->abspam, argp, len))
 			return -EFAULT;
 
 		for (i = 0; i < joydev->nabs; i++) {
@@ -512,13 +528,17 @@ static int joydev_ioctl_common(struct jo
 		}
 		return 0;
 
-	case JSIOCGAXMAP:
-		return copy_to_user(argp, joydev->abspam,
-			sizeof(__u8) * (ABS_MAX + 1)) ? -EFAULT : 0;
+	case (JSIOCGAXMAP & ~IOCSIZE_MASK):
+		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
+		return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : 0;
 
-	case JSIOCSBTNMAP:
-		if (copy_from_user(joydev->keypam, argp,
-				   sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)))
+	case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
+		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+		/*
+		 * FIXME: we should not copy into our keymap before
+		 * validating the data.
+		 */
+		if (copy_from_user(joydev->keypam, argp, len))
 			return -EFAULT;
 
 		for (i = 0; i < joydev->nkey; i++) {
@@ -530,23 +550,19 @@ static int joydev_ioctl_common(struct jo
 
 		return 0;
 
-	case JSIOCGBTNMAP:
-		return copy_to_user(argp, joydev->keypam,
-			sizeof(__u16) * (KEY_MAX - BTN_MISC + 1)) ? -EFAULT : 0;
+	case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
+		len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
+		return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : 0;
 
-	default:
-		if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) {
-			int len;
-			if (!dev->name)
-				return 0;
-			len = strlen(dev->name) + 1;
-			if (len > _IOC_SIZE(cmd))
-				len = _IOC_SIZE(cmd);
-			if (copy_to_user(argp, dev->name, len))
-				return -EFAULT;
-			return len;
-		}
+	case JSIOCGNAME(0):
+		name = dev->name;
+		if (!name)
+			return 0;
+
+		len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
+		return copy_to_user(argp, name, len) ? -EFAULT : len;
 	}
+
 	return -EINVAL;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/input/misc/wistron_btns.c linux-libre-2.6.30.10-gnu1/drivers/input/misc/wistron_btns.c
--- linux-libre-2.6.30-gnu1/drivers/input/misc/wistron_btns.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/input/misc/wistron_btns.c	2009-12-04 01:00:07.000000000 -0500
@@ -646,6 +646,15 @@ static struct dmi_system_id dmi_ids[] __
 	},
 	{
 		.callback = dmi_matched,
+		.ident = "Maxdata Pro 7000 DX",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MAXDATA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Pro 7000"),
+		},
+		.driver_data = keymap_fs_amilo_pro_v2000
+	},
+	{
+		.callback = dmi_matched,
 		.ident = "Fujitsu N3510",
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
diff -druNp linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/ev-layer.c linux-libre-2.6.30.10-gnu1/drivers/isdn/gigaset/ev-layer.c
--- linux-libre-2.6.30-gnu1/drivers/isdn/gigaset/ev-layer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/isdn/gigaset/ev-layer.c	2009-12-04 01:00:07.000000000 -0500
@@ -294,32 +294,33 @@ struct reply_t gigaset_tab_cid_m10x[] =
 	{RSP_OK,      604,604, -1,                605, 5, {ACT_CMD+AT_MSN}},
 	{RSP_OK,      605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
 	{RSP_NULL,    605,605, -1,                606, 5, {ACT_CMD+AT_ISO}},
-	{RSP_OK,      606,606, -1,                607, 5, {0},             "+VLS=17\r"}, /* set "Endgeraetemodus" */
+	{RSP_OK,      606,606, -1,                607, 5, {0}, "+VLS=17\r"},
 	{RSP_OK,      607,607, -1,                608,-1},
-	//{RSP_ZSAU,    608,608,ZSAU_PROCEEDING,    608, 0, {ACT_ERROR}},//DELETE
 	{RSP_ZSAU,    608,608,ZSAU_PROCEEDING,    609, 5, {ACT_CMD+AT_DIAL}},
 	{RSP_OK,      609,609, -1,                650, 0, {ACT_DIALING}},
 
-	{RSP_ZVLS,    608,608, 17,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZCTP,    609,609, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZCPN,    609,609, -1,                 -1,-1, {ACT_DEBUG}},
 	{RSP_ERROR,   601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
 	{EV_TIMEOUT,  601,609, -1,                  0, 0, {ACT_ABORTDIAL}},
 
-	/* dialing */
-	{RSP_ZCTP,    650,650, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZCPN,    650,650, -1,                 -1,-1, {ACT_DEBUG}},
-	{RSP_ZSAU,    650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */
-
-	/* connection established  */
-	{RSP_ZSAU,    650,650,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
-	{RSP_ZSAU,    750,750,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}}, //FIXME -> DLE1
+	/* optional dialing responses */
+	{EV_BC_OPEN,  650,650, -1,                651,-1},
+	{RSP_ZVLS,    608,651, 17,                 -1,-1, {ACT_DEBUG}},
+	{RSP_ZCTP,    609,651, -1,                 -1,-1, {ACT_DEBUG}},
+	{RSP_ZCPN,    609,651, -1,                 -1,-1, {ACT_DEBUG}},
+	{RSP_ZSAU,    650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
 
-	{EV_BC_OPEN,  800,800, -1,                800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout
+	/* connect */
+	{RSP_ZSAU,    650,650,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}},
+	{RSP_ZSAU,    651,651,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT,
+							   ACT_NOTIFY_BC_UP}},
+	{RSP_ZSAU,    750,750,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT}},
+	{RSP_ZSAU,    751,751,ZSAU_ACTIVE,        800,-1, {ACT_CONNECT,
+							   ACT_NOTIFY_BC_UP}},
+	{EV_BC_OPEN,  800,800, -1,                800,-1, {ACT_NOTIFY_BC_UP}},
 
 	/* remote hangup */
-	{RSP_ZSAU,    650,650,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEREJECT}},
-	{RSP_ZSAU,    750,750,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
+	{RSP_ZSAU,    650,651,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEREJECT}},
+	{RSP_ZSAU,    750,751,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
 	{RSP_ZSAU,    800,800,ZSAU_DISCONNECT_IND,  0, 0, {ACT_REMOTEHUP}},
 
 	/* hangup */
@@ -358,7 +359,8 @@ struct reply_t gigaset_tab_cid_m10x[] =
 	{RSP_ZSAU,    700,729,ZSAU_ACTIVE,          0, 0, {ACT_ABORTACCEPT}},
 	{RSP_ZSAU,    700,729,ZSAU_DISCONNECT_IND,  0, 0, {ACT_ABORTACCEPT}},
 
-	{EV_TIMEOUT,  750,750, -1,                  0, 0, {ACT_CONNTIMEOUT}},
+	{EV_BC_OPEN,  750,750, -1,                751,-1},
+	{EV_TIMEOUT,  750,751, -1,                  0, 0, {ACT_CONNTIMEOUT}},
 
 	/* B channel closed (general case) */
 	{EV_BC_CLOSED, -1, -1, -1,                 -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
@@ -876,12 +878,6 @@ static void bchannel_down(struct bc_stat
 
 static void bchannel_up(struct bc_state *bcs)
 {
-	if (!(bcs->chstate & CHS_D_UP)) {
-		dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__);
-		bcs->chstate |= CHS_D_UP;
-		gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
-	}
-
 	if (bcs->chstate & CHS_B_UP) {
 		dev_notice(bcs->cs->dev, "%s: B channel already up\n",
 			   __func__);
diff -druNp linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hfc_pci.c linux-libre-2.6.30.10-gnu1/drivers/isdn/hisax/hfc_pci.c
--- linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hfc_pci.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/isdn/hisax/hfc_pci.c	2009-12-04 01:00:07.000000000 -0500
@@ -82,8 +82,9 @@ release_io_hfcpci(struct IsdnCardState *
 	Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
 	pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0);	/* disable memory mapped ports + busmaster */
 	del_timer(&cs->hw.hfcpci.timer);
-	kfree(cs->hw.hfcpci.share_start);
-	cs->hw.hfcpci.share_start = NULL;
+	pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
+		cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+	cs->hw.hfcpci.fifos = NULL;
 	iounmap((void *)cs->hw.hfcpci.pci_io);
 }
 
@@ -1663,8 +1664,19 @@ setup_hfcpci(struct IsdnCard *card)
 					     dev_hfcpci);
 		i++;
 		if (tmp_hfcpci) {
+			dma_addr_t	dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL;
 			if (pci_enable_device(tmp_hfcpci))
 				continue;
+			if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) {
+				printk(KERN_WARNING
+					"HiSax hfc_pci: No suitable DMA available.\n");
+				continue;
+			}
+			if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) {
+				printk(KERN_WARNING
+					"HiSax hfc_pci: No suitable consistent DMA available.\n");
+				continue;
+			}
 			pci_set_master(tmp_hfcpci);
 			if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
 				continue;
@@ -1693,22 +1705,29 @@ setup_hfcpci(struct IsdnCard *card)
 		printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
 		return (0);
 	}
+
 	/* Allocate memory for FIFOS */
-	/* Because the HFC-PCI needs a 32K physical alignment, we */
-	/* need to allocate the double mem and align the address */
-	if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) {
-		printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
+	cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev,
+					0x8000, &cs->hw.hfcpci.dma);
+	if (!cs->hw.hfcpci.fifos) {
+		printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n");
 		return 0;
 	}
-	cs->hw.hfcpci.fifos = (void *)
-	    (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;
-	pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));
+	if (cs->hw.hfcpci.dma & 0x7fff) {
+		printk(KERN_WARNING
+		    "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
+		    (u_long)cs->hw.hfcpci.dma);
+		pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
+			cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+		return 0;
+	}
+	pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma);
 	cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
 	printk(KERN_INFO
-	       "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n",
+	       "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n",
 	       cs->hw.hfcpci.pci_io,
 	       cs->hw.hfcpci.fifos,
-	       (u_int) virt_to_bus(cs->hw.hfcpci.fifos),
+	       (u_long)cs->hw.hfcpci.dma,
 	       cs->irq, HZ);
 
 	spin_lock_irqsave(&cs->lock, flags);
diff -druNp linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hisax.h linux-libre-2.6.30.10-gnu1/drivers/isdn/hisax/hisax.h
--- linux-libre-2.6.30-gnu1/drivers/isdn/hisax/hisax.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/isdn/hisax/hisax.h	2009-12-04 01:00:07.000000000 -0500
@@ -703,7 +703,7 @@ struct hfcPCI_hw {
         int nt_timer;
         struct pci_dev *dev;
         unsigned char *pci_io; /* start of PCI IO memory */
-        void *share_start; /* shared memory for Fifos start */
+	dma_addr_t dma; /* dma handle for Fifos */
         void *fifos; /* FIFO memory */ 
         int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
 	struct timer_list timer;
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm.c linux-libre-2.6.30.10-gnu1/drivers/md/dm.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm.c	2009-12-04 01:00:07.000000000 -0500
@@ -1780,6 +1780,10 @@ struct mapped_device *dm_get_from_kobjec
 	if (&md->kobj != kobj)
 		return NULL;
 
+	if (test_bit(DMF_FREEING, &md->flags) ||
+	    test_bit(DMF_DELETING, &md->flags))
+		return NULL;
+
 	dm_get(md);
 	return md;
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-exception-store.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-exception-store.c	2009-12-04 01:00:07.000000000 -0500
@@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exce
 	 */
 	chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
 
+	return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
+						 error);
+}
+
+int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
+				      unsigned long chunk_size_ulong,
+				      char **error)
+{
 	/* Check chunk_size is a power of 2 */
 	if (!is_power_of_2(chunk_size_ulong)) {
 		*error = "Chunk size is not a power of 2";
@@ -183,6 +191,11 @@ static int set_chunk_size(struct dm_exce
 		return -EINVAL;
 	}
 
+	if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
+		*error = "Chunk size is too high";
+		return -EINVAL;
+	}
+
 	store->chunk_size = chunk_size_ulong;
 	store->chunk_mask = chunk_size_ulong - 1;
 	store->chunk_shift = ffs(chunk_size_ulong) - 1;
@@ -195,7 +208,7 @@ int dm_exception_store_create(struct dm_
 			      struct dm_exception_store **store)
 {
 	int r = 0;
-	struct dm_exception_store_type *type;
+	struct dm_exception_store_type *type = NULL;
 	struct dm_exception_store *tmp_store;
 	char persistent;
 
@@ -211,12 +224,15 @@ int dm_exception_store_create(struct dm_
 	}
 
 	persistent = toupper(*argv[1]);
-	if (persistent != 'P' && persistent != 'N') {
+	if (persistent == 'P')
+		type = get_type("P");
+	else if (persistent == 'N')
+		type = get_type("N");
+	else {
 		ti->error = "Persistent flag is not P or N";
 		return -EINVAL;
 	}
 
-	type = get_type(argv[1]);
 	if (!type) {
 		ti->error = "Exception store type not recognised";
 		r = -EINVAL;
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.h linux-libre-2.6.30.10-gnu1/drivers/md/dm-exception-store.h
--- linux-libre-2.6.30-gnu1/drivers/md/dm-exception-store.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-exception-store.h	2009-12-04 01:00:07.000000000 -0500
@@ -156,7 +156,7 @@ static inline void dm_consecutive_chunk_
  */
 static inline sector_t get_dev_size(struct block_device *bdev)
 {
-	return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+	return i_size_read(bdev->bd_inode) >> SECTOR_SHIFT;
 }
 
 static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
@@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(st
 int dm_exception_store_type_register(struct dm_exception_store_type *type);
 int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
 
+int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
+				      unsigned long chunk_size_ulong,
+				      char **error);
+
 int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
 			      unsigned *args_used,
 			      struct dm_exception_store **store);
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-log.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-log.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-log.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-log.c	2009-12-04 01:00:07.000000000 -0500
@@ -415,7 +415,7 @@ static int create_log_context(struct dm_
 		buf_size = dm_round_up((LOG_OFFSET << SECTOR_SHIFT) +
 				       bitset_size, ti->limits.hardsect_size);
 
-		if (buf_size > dev->bdev->bd_inode->i_size) {
+		if (buf_size > i_size_read(dev->bdev->bd_inode)) {
 			DMWARN("log device %s too small: need %llu bytes",
 				dev->name, (unsigned long long)buf_size);
 			kfree(lc);
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-mpath.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-mpath.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-mpath.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-mpath.c	2009-12-04 01:00:07.000000000 -0500
@@ -553,6 +553,12 @@ static int parse_path_selector(struct ar
 		return -EINVAL;
 	}
 
+	if (ps_argc > as->argc) {
+		dm_put_path_selector(pst);
+		ti->error = "not enough arguments for path selector";
+		return -EINVAL;
+	}
+
 	r = pst->create(&pg->ps, ps_argc, as->argv);
 	if (r) {
 		dm_put_path_selector(pst);
@@ -699,6 +705,11 @@ static int parse_hw_handler(struct arg_s
 	if (!hw_argc)
 		return 0;
 
+	if (hw_argc > as->argc) {
+		ti->error = "not enough arguments for hardware handler";
+		return -EINVAL;
+	}
+
 	m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL);
 	request_module("scsi_dh_%s", m->hw_handler_name);
 	if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
@@ -836,6 +847,7 @@ static void multipath_dtr(struct dm_targ
 
 	flush_workqueue(kmpath_handlerd);
 	flush_workqueue(kmultipathd);
+	flush_scheduled_work();
 	free_multipath(m);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-raid1.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-raid1.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-raid1.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-raid1.c	2009-12-04 01:00:07.000000000 -0500
@@ -638,6 +638,7 @@ static void do_writes(struct mirror_set
 		spin_lock_irq(&ms->lock);
 		bio_list_merge(&ms->writes, &requeue);
 		spin_unlock_irq(&ms->lock);
+		delayed_wake(ms);
 	}
 
 	/*
@@ -647,7 +648,13 @@ static void do_writes(struct mirror_set
 	 */
 	dm_rh_inc_pending(ms->rh, &sync);
 	dm_rh_inc_pending(ms->rh, &nosync);
-	ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0;
+
+	/*
+	 * If the flush fails on a previous call and succeeds here,
+	 * we must not reset the log_failure variable.  We need
+	 * userspace interaction to do that.
+	 */
+	ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;
 
 	/*
 	 * Dispatch io.
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-snap-persistent.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-snap-persistent.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-snap-persistent.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-snap-persistent.c	2009-12-04 01:00:07.000000000 -0500
@@ -106,6 +106,13 @@ struct pstore {
 	void *zero_area;
 
 	/*
+	 * An area used for header. The header can be written
+	 * concurrently with metadata (when invalidating the snapshot),
+	 * so it needs a separate buffer.
+	 */
+	void *header_area;
+
+	/*
 	 * Used to keep track of which metadata area the data in
 	 * 'chunk' refers to.
 	 */
@@ -148,16 +155,27 @@ static int alloc_area(struct pstore *ps)
 	 */
 	ps->area = vmalloc(len);
 	if (!ps->area)
-		return r;
+		goto err_area;
 
 	ps->zero_area = vmalloc(len);
-	if (!ps->zero_area) {
-		vfree(ps->area);
-		return r;
-	}
+	if (!ps->zero_area)
+		goto err_zero_area;
 	memset(ps->zero_area, 0, len);
 
+	ps->header_area = vmalloc(len);
+	if (!ps->header_area)
+		goto err_header_area;
+
 	return 0;
+
+err_header_area:
+	vfree(ps->zero_area);
+
+err_zero_area:
+	vfree(ps->area);
+
+err_area:
+	return r;
 }
 
 static void free_area(struct pstore *ps)
@@ -169,6 +187,10 @@ static void free_area(struct pstore *ps)
 	if (ps->zero_area)
 		vfree(ps->zero_area);
 	ps->zero_area = NULL;
+
+	if (ps->header_area)
+		vfree(ps->header_area);
+	ps->header_area = NULL;
 }
 
 struct mdata_req {
@@ -188,7 +210,8 @@ static void do_metadata(struct work_stru
 /*
  * Read or write a chunk aligned and sized block of data from a device.
  */
-static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
+static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
+		    int metadata)
 {
 	struct dm_io_region where = {
 		.bdev = ps->store->cow->bdev,
@@ -198,7 +221,7 @@ static int chunk_io(struct pstore *ps, c
 	struct dm_io_request io_req = {
 		.bi_rw = rw,
 		.mem.type = DM_IO_VMA,
-		.mem.ptr.vma = ps->area,
+		.mem.ptr.vma = area,
 		.client = ps->io_client,
 		.notify.fn = NULL,
 	};
@@ -240,7 +263,7 @@ static int area_io(struct pstore *ps, in
 
 	chunk = area_location(ps, ps->current_area);
 
-	r = chunk_io(ps, chunk, rw, 0);
+	r = chunk_io(ps, ps->area, chunk, rw, 0);
 	if (r)
 		return r;
 
@@ -254,20 +277,7 @@ static void zero_memory_area(struct psto
 
 static int zero_disk_area(struct pstore *ps, chunk_t area)
 {
-	struct dm_io_region where = {
-		.bdev = ps->store->cow->bdev,
-		.sector = ps->store->chunk_size * area_location(ps, area),
-		.count = ps->store->chunk_size,
-	};
-	struct dm_io_request io_req = {
-		.bi_rw = WRITE,
-		.mem.type = DM_IO_VMA,
-		.mem.ptr.vma = ps->zero_area,
-		.client = ps->io_client,
-		.notify.fn = NULL,
-	};
-
-	return dm_io(&io_req, 1, &where, NULL);
+	return chunk_io(ps, ps->zero_area, area_location(ps, area), WRITE, 0);
 }
 
 static int read_header(struct pstore *ps, int *new_snapshot)
@@ -276,6 +286,7 @@ static int read_header(struct pstore *ps
 	struct disk_header *dh;
 	chunk_t chunk_size;
 	int chunk_size_supplied = 1;
+	char *chunk_err;
 
 	/*
 	 * Use default chunk size (or hardsect_size, if larger) if none supplied
@@ -297,11 +308,11 @@ static int read_header(struct pstore *ps
 	if (r)
 		return r;
 
-	r = chunk_io(ps, 0, READ, 1);
+	r = chunk_io(ps, ps->header_area, 0, READ, 1);
 	if (r)
 		goto bad;
 
-	dh = (struct disk_header *) ps->area;
+	dh = ps->header_area;
 
 	if (le32_to_cpu(dh->magic) == 0) {
 		*new_snapshot = 1;
@@ -319,20 +330,25 @@ static int read_header(struct pstore *ps
 	ps->version = le32_to_cpu(dh->version);
 	chunk_size = le32_to_cpu(dh->chunk_size);
 
-	if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
+	if (ps->store->chunk_size == chunk_size)
 		return 0;
 
-	DMWARN("chunk size %llu in device metadata overrides "
-	       "table chunk size of %llu.",
-	       (unsigned long long)chunk_size,
-	       (unsigned long long)ps->store->chunk_size);
+	if (chunk_size_supplied)
+		DMWARN("chunk size %llu in device metadata overrides "
+		       "table chunk size of %llu.",
+		       (unsigned long long)chunk_size,
+		       (unsigned long long)ps->store->chunk_size);
 
 	/* We had a bogus chunk_size. Fix stuff up. */
 	free_area(ps);
 
-	ps->store->chunk_size = chunk_size;
-	ps->store->chunk_mask = chunk_size - 1;
-	ps->store->chunk_shift = ffs(chunk_size) - 1;
+	r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
+					      &chunk_err);
+	if (r) {
+		DMERR("invalid on-disk chunk size %llu: %s.",
+		      (unsigned long long)chunk_size, chunk_err);
+		return r;
+	}
 
 	r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
 				ps->io_client);
@@ -351,15 +367,15 @@ static int write_header(struct pstore *p
 {
 	struct disk_header *dh;
 
-	memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
+	memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT);
 
-	dh = (struct disk_header *) ps->area;
+	dh = ps->header_area;
 	dh->magic = cpu_to_le32(SNAP_MAGIC);
 	dh->valid = cpu_to_le32(ps->valid);
 	dh->version = cpu_to_le32(ps->version);
 	dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
 
-	return chunk_io(ps, 0, WRITE, 1);
+	return chunk_io(ps, ps->header_area, 0, WRITE, 1);
 }
 
 /*
@@ -679,6 +695,8 @@ static int persistent_ctr(struct dm_exce
 	ps->valid = 1;
 	ps->version = SNAPSHOT_DISK_VERSION;
 	ps->area = NULL;
+	ps->zero_area = NULL;
+	ps->header_area = NULL;
 	ps->next_free = 2;	/* skipping the header and first area */
 	ps->current_committed = 0;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/dm-table.c linux-libre-2.6.30.10-gnu1/drivers/md/dm-table.c
--- linux-libre-2.6.30-gnu1/drivers/md/dm-table.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/dm-table.c	2009-12-04 01:00:07.000000000 -0500
@@ -387,7 +387,8 @@ static void close_dev(struct dm_dev_inte
 static int check_device_area(struct dm_dev_internal *dd, sector_t start,
 			     sector_t len)
 {
-	sector_t dev_size = dd->dm_dev.bdev->bd_inode->i_size >> SECTOR_SHIFT;
+	sector_t dev_size = i_size_read(dd->dm_dev.bdev->bd_inode) >>
+			    SECTOR_SHIFT;
 
 	if (!dev_size)
 		return 1;
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/md.c linux-libre-2.6.30.10-gnu1/drivers/md/md.c
--- linux-libre-2.6.30-gnu1/drivers/md/md.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/md.c	2009-12-04 01:00:07.000000000 -0500
@@ -1410,8 +1410,14 @@ static void super_1_sync(mddev_t *mddev,
 		if (rdev2->desc_nr+1 > max_dev)
 			max_dev = rdev2->desc_nr+1;
 
-	if (max_dev > le32_to_cpu(sb->max_dev))
+	if (max_dev > le32_to_cpu(sb->max_dev)) {
+		int bmask;
 		sb->max_dev = cpu_to_le32(max_dev);
+		rdev->sb_size = max_dev * 2 + 256;
+		bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
+		if (rdev->sb_size & bmask)
+			rdev->sb_size = (rdev->sb_size | bmask) + 1;
+	}
 	for (i=0; i<max_dev;i++)
 		sb->dev_roles[i] = cpu_to_le16(0xfffe);
 	
@@ -2680,6 +2686,7 @@ level_store(mddev_t *mddev, const char *
 	ssize_t rv = len;
 	struct mdk_personality *pers;
 	void *priv;
+	mdk_rdev_t *rdev;
 
 	if (mddev->pers == NULL) {
 		if (len == 0)
@@ -2759,6 +2766,12 @@ level_store(mddev_t *mddev, const char *
 	mddev_suspend(mddev);
 	mddev->pers->stop(mddev);
 	module_put(mddev->pers->owner);
+	/* Invalidate devices that are now superfluous */
+	list_for_each_entry(rdev, &mddev->disks, same_set)
+		if (rdev->raid_disk >= mddev->raid_disks) {
+			rdev->raid_disk = -1;
+			clear_bit(In_sync, &rdev->flags);
+		}
 	mddev->pers = pers;
 	mddev->private = priv;
 	strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
@@ -3589,7 +3602,8 @@ suspend_lo_store(mddev_t *mddev, const c
 	char *e;
 	unsigned long long new = simple_strtoull(buf, &e, 10);
 
-	if (mddev->pers->quiesce == NULL)
+	if (mddev->pers == NULL ||
+	    mddev->pers->quiesce == NULL)
 		return -EINVAL;
 	if (buf == e || (*e && *e != '\n'))
 		return -EINVAL;
@@ -3617,7 +3631,8 @@ suspend_hi_store(mddev_t *mddev, const c
 	char *e;
 	unsigned long long new = simple_strtoull(buf, &e, 10);
 
-	if (mddev->pers->quiesce == NULL)
+	if (mddev->pers == NULL ||
+	    mddev->pers->quiesce == NULL)
 		return -EINVAL;
 	if (buf == e || (*e && *e != '\n'))
 		return -EINVAL;
@@ -3876,6 +3891,8 @@ static int md_alloc(dev_t dev, char *nam
 			if (mddev2->gendisk &&
 			    strcmp(mddev2->gendisk->disk_name, name) == 0) {
 				spin_unlock(&all_mddevs_lock);
+				mutex_unlock(&disks_mutex);
+				mddev_put(mddev);
 				return -EEXIST;
 			}
 		spin_unlock(&all_mddevs_lock);
diff -druNp linux-libre-2.6.30-gnu1/drivers/md/raid5.c linux-libre-2.6.30.10-gnu1/drivers/md/raid5.c
--- linux-libre-2.6.30-gnu1/drivers/md/raid5.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/md/raid5.c	2009-12-04 01:00:07.000000000 -0500
@@ -3696,13 +3696,15 @@ static int make_request(struct request_q
 				spin_unlock_irq(&conf->device_lock);
 				if (must_retry) {
 					release_stripe(sh);
+					schedule();
 					goto retry;
 				}
 			}
 			/* FIXME what if we get a false positive because these
 			 * are being updated.
 			 */
-			if (logical_sector >= mddev->suspend_lo &&
+			if (bio_data_dir(bi) == WRITE &&
+			    logical_sector >= mddev->suspend_lo &&
 			    logical_sector < mddev->suspend_hi) {
 				release_stripe(sh);
 				schedule();
@@ -4308,6 +4310,15 @@ raid5_size(mddev_t *mddev, sector_t sect
 	return sectors * (raid_disks - conf->max_degraded);
 }
 
+static void free_conf(raid5_conf_t *conf)
+{
+	shrink_stripes(conf);
+	safe_put_page(conf->spare_page);
+	kfree(conf->disks);
+	kfree(conf->stripe_hashtbl);
+	kfree(conf);
+}
+
 static raid5_conf_t *setup_conf(mddev_t *mddev)
 {
 	raid5_conf_t *conf;
@@ -4437,11 +4448,7 @@ static raid5_conf_t *setup_conf(mddev_t
 
  abort:
 	if (conf) {
-		shrink_stripes(conf);
-		safe_put_page(conf->spare_page);
-		kfree(conf->disks);
-		kfree(conf->stripe_hashtbl);
-		kfree(conf);
+		free_conf(conf);
 		return ERR_PTR(-EIO);
 	} else
 		return ERR_PTR(-ENOMEM);
@@ -4607,12 +4614,8 @@ abort:
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
 	if (conf) {
-		shrink_stripes(conf);
 		print_raid5_conf(conf);
-		safe_put_page(conf->spare_page);
-		kfree(conf->disks);
-		kfree(conf->stripe_hashtbl);
-		kfree(conf);
+		free_conf(conf);
 	}
 	mddev->private = NULL;
 	printk(KERN_ALERT "raid5: failed to run raid set %s\n", mdname(mddev));
@@ -4627,13 +4630,10 @@ static int stop(mddev_t *mddev)
 
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
-	shrink_stripes(conf);
-	kfree(conf->stripe_hashtbl);
 	mddev->queue->backing_dev_info.congested_fn = NULL;
 	blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
 	sysfs_remove_group(&mddev->kobj, &raid5_attrs_group);
-	kfree(conf->disks);
-	kfree(conf);
+	free_conf(conf);
 	mddev->private = NULL;
 	return 0;
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.c linux-libre-2.6.30.10-gnu1/drivers/media/dvb/frontends/lgdt3305.c
--- linux-libre-2.6.30-gnu1/drivers/media/dvb/frontends/lgdt3305.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/dvb/frontends/lgdt3305.c	2009-12-04 01:00:07.000000000 -0500
@@ -19,6 +19,7 @@
  *
  */
 
+#include <asm/div64.h>
 #include <linux/dvb/frontend.h>
 #include "dvb_math.h"
 #include "lgdt3305.h"
@@ -496,27 +497,15 @@ static int lgdt3305_set_if(struct lgdt33
 
 	nco = if_freq_khz / 10;
 
-#define LGDT3305_64BIT_DIVISION_ENABLED 0
-	/* FIXME: 64bit division disabled to avoid linking error:
-	 * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
-	 */
 	switch (param->u.vsb.modulation) {
 	case VSB_8:
-#if LGDT3305_64BIT_DIVISION_ENABLED
 		nco <<= 24;
-		nco /= 625;
-#else
-		nco *= ((1 << 24) / 625);
-#endif
+		do_div(nco, 625);
 		break;
 	case QAM_64:
 	case QAM_256:
-#if LGDT3305_64BIT_DIVISION_ENABLED
 		nco <<= 28;
-		nco /= 625;
-#else
-		nco *= ((1 << 28) / 625);
-#endif
+		do_div(nco, 625);
 		break;
 	default:
 		return -EINVAL;
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-controls.c linux-libre-2.6.30.10-gnu1/drivers/media/video/cx18/cx18-controls.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/cx18/cx18-controls.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/cx18/cx18-controls.c	2009-12-04 01:00:07.000000000 -0500
@@ -61,6 +61,8 @@ int cx18_queryctrl(struct file *file, vo
 
 	switch (qctrl->id) {
 	/* Standard V4L2 controls */
+	case V4L2_CID_USER_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_BRIGHTNESS:
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/cx2341x.c linux-libre-2.6.30.10-gnu1/drivers/media/video/cx2341x.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/cx2341x.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/cx2341x.c	2009-12-04 01:00:07.000000000 -0500
@@ -500,6 +500,8 @@ int cx2341x_ctrl_query(const struct cx23
 	int err;
 
 	switch (qctrl->id) {
+	case V4L2_CID_MPEG_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_MPEG_STREAM_TYPE:
 		return v4l2_ctrl_query_fill(qctrl,
 				V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-cards.c linux-libre-2.6.30.10-gnu1/drivers/media/video/em28xx/em28xx-cards.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 16:44:18.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/em28xx/em28xx-cards.c	2013-05-03 17:23:10.000000000 -0400
@@ -1886,6 +1886,9 @@ void em28xx_card_setup(struct em28xx *de
 	if (em28xx_boards[dev->model].tuner_addr)
 		dev->tuner_addr = em28xx_boards[dev->model].tuner_addr;
 
+	if (em28xx_boards[dev->model].tda9887_conf)
+		dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
+
 	/* request some modules */
 	switch (dev->model) {
 	case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov534.c linux-libre-2.6.30.10-gnu1/drivers/media/video/gspca/ov534.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/gspca/ov534.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/gspca/ov534.c	2009-12-04 01:00:07.000000000 -0500
@@ -832,9 +832,11 @@ static void sd_pkt_scan(struct gspca_dev
 	__u32 this_pts;
 	u16 this_fid;
 	int remaining_len = len;
+	int payload_len;
 
+	payload_len = (sd->sensor == SENSOR_OV772X) ? 2048 : 2040;
 	do {
-		len = min(remaining_len, 2040);		/*fixme: was 2048*/
+		len = min(remaining_len, payload_len);
 
 		/* Payloads are prefixed with a UVC-style header.  We
 		   consider a frame to start when the FID toggles, or the PTS
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-controls.c linux-libre-2.6.30.10-gnu1/drivers/media/video/ivtv/ivtv-controls.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/ivtv/ivtv-controls.c	2009-12-04 01:00:07.000000000 -0500
@@ -60,6 +60,8 @@ int ivtv_queryctrl(struct file *file, vo
 
 	switch (qctrl->id) {
 	/* Standard V4L2 controls */
+	case V4L2_CID_USER_CLASS:
+		return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
 	case V4L2_CID_BRIGHTNESS:
 	case V4L2_CID_HUE:
 	case V4L2_CID_SATURATION:
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/Makefile linux-libre-2.6.30.10-gnu1/drivers/media/video/Makefile
--- linux-libre-2.6.30-gnu1/drivers/media/video/Makefile	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/Makefile	2009-12-04 01:00:07.000000000 -0500
@@ -12,6 +12,8 @@ omap2cam-objs	:=	omap24xxcam.o omap24xxc
 
 videodev-objs	:=	v4l2-dev.o v4l2-ioctl.o v4l2-device.o
 
+# V4L2 core modules
+
 obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-int-device.o
 ifeq ($(CONFIG_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l2-compat-ioctl32.o
@@ -23,21 +25,15 @@ ifeq ($(CONFIG_VIDEO_V4L1_COMPAT),y)
   obj-$(CONFIG_VIDEO_DEV) += v4l1-compat.o
 endif
 
-obj-$(CONFIG_VIDEO_TUNER) += tuner.o
+# All i2c modules must come first:
 
-obj-$(CONFIG_VIDEO_BT848) += bt8xx/
-obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+obj-$(CONFIG_VIDEO_TUNER) += tuner.o
 obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
 obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
 obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
-
 obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
 obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
 obj-$(CONFIG_VIDEO_SAA5249) += saa5249.o
-obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
-obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
-obj-$(CONFIG_VIDEO_W9966) += w9966.o
-
 obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
 obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
 obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
@@ -54,11 +50,40 @@ obj-$(CONFIG_VIDEO_BT819) += bt819.o
 obj-$(CONFIG_VIDEO_BT856) += bt856.o
 obj-$(CONFIG_VIDEO_BT866) += bt866.o
 obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+obj-$(CONFIG_VIDEO_VINO) += indycam.o
+obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
+obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
+obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
+obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
+obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+obj-$(CONFIG_VIDEO_M52790) += m52790.o
+obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
+obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
+obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
+obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
+obj-$(CONFIG_VIDEO_CX25840) += cx25840/
+obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
+obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
+obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
+obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
+obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
-obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
+obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
+obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
+obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
+obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
+obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
+
+# And now the v4l2 drivers:
 
+obj-$(CONFIG_VIDEO_BT848) += bt8xx/
+obj-$(CONFIG_VIDEO_ZORAN) += zoran/
+obj-$(CONFIG_VIDEO_CQCAM) += c-qcam.o
+obj-$(CONFIG_VIDEO_BWQCAM) += bw-qcam.o
+obj-$(CONFIG_VIDEO_W9966) += w9966.o
 obj-$(CONFIG_VIDEO_PMS) += pms.o
-obj-$(CONFIG_VIDEO_VINO) += vino.o indycam.o
+obj-$(CONFIG_VIDEO_VINO) += vino.o
 obj-$(CONFIG_VIDEO_STRADIS) += stradis.o
 obj-$(CONFIG_VIDEO_CPIA) += cpia.o
 obj-$(CONFIG_VIDEO_CPIA_PP) += cpia_pp.o
@@ -69,17 +94,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
 obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
 obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
 obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
-obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
-obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
 obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
-obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
-obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
-obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
-obj-$(CONFIG_VIDEO_M52790) += m52790.o
-obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
-obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
-obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
-obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
 obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
 obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
 obj-$(CONFIG_VIDEO_MXB) += mxb.o
@@ -92,19 +107,12 @@ obj-$(CONFIG_VIDEOBUF_DMA_CONTIG) += vid
 obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
 obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
 obj-$(CONFIG_VIDEO_BTCX)  += btcx-risc.o
-obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 
 obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
 
-obj-$(CONFIG_VIDEO_CX25840) += cx25840/
-obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
-obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
 obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
 
 obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
-obj-$(CONFIG_VIDEO_OV7670) 	+= ov7670.o
-
-obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
 
 obj-$(CONFIG_USB_DABUSB)        += dabusb.o
 obj-$(CONFIG_USB_OV511)         += ov511.o
@@ -134,24 +142,21 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
 obj-$(CONFIG_VIDEO_VIVI) += vivi.o
 obj-$(CONFIG_VIDEO_CX23885) += cx23885/
 
+obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
+obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
+obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
+# soc-camera host drivers have to be linked after camera drivers
 obj-$(CONFIG_VIDEO_MX1)			+= mx1_camera.o
 obj-$(CONFIG_VIDEO_MX3)			+= mx3_camera.o
 obj-$(CONFIG_VIDEO_PXA27x)		+= pxa_camera.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
-obj-$(CONFIG_VIDEO_OMAP2)		+= omap2cam.o
-obj-$(CONFIG_SOC_CAMERA)		+= soc_camera.o
-obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
-obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
-obj-$(CONFIG_SOC_CAMERA_MT9T031)	+= mt9t031.o
-obj-$(CONFIG_SOC_CAMERA_MT9V022)	+= mt9v022.o
-obj-$(CONFIG_SOC_CAMERA_OV772X)		+= ov772x.o
-obj-$(CONFIG_SOC_CAMERA_PLATFORM)	+= soc_camera_platform.o
-obj-$(CONFIG_SOC_CAMERA_TW9910)		+= tw9910.o
 
 obj-$(CONFIG_VIDEO_AU0828) += au0828/
 
 obj-$(CONFIG_USB_VIDEO_CLASS)	+= uvc/
 
+obj-$(CONFIG_VIDEO_IR_I2C)  += ir-kbd-i2c.o
+
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
 EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-libre-2.6.30.10-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-libre-2.6.30-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 16:45:51.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2013-05-03 17:24:42.000000000 -0400
@@ -1978,6 +1978,34 @@ static unsigned int pvr2_copy_i2c_addr_l
 }
 
 
+static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
+{
+	/*
+	  Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit of nuttiness
+	  for cx25840 causes that module to correctly set up its video
+	  scaling.  This is really a problem in the cx25840 module itself,
+	  but we work around it here.  The problem has not been seen in
+	  ivtv because there VBI is supported and set up.  We don't do VBI
+	  here (at least not yet) and thus we never attempted to even set
+	  it up.
+	*/
+	struct v4l2_format fmt;
+	if (hdw->decoder_client_id != PVR2_CLIENT_ID_CX25840) {
+		/* We're not using a cx25840 so don't enable the hack */
+		return;
+	}
+
+	pvr2_trace(PVR2_TRACE_INIT,
+		   "Module ID %u:"
+		   " Executing cx25840 VBI hack",
+		   hdw->decoder_client_id);
+	memset(&fmt, 0, sizeof(fmt));
+	fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+	v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+			     video, s_fmt, &fmt);
+}
+
+
 static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
 				const struct pvr2_device_client_desc *cd)
 {
@@ -2069,30 +2097,6 @@ static int pvr2_hdw_load_subdev(struct p
 	/* client-specific setup... */
 	switch (mid) {
 	case PVR2_CLIENT_ID_CX25840:
-		hdw->decoder_client_id = mid;
-		{
-			/*
-			  Mike Isely <isely@pobox.com> 19-Nov-2006 - This
-			  bit of nuttiness for cx25840 causes that module
-			  to correctly set up its video scaling.  This is
-			  really a problem in the cx25840 module itself,
-			  but we work around it here.  The problem has not
-			  been seen in ivtv because there VBI is supported
-			  and set up.  We don't do VBI here (at least not
-			  yet) and thus we never attempted to even set it
-			  up.
-			*/
-			struct v4l2_format fmt;
-			pvr2_trace(PVR2_TRACE_INIT,
-				   "Module ID %u:"
-				   " Executing cx25840 VBI hack",
-				   mid);
-			memset(&fmt, 0, sizeof(fmt));
-			fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
-			v4l2_device_call_all(&hdw->v4l2_dev, mid,
-					     video, s_fmt, &fmt);
-		}
-		break;
 	case PVR2_CLIENT_ID_SAA7115:
 		hdw->decoder_client_id = mid;
 		break;
@@ -2193,6 +2197,8 @@ static void pvr2_hdw_setup_low(struct pv
 		cptr->info->set_value(cptr,~0,cptr->info->default_value);
 	}
 
+	pvr2_hdw_cx25840_vbi_hack(hdw);
+
 	/* Set up special default values for the television and radio
 	   frequencies here.  It's not really important what these defaults
 	   are, but I set them to something usable in the Chicago area just
@@ -2944,6 +2950,7 @@ static void pvr2_subdev_update(struct pv
 			vs = hdw->std_mask_cur;
 			v4l2_device_call_all(&hdw->v4l2_dev, 0,
 					     core, s_std, vs);
+			pvr2_hdw_cx25840_vbi_hack(hdw);
 		}
 		hdw->tuner_signal_stale = !0;
 		hdw->cropcap_stale = !0;
@@ -4066,6 +4073,7 @@ int pvr2_hdw_cmd_decoder_reset(struct pv
 	if (hdw->decoder_client_id) {
 		v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
 				     core, reset, 0);
+		pvr2_hdw_cx25840_vbi_hack(hdw);
 		return 0;
 	}
 	pvr2_trace(PVR2_TRACE_INIT,
diff -druNp linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/Makefile linux-libre-2.6.30.10-gnu1/drivers/media/video/saa7134/Makefile
--- linux-libre-2.6.30-gnu1/drivers/media/video/saa7134/Makefile	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/media/video/saa7134/Makefile	2009-12-04 01:00:07.000000000 -0500
@@ -3,8 +3,7 @@ saa7134-objs :=	saa7134-cards.o saa7134-
 		saa7134-ts.o saa7134-tvaudio.o saa7134-vbi.o    \
 		saa7134-video.o saa7134-input.o
 
-obj-$(CONFIG_VIDEO_SAA7134) +=  saa7134.o saa7134-empress.o \
-				saa6752hs.o
+obj-$(CONFIG_VIDEO_SAA7134) +=  saa6752hs.o saa7134.o saa7134-empress.o
 
 obj-$(CONFIG_VIDEO_SAA7134_ALSA) += saa7134-alsa.o
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.c linux-libre-2.6.30.10-gnu1/drivers/mmc/host/mvsdio.c
--- linux-libre-2.6.30-gnu1/drivers/mmc/host/mvsdio.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/mmc/host/mvsdio.c	2009-12-04 01:00:07.000000000 -0500
@@ -384,7 +384,7 @@ static irqreturn_t mvsd_irq(int irq, voi
 				u16 val[2] = {0, 0};
 				val[0] = mvsd_read(MVSD_FIFO);
 				val[1] = mvsd_read(MVSD_FIFO);
-				memcpy(p, &val, s);
+				memcpy(p, ((void *)&val) + 4 - s, s);
 				s = 0;
 				intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
 			}
@@ -423,7 +423,7 @@ static irqreturn_t mvsd_irq(int irq, voi
 		if (s < 4) {
 			if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
 				u16 val[2] = {0, 0};
-				memcpy(&val, p, s);
+				memcpy(((void *)&val) + 4 - s, p, s);
 				mvsd_write(MVSD_FIFO, val[0]);
 				mvsd_write(MVSD_FIFO, val[1]);
 				s = 0;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/8139too.c linux-libre-2.6.30.10-gnu1/drivers/net/8139too.c
--- linux-libre-2.6.30-gnu1/drivers/net/8139too.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/8139too.c	2009-12-04 01:00:07.000000000 -0500
@@ -917,6 +917,7 @@ static const struct net_device_ops rtl81
 	.ndo_open		= rtl8139_open,
 	.ndo_stop		= rtl8139_close,
 	.ndo_get_stats		= rtl8139_get_stats,
+	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address 	= rtl8139_set_mac_address,
 	.ndo_start_xmit		= rtl8139_start_xmit,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/arm/ixp4xx_eth.c linux-libre-2.6.30.10-gnu1/drivers/net/arm/ixp4xx_eth.c
--- linux-libre-2.6.30-gnu1/drivers/net/arm/ixp4xx_eth.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/arm/ixp4xx_eth.c	2009-12-04 01:00:07.000000000 -0500
@@ -1140,7 +1140,9 @@ static const struct net_device_ops ixp4x
 	.ndo_start_xmit = eth_xmit,
 	.ndo_set_multicast_list = eth_set_mcast_list,
 	.ndo_do_ioctl = eth_ioctl,
-
+	.ndo_change_mtu = eth_change_mtu,
+	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_validate_addr = eth_validate_addr,
 };
 
 static int __devinit eth_init_one(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_ethtool.c linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c_ethtool.c
--- linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_ethtool.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c_ethtool.c	2009-12-04 01:00:07.000000000 -0500
@@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_devi
 	struct atl1c_adapter *adapter = netdev_priv(netdev);
 
 	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-			    WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+			    WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
 		return -EOPNOTSUPP;
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c.h linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c.h
--- linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c.h	2009-12-04 01:00:07.000000000 -0500
@@ -188,14 +188,14 @@ struct atl1c_tpd_ext_desc {
 #define RRS_HDS_TYPE_DATA	2
 
 #define RRS_IS_NO_HDS_TYPE(flag) \
-	(((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == 0)
+	((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == 0)
 
 #define RRS_IS_HDS_HEAD(flag) \
-	(((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+	((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
 			RRS_HDS_TYPE_HEAD)
 
 #define RRS_IS_HDS_DATA(flag) \
-	(((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK == \
+	((((flag) >> (RRS_HDS_TYPE_SHIFT)) & RRS_HDS_TYPE_MASK) == \
 			RRS_HDS_TYPE_DATA)
 
 /* rrs word 3 bit 0:31 */
@@ -245,7 +245,7 @@ struct atl1c_tpd_ext_desc {
 #define RRS_PACKET_TYPE_802_3  	1
 #define RRS_PACKET_TYPE_ETH	0
 #define RRS_PACKET_IS_ETH(word) \
-	(((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK == \
+	((((word) >> RRS_PACKET_TYPE_SHIFT) & RRS_PACKET_TYPE_MASK) == \
 			RRS_PACKET_TYPE_ETH)
 #define RRS_RXD_IS_VALID(word) \
 	((((word) >> RRS_RXD_UPDATED_SHIFT) & RRS_RXD_UPDATED_MASK) == 1)
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_main.c linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c_main.c
--- linux-libre-2.6.30-gnu1/drivers/net/atl1c/atl1c_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/atl1c/atl1c_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -1701,7 +1701,7 @@ static void atl1c_clean_rx_irq(struct at
 		if (likely(RRS_RXD_IS_VALID(rrs->word3))) {
 			rfd_num = (rrs->word0 >> RRS_RX_RFD_CNT_SHIFT) &
 				RRS_RX_RFD_CNT_MASK;
-			if (unlikely(rfd_num) != 1)
+			if (unlikely(rfd_num != 1))
 				/* TODO support mul rfd*/
 				if (netif_msg_rx_err(adapter))
 					dev_warn(&pdev->dev,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/benet/be_ethtool.c linux-libre-2.6.30.10-gnu1/drivers/net/benet/be_ethtool.c
--- linux-libre-2.6.30-gnu1/drivers/net/benet/be_ethtool.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/benet/be_ethtool.c	2009-12-04 01:00:07.000000000 -0500
@@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netde
 		return -EINVAL;
 
 	adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
-	if (adapter->max_rx_coal > MAX_SKB_FRAGS)
-		adapter->max_rx_coal = MAX_SKB_FRAGS - 1;
+	if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME)
+		adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME;
 
 	/* if AIC is being turned on now, start with an EQD of 0 */
 	if (rx_eq->enable_aic == 0 &&
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/benet/be.h linux-libre-2.6.30.10-gnu1/drivers/net/benet/be.h
--- linux-libre-2.6.30-gnu1/drivers/net/benet/be.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/benet/be.h	2009-12-04 01:00:07.000000000 -0500
@@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_
 #define RX_FRAGS_REFILL_WM	(RX_Q_LEN - MAX_RX_POST)
 
 #define BE_MAX_LRO_DESCRIPTORS  16
-#define BE_MAX_FRAGS_PER_FRAME  16
+#define BE_MAX_FRAGS_PER_FRAME  (min((u32) 16, (u32) MAX_SKB_FRAGS))
 
 struct be_dma_mem {
 	void *va;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/benet/be_main.c linux-libre-2.6.30.10-gnu1/drivers/net/benet/be_main.c
--- linux-libre-2.6.30-gnu1/drivers/net/benet/be_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/benet/be_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -682,7 +682,7 @@ static void skb_fill_rx_data(struct be_a
 {
 	struct be_queue_info *rxq = &adapter->rx_obj.q;
 	struct be_rx_page_info *page_info;
-	u16 rxq_idx, i, num_rcvd;
+	u16 rxq_idx, i, num_rcvd, j;
 	u32 pktsize, hdr_len, curr_frag_len;
 	u8 *start;
 
@@ -725,22 +725,33 @@ static void skb_fill_rx_data(struct be_a
 
 	/* More frags present for this completion */
 	pktsize -= curr_frag_len; /* account for above copied frag */
-	for (i = 1; i < num_rcvd; i++) {
+	for (i = 1, j = 0; i < num_rcvd; i++) {
 		index_inc(&rxq_idx, rxq->len);
 		page_info = get_rx_page_info(adapter, rxq_idx);
 
 		curr_frag_len = min(pktsize, rx_frag_size);
 
-		skb_shinfo(skb)->frags[i].page = page_info->page;
-		skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset;
-		skb_shinfo(skb)->frags[i].size = curr_frag_len;
+		/* Coalesce all frags from the same physical page in one slot */
+		if (page_info->page_offset == 0) {
+			/* Fresh page */
+			j++;
+			skb_shinfo(skb)->frags[j].page = page_info->page;
+			skb_shinfo(skb)->frags[j].page_offset =
+							page_info->page_offset;
+			skb_shinfo(skb)->frags[j].size = 0;
+			skb_shinfo(skb)->nr_frags++;
+		} else {
+			put_page(page_info->page);
+		}
+
+		skb_shinfo(skb)->frags[j].size += curr_frag_len;
 		skb->len += curr_frag_len;
 		skb->data_len += curr_frag_len;
-		skb_shinfo(skb)->nr_frags++;
 		pktsize -= curr_frag_len;
 
 		memset(page_info, 0, sizeof(*page_info));
 	}
+	BUG_ON(j > MAX_SKB_FRAGS);
 
 	be_rx_stats_update(adapter, pktsize, num_rcvd);
 	return;
@@ -803,7 +814,7 @@ static void be_rx_compl_process_lro(stru
 	struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
 	struct be_queue_info *rxq = &adapter->rx_obj.q;
 	u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len;
-	u16 i, rxq_idx = 0, vid;
+	u16 i, rxq_idx = 0, vid, j;
 
 	num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
 	pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
@@ -811,20 +822,28 @@ static void be_rx_compl_process_lro(stru
 	rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
 
 	remaining = pkt_size;
-	for (i = 0; i < num_rcvd; i++) {
+	for (i = 0, j = -1; i < num_rcvd; i++) {
 		page_info = get_rx_page_info(adapter, rxq_idx);
 
 		curr_frag_len = min(remaining, rx_frag_size);
 
-		rx_frags[i].page = page_info->page;
-		rx_frags[i].page_offset = page_info->page_offset;
-		rx_frags[i].size = curr_frag_len;
-		remaining -= curr_frag_len;
+		/* Coalesce all frags from the same physical page in one slot */
+		if (i == 0 || page_info->page_offset == 0) {
+			/* First frag or Fresh page */
+			j++;
+			rx_frags[j].page = page_info->page;
+			rx_frags[j].page_offset = page_info->page_offset;
+			rx_frags[j].size = 0;
+		} else {
+			put_page(page_info->page);
+		}
+		rx_frags[j].size += curr_frag_len;
 
+		remaining -= curr_frag_len;
 		index_inc(&rxq_idx, rxq->len);
-
 		memset(page_info, 0, sizeof(*page_info));
 	}
+	BUG_ON(j > MAX_SKB_FRAGS);
 
 	if (likely(!vlanf)) {
 		lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_sysfs.c linux-libre-2.6.30.10-gnu1/drivers/net/bonding/bond_sysfs.c
--- linux-libre-2.6.30-gnu1/drivers/net/bonding/bond_sysfs.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/bonding/bond_sysfs.c	2009-12-04 01:00:07.000000000 -0500
@@ -1538,6 +1538,7 @@ int bond_create_sysfs(void)
 			printk(KERN_ERR
 			       "network device named %s already exists in sysfs",
 			       class_attr_bonding_masters.attr.name);
+		ret = 0;
 	}
 
 	return ret;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/e1000e/netdev.c linux-libre-2.6.30.10-gnu1/drivers/net/e1000e/netdev.c
--- linux-libre-2.6.30-gnu1/drivers/net/e1000e/netdev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/e1000e/netdev.c	2009-12-04 01:00:07.000000000 -0500
@@ -1996,7 +1996,7 @@ static int e1000_clean(struct napi_struc
 	struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, napi);
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *poll_dev = adapter->netdev;
-	int tx_cleaned = 0, work_done = 0;
+	int tx_cleaned = 1, work_done = 0;
 
 	adapter = netdev_priv(poll_dev);
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/e100.c linux-libre-2.6.30.10-gnu1/drivers/net/e100.c
--- linux-libre-2.6.30-gnu1/drivers/net/e100.c	2013-05-03 16:46:49.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/e100.c	2013-05-03 17:25:39.000000000 -0400
@@ -1761,6 +1761,9 @@ static int e100_rx_indicate(struct nic *
 
 			if (ioread8(&nic->csr->scb.status) & rus_no_res)
 				nic->ru_running = RU_SUSPENDED;
+		pci_dma_sync_single_for_device(nic->pdev, rx->dma_addr,
+					       sizeof(struct rfd),
+					       PCI_DMA_FROMDEVICE);
 		return -ENODATA;
 	}
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea.h linux-libre-2.6.30.10-gnu1/drivers/net/ehea/ehea.h
--- linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/ehea/ehea.h	2009-12-04 01:00:07.000000000 -0500
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0101"
+#define DRV_VERSION	"EHEA_0102"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_main.c linux-libre-2.6.30.10-gnu1/drivers/net/ehea/ehea_main.c
--- linux-libre-2.6.30-gnu1/drivers/net/ehea/ehea_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/ehea/ehea_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -1545,6 +1545,9 @@ static int ehea_clean_portres(struct ehe
 {
 	int ret, i;
 
+	if (pr->qp)
+		netif_napi_del(&pr->napi);
+
 	ret = ehea_destroy_qp(pr->qp);
 
 	if (!ret) {
@@ -3080,7 +3083,9 @@ static const struct net_device_ops ehea_
 	.ndo_poll_controller	= ehea_netpoll,
 #endif
 	.ndo_get_stats		= ehea_get_stats,
+	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_set_mac_address	= ehea_set_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_multicast_list	= ehea_set_multicast_list,
 	.ndo_change_mtu		= ehea_change_mtu,
 	.ndo_vlan_rx_register	= ehea_vlan_rx_register,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/gianfar.c linux-libre-2.6.30.10-gnu1/drivers/net/gianfar.c
--- linux-libre-2.6.30-gnu1/drivers/net/gianfar.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/gianfar.c	2009-12-04 01:00:07.000000000 -0500
@@ -155,6 +155,8 @@ static const struct net_device_ops gfar_
 	.ndo_tx_timeout = gfar_timeout,
 	.ndo_do_ioctl = gfar_ioctl,
 	.ndo_vlan_rx_register = gfar_vlan_rx_register,
+	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = gfar_netpoll,
 #endif
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/mlx4/eq.c linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/eq.c
--- linux-libre-2.6.30-gnu1/drivers/net/mlx4/eq.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/eq.c	2009-12-04 01:00:07.000000000 -0500
@@ -524,48 +524,6 @@ static void mlx4_unmap_clr_int(struct ml
 	iounmap(priv->clr_base);
 }
 
-int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt)
-{
-	struct mlx4_priv *priv = mlx4_priv(dev);
-	int ret;
-
-	/*
-	 * We assume that mapping one page is enough for the whole EQ
-	 * context table.  This is fine with all current HCAs, because
-	 * we only use 32 EQs and each EQ uses 64 bytes of context
-	 * memory, or 1 KB total.
-	 */
-	priv->eq_table.icm_virt = icm_virt;
-	priv->eq_table.icm_page = alloc_page(GFP_HIGHUSER);
-	if (!priv->eq_table.icm_page)
-		return -ENOMEM;
-	priv->eq_table.icm_dma  = pci_map_page(dev->pdev, priv->eq_table.icm_page, 0,
-					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
-	if (pci_dma_mapping_error(dev->pdev, priv->eq_table.icm_dma)) {
-		__free_page(priv->eq_table.icm_page);
-		return -ENOMEM;
-	}
-
-	ret = mlx4_MAP_ICM_page(dev, priv->eq_table.icm_dma, icm_virt);
-	if (ret) {
-		pci_unmap_page(dev->pdev, priv->eq_table.icm_dma, PAGE_SIZE,
-			       PCI_DMA_BIDIRECTIONAL);
-		__free_page(priv->eq_table.icm_page);
-	}
-
-	return ret;
-}
-
-void mlx4_unmap_eq_icm(struct mlx4_dev *dev)
-{
-	struct mlx4_priv *priv = mlx4_priv(dev);
-
-	mlx4_UNMAP_ICM(dev, priv->eq_table.icm_virt, 1);
-	pci_unmap_page(dev->pdev, priv->eq_table.icm_dma, PAGE_SIZE,
-		       PCI_DMA_BIDIRECTIONAL);
-	__free_page(priv->eq_table.icm_page);
-}
-
 int mlx4_alloc_eq_table(struct mlx4_dev *dev)
 {
 	struct mlx4_priv *priv = mlx4_priv(dev);
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/mlx4/main.c linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/main.c
--- linux-libre-2.6.30-gnu1/drivers/net/mlx4/main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/main.c	2009-12-04 01:00:07.000000000 -0500
@@ -520,7 +520,10 @@ static int mlx4_init_icm(struct mlx4_dev
 		goto err_unmap_aux;
 	}
 
-	err = mlx4_map_eq_icm(dev, init_hca->eqc_base);
+	err = mlx4_init_icm_table(dev, &priv->eq_table.table,
+				  init_hca->eqc_base, dev_cap->eqc_entry_sz,
+				  dev->caps.num_eqs, dev->caps.num_eqs,
+				  0, 0);
 	if (err) {
 		mlx4_err(dev, "Failed to map EQ context memory, aborting.\n");
 		goto err_unmap_cmpt;
@@ -663,7 +666,7 @@ err_unmap_mtt:
 	mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table);
 
 err_unmap_eq:
-	mlx4_unmap_eq_icm(dev);
+	mlx4_cleanup_icm_table(dev, &priv->eq_table.table);
 
 err_unmap_cmpt:
 	mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table);
@@ -693,11 +696,11 @@ static void mlx4_free_icms(struct mlx4_d
 	mlx4_cleanup_icm_table(dev, &priv->qp_table.qp_table);
 	mlx4_cleanup_icm_table(dev, &priv->mr_table.dmpt_table);
 	mlx4_cleanup_icm_table(dev, &priv->mr_table.mtt_table);
+	mlx4_cleanup_icm_table(dev, &priv->eq_table.table);
 	mlx4_cleanup_icm_table(dev, &priv->eq_table.cmpt_table);
 	mlx4_cleanup_icm_table(dev, &priv->cq_table.cmpt_table);
 	mlx4_cleanup_icm_table(dev, &priv->srq_table.cmpt_table);
 	mlx4_cleanup_icm_table(dev, &priv->qp_table.cmpt_table);
-	mlx4_unmap_eq_icm(dev);
 
 	mlx4_UNMAP_ICM_AUX(dev);
 	mlx4_free_icm(dev, priv->fw.aux_icm, 0);
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4.h linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/mlx4.h
--- linux-libre-2.6.30-gnu1/drivers/net/mlx4/mlx4.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/mlx4/mlx4.h	2009-12-04 01:00:07.000000000 -0500
@@ -205,9 +205,7 @@ struct mlx4_eq_table {
 	void __iomem	      **uar_map;
 	u32			clr_mask;
 	struct mlx4_eq	       *eq;
-	u64			icm_virt;
-	struct page	       *icm_page;
-	dma_addr_t		icm_dma;
+	struct mlx4_icm_table	table;
 	struct mlx4_icm_table	cmpt_table;
 	int			have_irq;
 	u8			inta_pin;
@@ -373,9 +371,6 @@ u64 mlx4_make_profile(struct mlx4_dev *d
 		      struct mlx4_dev_cap *dev_cap,
 		      struct mlx4_init_hca_param *init_hca);
 
-int mlx4_map_eq_icm(struct mlx4_dev *dev, u64 icm_virt);
-void mlx4_unmap_eq_icm(struct mlx4_dev *dev);
-
 int mlx4_cmd_init(struct mlx4_dev *dev);
 void mlx4_cmd_cleanup(struct mlx4_dev *dev);
 void mlx4_cmd_event(struct mlx4_dev *dev, u16 token, u8 status, u64 out_param);
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/mv643xx_eth.c linux-libre-2.6.30.10-gnu1/drivers/net/mv643xx_eth.c
--- linux-libre-2.6.30-gnu1/drivers/net/mv643xx_eth.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/mv643xx_eth.c	2009-12-04 01:00:07.000000000 -0500
@@ -1751,12 +1751,12 @@ static void mv643xx_eth_program_unicast_
 
 	uc_addr_set(mp, dev->dev_addr);
 
-	port_config = rdlp(mp, PORT_CONFIG);
+	port_config = rdlp(mp, PORT_CONFIG) & ~UNICAST_PROMISCUOUS_MODE;
+
 	nibbles = uc_addr_filter_mask(dev);
 	if (!nibbles) {
 		port_config |= UNICAST_PROMISCUOUS_MODE;
-		wrlp(mp, PORT_CONFIG, port_config);
-		return;
+		nibbles = 0xffff;
 	}
 
 	for (i = 0; i < 16; i += 4) {
@@ -1777,7 +1777,6 @@ static void mv643xx_eth_program_unicast_
 		wrl(mp, off, v);
 	}
 
-	port_config &= ~UNICAST_PROMISCUOUS_MODE;
 	wrlp(mp, PORT_CONFIG, port_config);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/plip.c linux-libre-2.6.30.10-gnu1/drivers/net/plip.c
--- linux-libre-2.6.30-gnu1/drivers/net/plip.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/plip.c	2009-12-04 01:00:07.000000000 -0500
@@ -270,6 +270,9 @@ static const struct net_device_ops plip_
 	.ndo_stop		 = plip_close,
 	.ndo_start_xmit		 = plip_tx_packet,
 	.ndo_do_ioctl		 = plip_ioctl,
+	.ndo_change_mtu		 = eth_change_mtu,
+	.ndo_set_mac_address	 = eth_mac_addr,
+	.ndo_validate_addr	 = eth_validate_addr,
 };
 
 /* Entry point of PLIP driver.
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/ppp_generic.c linux-libre-2.6.30.10-gnu1/drivers/net/ppp_generic.c
--- linux-libre-2.6.30-gnu1/drivers/net/ppp_generic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/ppp_generic.c	2009-12-04 01:00:07.000000000 -0500
@@ -1383,7 +1383,7 @@ static int ppp_mp_explode(struct ppp *pp
 
 	/* create a	fragment for each channel */
 	bits = B;
-	while (nfree > 0 &&	len	> 0) {
+	while (len	> 0) {
 		list = list->next;
 		if (list ==	&ppp->channels)	{
 			i =	0;
@@ -1430,29 +1430,31 @@ static int ppp_mp_explode(struct ppp *pp
 		*otherwise divide it according to the speed
 		*of the channel we are going to transmit on
 		*/
-		if (pch->speed == 0) {
-			flen = totlen/nfree	;
-			if (nbigger > 0) {
-				flen++;
-				nbigger--;
-			}
-		} else {
-			flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
-				((totspeed*totfree)/pch->speed)) - hdrlen;
-			if (nbigger > 0) {
-				flen += ((totfree - nzero)*pch->speed)/totspeed;
-				nbigger -= ((totfree - nzero)*pch->speed)/
+		if (nfree > 0) {
+			if (pch->speed == 0) {
+				flen = totlen/nfree	;
+				if (nbigger > 0) {
+					flen++;
+					nbigger--;
+				}
+			} else {
+				flen = (((totfree - nzero)*(totlen + hdrlen*totfree)) /
+					((totspeed*totfree)/pch->speed)) - hdrlen;
+				if (nbigger > 0) {
+					flen += ((totfree - nzero)*pch->speed)/totspeed;
+					nbigger -= ((totfree - nzero)*pch->speed)/
 							totspeed;
+				}
 			}
+			nfree--;
 		}
-		nfree--;
 
 		/*
 		 *check	if we are on the last channel or
 		 *we exceded the lenght	of the data	to
 		 *fragment
 		 */
-		if ((nfree == 0) || (flen > len))
+		if ((nfree <= 0) || (flen > len))
 			flen = len;
 		/*
 		 *it is not worth to tx on slow channels:
@@ -1466,7 +1468,7 @@ static int ppp_mp_explode(struct ppp *pp
 			continue;
 		}
 
-		mtu	= pch->chan->mtu + 2 - hdrlen;
+		mtu	= pch->chan->mtu - hdrlen;
 		if (mtu	< 4)
 			mtu	= 4;
 		if (flen > mtu)
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/pppol2tp.c linux-libre-2.6.30.10-gnu1/drivers/net/pppol2tp.c
--- linux-libre-2.6.30-gnu1/drivers/net/pppol2tp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/pppol2tp.c	2009-12-04 01:00:07.000000000 -0500
@@ -2682,6 +2682,7 @@ out_unregister_pppol2tp_proto:
 static void __exit pppol2tp_exit(void)
 {
 	unregister_pppox_proto(PX_PROTO_OL2TP);
+	unregister_pernet_gen_device(pppol2tp_net_id, &pppol2tp_net_ops);
 	proto_unregister(&pppol2tp_sk_proto);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_net.c linux-libre-2.6.30.10-gnu1/drivers/net/ps3_gelic_net.c
--- linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_net.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/ps3_gelic_net.c	2009-12-04 01:00:07.000000000 -0500
@@ -1410,6 +1410,7 @@ static const struct net_device_ops gelic
 	.ndo_set_multicast_list = gelic_net_set_multi,
 	.ndo_change_mtu = gelic_net_change_mtu,
 	.ndo_tx_timeout = gelic_net_tx_timeout,
+	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = gelic_net_poll_controller,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_wireless.c linux-libre-2.6.30.10-gnu1/drivers/net/ps3_gelic_wireless.c
--- linux-libre-2.6.30-gnu1/drivers/net/ps3_gelic_wireless.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/ps3_gelic_wireless.c	2009-12-04 01:00:07.000000000 -0500
@@ -2707,6 +2707,7 @@ static const struct net_device_ops gelic
 	.ndo_set_multicast_list = gelic_net_set_multi,
 	.ndo_change_mtu = gelic_net_change_mtu,
 	.ndo_tx_timeout = gelic_net_tx_timeout,
+	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = gelic_net_poll_controller,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/sky2.c linux-libre-2.6.30.10-gnu1/drivers/net/sky2.c
--- linux-libre-2.6.30-gnu1/drivers/net/sky2.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/sky2.c	2009-12-04 01:00:07.000000000 -0500
@@ -2441,7 +2441,7 @@ static int sky2_status_intr(struct sky2_
 			if (likely(status >> 16 == (status & 0xffff))) {
 				skb = sky2->rx_ring[sky2->rx_next].skb;
 				skb->ip_summed = CHECKSUM_COMPLETE;
-				skb->csum = status & 0xffff;
+				skb->csum = le16_to_cpu(status);
 			} else {
 				printk(KERN_NOTICE PFX "%s: hardware receive "
 				       "checksum problem (status = %#x)\n",
@@ -4365,6 +4365,22 @@ static int __devinit sky2_probe(struct p
 		goto err_out;
 	}
 
+	/* Get configuration information
+	 * Note: only regular PCI config access once to test for HW issues
+	 *       other PCI access through shared memory for speed and to
+	 *	 avoid MMCONFIG problems.
+	 */
+	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
+	if (err) {
+		dev_err(&pdev->dev, "PCI read config failed\n");
+		goto err_out;
+	}
+
+	if (~reg == 0) {
+		dev_err(&pdev->dev, "PCI configuration read error\n");
+		goto err_out;
+	}
+
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
@@ -4390,21 +4406,6 @@ static int __devinit sky2_probe(struct p
 		}
 	}
 
-	/* Get configuration information
-	 * Note: only regular PCI config access once to test for HW issues
-	 *       other PCI access through shared memory for speed and to
-	 *	 avoid MMCONFIG problems.
-	 */
-	err = pci_read_config_dword(pdev, PCI_DEV_REG2, &reg);
-	if (err) {
-		dev_err(&pdev->dev, "PCI read config failed\n");
-		goto err_out_free_regions;
-	}
-
-	/* size of available VPD, only impact sysfs */
-	err = pci_vpd_truncate(pdev, 1ul << (((reg & PCI_VPD_ROM_SZ) >> 14) + 8));
-	if (err)
-		dev_warn(&pdev->dev, "Can't set VPD size\n");
 
 #ifdef __BIG_ENDIAN
 	/* The sk98lin vendor driver uses hardware byte swapping but
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/smc91x.c linux-libre-2.6.30.10-gnu1/drivers/net/smc91x.c
--- linux-libre-2.6.30-gnu1/drivers/net/smc91x.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/smc91x.c	2009-12-04 01:00:07.000000000 -0500
@@ -1774,6 +1774,7 @@ static const struct net_device_ops smc_n
 	.ndo_start_xmit		= smc_hard_start_xmit,
 	.ndo_tx_timeout		= smc_timeout,
 	.ndo_set_multicast_list	= smc_set_multicast_list,
+	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address 	= eth_mac_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/smsc911x.c linux-libre-2.6.30.10-gnu1/drivers/net/smsc911x.c
--- linux-libre-2.6.30-gnu1/drivers/net/smsc911x.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/smsc911x.c	2009-12-04 01:00:07.000000000 -0500
@@ -1766,6 +1766,7 @@ static const struct net_device_ops smsc9
 	.ndo_get_stats		= smsc911x_get_stats,
 	.ndo_set_multicast_list	= smsc911x_set_multicast_list,
 	.ndo_do_ioctl		= smsc911x_do_ioctl,
+	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address 	= smsc911x_set_mac_address,
 #ifdef CONFIG_NET_POLL_CONTROLLER
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/sunvnet.c linux-libre-2.6.30.10-gnu1/drivers/net/sunvnet.c
--- linux-libre-2.6.30-gnu1/drivers/net/sunvnet.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/sunvnet.c	2009-12-04 01:00:07.000000000 -0500
@@ -1016,7 +1016,9 @@ static const struct net_device_ops vnet_
 	.ndo_open		= vnet_open,
 	.ndo_stop		= vnet_close,
 	.ndo_set_multicast_list	= vnet_set_rx_mode,
+	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_set_mac_address	= vnet_set_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_tx_timeout		= vnet_tx_timeout,
 	.ndo_change_mtu		= vnet_change_mtu,
 	.ndo_start_xmit		= vnet_start_xmit,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/tun.c linux-libre-2.6.30.10-gnu1/drivers/net/tun.c
--- linux-libre-2.6.30-gnu1/drivers/net/tun.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/tun.c	2009-12-04 01:00:07.000000000 -0500
@@ -486,12 +486,14 @@ static unsigned int tun_chr_poll(struct
 {
 	struct tun_file *tfile = file->private_data;
 	struct tun_struct *tun = __tun_get(tfile);
-	struct sock *sk = tun->sk;
+	struct sock *sk;
 	unsigned int mask = 0;
 
 	if (!tun)
 		return POLLERR;
 
+	sk = tun->sk;
+
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
 
 	poll_wait(file, &tun->socket.wait, wait);
@@ -1275,21 +1277,22 @@ static int tun_chr_open(struct inode *in
 static int tun_chr_close(struct inode *inode, struct file *file)
 {
 	struct tun_file *tfile = file->private_data;
-	struct tun_struct *tun = __tun_get(tfile);
+	struct tun_struct *tun;
 
 
+	rtnl_lock();
+	tun = __tun_get(tfile);
 	if (tun) {
 		DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
 
-		rtnl_lock();
 		__tun_detach(tun);
 
 		/* If desireable, unregister the netdevice. */
 		if (!(tun->flags & TUN_PERSIST))
 			unregister_netdevice(tun->dev);
 
-		rtnl_unlock();
 	}
+	rtnl_unlock();
 
 	tun = tfile->tun;
 	if (tun)
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/usb/cdc_subset.c linux-libre-2.6.30.10-gnu1/drivers/net/usb/cdc_subset.c
--- linux-libre-2.6.30-gnu1/drivers/net/usb/cdc_subset.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/usb/cdc_subset.c	2009-12-04 01:00:07.000000000 -0500
@@ -307,9 +307,10 @@ static const struct usb_device_id	produc
 	USB_DEVICE (0x1286, 0x8001),    // "blob" bootloader
 	.driver_info =  (unsigned long) &blob_info,
 }, {
-	// Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
-	// e.g. Gumstix, current OpenZaurus, ...
-	USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
+	// Linux Ethernet/RNDIS gadget, mostly on PXA, second config
+	// e.g. Gumstix, current OpenZaurus, ... or anything else
+	// that just enables this gadget option.
+	USB_DEVICE (0x0525, 0xa4a2),
 	.driver_info =	(unsigned long) &linuxdev_info,
 },
 #endif
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/usb/kaweth.c linux-libre-2.6.30.10-gnu1/drivers/net/usb/kaweth.c
--- linux-libre-2.6.30-gnu1/drivers/net/usb/kaweth.c	2013-05-03 16:47:46.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/usb/kaweth.c	2013-05-03 17:26:32.000000000 -0400
@@ -979,6 +979,9 @@ static const struct net_device_ops kawet
 	.ndo_tx_timeout =		kaweth_tx_timeout,
 	.ndo_set_multicast_list =	kaweth_set_rx_mode,
 	.ndo_get_stats =		kaweth_netdev_stats,
+	.ndo_change_mtu =		eth_change_mtu,
+	.ndo_set_mac_address =		eth_mac_addr,
+	.ndo_validate_addr =		eth_validate_addr,
 };
 
 static int kaweth_probe(
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/usb/pegasus.c linux-libre-2.6.30.10-gnu1/drivers/net/usb/pegasus.c
--- linux-libre-2.6.30-gnu1/drivers/net/usb/pegasus.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/usb/pegasus.c	2009-12-04 01:00:07.000000000 -0500
@@ -297,7 +297,7 @@ static int update_eth_regs_async(pegasus
 
 	pegasus->dr.bRequestType = PEGASUS_REQT_WRITE;
 	pegasus->dr.bRequest = PEGASUS_REQ_SET_REGS;
-	pegasus->dr.wValue = 0;
+	pegasus->dr.wValue = cpu_to_le16(0);
 	pegasus->dr.wIndex = cpu_to_le16(EthCtrl0);
 	pegasus->dr.wLength = cpu_to_le16(3);
 	pegasus->ctrl_urb->transfer_buffer_length = 3;
@@ -446,11 +446,12 @@ static int write_eprom_word(pegasus_t *
 	int i;
 	__u8 tmp, d[4] = { 0x3f, 0, 0, EPROM_WRITE };
 	int ret;
+	__le16 le_data = cpu_to_le16(data);
 
 	set_registers(pegasus, EpromOffset, 4, d);
 	enable_eprom_write(pegasus);
 	set_register(pegasus, EpromOffset, index);
-	set_registers(pegasus, EpromData, 2, &data);
+	set_registers(pegasus, EpromData, 2, &le_data);
 	set_register(pegasus, EpromCtrl, EPROM_WRITE);
 
 	for (i = 0; i < REG_TIMEOUT; i++) {
@@ -923,29 +924,32 @@ static struct net_device_stats *pegasus_
 
 static inline void disable_net_traffic(pegasus_t * pegasus)
 {
-	int tmp = 0;
+	__le16 tmp = cpu_to_le16(0);
 
-	set_registers(pegasus, EthCtrl0, 2, &tmp);
+	set_registers(pegasus, EthCtrl0, sizeof(tmp), &tmp);
 }
 
 static inline void get_interrupt_interval(pegasus_t * pegasus)
 {
-	__u8 data[2];
+	u16 data;
+	u8 interval;
 
-	read_eprom_word(pegasus, 4, (__u16 *) data);
+	read_eprom_word(pegasus, 4, &data);
+	interval = data >> 8;
 	if (pegasus->usb->speed != USB_SPEED_HIGH) {
-		if (data[1] < 0x80) {
+		if (interval < 0x80) {
 			if (netif_msg_timer(pegasus))
 				dev_info(&pegasus->intf->dev, "intr interval "
 					"changed from %ums to %ums\n",
-					data[1], 0x80);
-			data[1] = 0x80;
+					interval, 0x80);
+			interval = 0x80;
+			data = (data & 0x00FF) | ((u16)interval << 8);
 #ifdef PEGASUS_WRITE_EEPROM
-			write_eprom_word(pegasus, 4, *(__u16 *) data);
+			write_eprom_word(pegasus, 4, data);
 #endif
 		}
 	}
-	pegasus->intr_interval = data[1];
+	pegasus->intr_interval = interval;
 }
 
 static void set_carrier(struct net_device *net)
@@ -1299,7 +1303,8 @@ static int pegasus_blacklisted(struct us
 	/* Special quirk to keep the driver from handling the Belkin Bluetooth
 	 * dongle which happens to have the same ID.
 	 */
-	if ((udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) &&
+	if ((udd->idVendor == cpu_to_le16(VENDOR_BELKIN)) &&
+	    (udd->idProduct == cpu_to_le16(0x0121)) &&
 	    (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
 	    (udd->bDeviceProtocol == 1))
 		return 1;
@@ -1488,6 +1493,9 @@ static const struct net_device_ops pegas
 	.ndo_set_multicast_list =	pegasus_set_multicast,
 	.ndo_get_stats =		pegasus_netdev_stats,
 	.ndo_tx_timeout =		pegasus_tx_timeout,
+	.ndo_change_mtu =		eth_change_mtu,
+	.ndo_set_mac_address =		eth_mac_addr,
+	.ndo_validate_addr =		eth_validate_addr,
 };
 
 static struct usb_driver pegasus_driver = {
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/via-rhine.c linux-libre-2.6.30.10-gnu1/drivers/net/via-rhine.c
--- linux-libre-2.6.30-gnu1/drivers/net/via-rhine.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/via-rhine.c	2009-12-04 01:00:07.000000000 -0500
@@ -622,6 +622,7 @@ static const struct net_device_ops rhine
 	.ndo_start_xmit		 = rhine_start_tx,
 	.ndo_get_stats		 = rhine_get_stats,
 	.ndo_set_multicast_list	 = rhine_set_rx_mode,
+	.ndo_change_mtu		 = eth_change_mtu,
 	.ndo_validate_addr	 = eth_validate_addr,
 	.ndo_set_mac_address 	 = eth_mac_addr,
 	.ndo_do_ioctl		 = netdev_ioctl,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/via-velocity.c linux-libre-2.6.30.10-gnu1/drivers/net/via-velocity.c
--- linux-libre-2.6.30-gnu1/drivers/net/via-velocity.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/via-velocity.c	2009-12-04 01:00:07.000000000 -0500
@@ -1845,7 +1845,7 @@ static void velocity_free_tx_buf(struct
 	 */
 	if (tdinfo->skb_dma) {
 
-		pktlen = (skb->len > ETH_ZLEN ? : ETH_ZLEN);
+		pktlen = max_t(unsigned int, skb->len, ETH_ZLEN);
 		for (i = 0; i < tdinfo->nskb_dma; i++) {
 #ifdef VELOCITY_ZERO_COPY_SUPPORT
 			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i], le16_to_cpu(td->tdesc1.len), PCI_DMA_TODEVICE);
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/main.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ar9170/main.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ar9170/main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ar9170/main.c	2009-12-04 01:00:07.000000000 -0500
@@ -1486,13 +1486,14 @@ static int ar9170_conf_tx(struct ieee802
 	int ret;
 
 	mutex_lock(&ar->mutex);
-	if ((param) && !(queue > ar->hw->queues)) {
+	if (queue < __AR9170_NUM_TXQ) {
 		memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
 		       param, sizeof(*param));
 
 		ret = ar9170_set_qos(ar);
-	} else
+	} else {
 		ret = -EINVAL;
+	}
 
 	mutex_unlock(&ar->mutex);
 	return ret;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath5k/base.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath5k/base.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath5k/base.c	2009-12-04 01:00:07.000000000 -0500
@@ -685,6 +685,13 @@ ath5k_pci_resume(struct pci_dev *pdev)
 	if (err)
 		return err;
 
+	/*
+	 * Suspend/Resume resets the PCI configuration space, so we have to
+	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
+	 * PCI Tx retries from interfering with C3 CPU state
+	 */
+	pci_write_config_byte(pdev, 0x41, 0);
+
 	err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
 	if (err) {
 		ATH5K_ERR(sc, "request_irq failed\n");
@@ -2616,7 +2623,7 @@ ath5k_reset(struct ath5k_softc *sc, stru
 		sc->curchan = chan;
 		sc->curband = &sc->sbands[chan->band];
 	}
-	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
+	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL);
 	if (ret) {
 		ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
 		goto err;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/calib.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/calib.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/calib.c	2009-12-04 01:00:07.000000000 -0500
@@ -284,8 +284,8 @@ static bool ath9k_hw_iscal_supported(str
 		return true;
 	case ADC_GAIN_CAL:
 	case ADC_DC_CAL:
-		if (conf->channel->band == IEEE80211_BAND_5GHZ &&
-		  conf_is_ht20(conf))
+		if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+		      conf_is_ht20(conf)))
 			return true;
 		break;
 	}
@@ -883,7 +883,7 @@ bool ath9k_hw_calibrate(struct ath_hw *a
 static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-	if (chan->channelFlags & CHANNEL_HT20) {
+	if (IS_CHAN_HT20(chan)) {
 		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
 		REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
 		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
@@ -919,83 +919,66 @@ static bool ar9285_clc(struct ath_hw *ah
 	return true;
 }
 
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-		       struct ath9k_channel *chan)
+bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
 {
 	if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
 		if (!ar9285_clc(ah, chan))
 			return false;
-	} else if (AR_SREV_9280_10_OR_LATER(ah)) {
-		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-		REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+	} else {
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+		}
 
-		/* Kick off the cal */
+		/* Calibrate the AGC */
 		REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-				REG_READ(ah, AR_PHY_AGC_CONTROL) |
-				AR_PHY_AGC_CONTROL_CAL);
+			  REG_READ(ah, AR_PHY_AGC_CONTROL) |
+			  AR_PHY_AGC_CONTROL_CAL);
 
-		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-					AR_PHY_AGC_CONTROL_CAL, 0,
-					AH_WAIT_TIMEOUT)) {
+		/* Poll for offset calibration complete */
+		if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+				   0, AH_WAIT_TIMEOUT)) {
 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
 				"offset calibration failed to complete in 1ms; "
 				"noisy environment?\n");
 			return false;
 		}
 
-		REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-		REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-	}
-
-	/* Calibrate the AGC */
-	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-			REG_READ(ah, AR_PHY_AGC_CONTROL) |
-			AR_PHY_AGC_CONTROL_CAL);
-
-	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-				0, AH_WAIT_TIMEOUT)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-			"offset calibration failed to complete in 1ms; "
-			"noisy environment?\n");
-		return false;
-	}
-
-	if (AR_SREV_9280_10_OR_LATER(ah)) {
-		REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+		if (AR_SREV_9280_10_OR_LATER(ah)) {
+			REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+			REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+		}
 	}
 
 	/* Do PA Calibration */
 	if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
 		ath9k_hw_9285_pa_cal(ah);
 
-	/* Do NF Calibration */
+	/* Do NF Calibration after DC offset and other calibrations */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-			REG_READ(ah, AR_PHY_AGC_CONTROL) |
-			AR_PHY_AGC_CONTROL_NF);
+		  REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
 
 	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
 
+	/* Enable IQ, ADC Gain and ADC DC offset CALs */
 	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
 		if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
 			INIT_CAL(&ah->adcgain_caldata);
 			INSERT_CAL(ah, &ah->adcgain_caldata);
 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-					"enabling ADC Gain Calibration.\n");
+				"enabling ADC Gain Calibration.\n");
 		}
 		if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
 			INIT_CAL(&ah->adcdc_caldata);
 			INSERT_CAL(ah, &ah->adcdc_caldata);
 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-					"enabling ADC DC Calibration.\n");
+				"enabling ADC DC Calibration.\n");
 		}
 		if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
 			INIT_CAL(&ah->iq_caldata);
 			INSERT_CAL(ah, &ah->iq_caldata);
 			DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-					"enabling IQ Calibration.\n");
+				"enabling IQ Calibration.\n");
 		}
 
 		ah->cal_list_curr = ah->cal_list;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/main.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/main.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/main.c	2009-12-04 01:00:07.000000000 -0500
@@ -408,6 +408,18 @@ set_timer:
 	mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
 }
 
+static void ath_start_ani(struct ath_softc *sc)
+{
+	unsigned long timestamp = jiffies_to_msecs(jiffies);
+
+	sc->ani.longcal_timer = timestamp;
+	sc->ani.shortcal_timer = timestamp;
+	sc->ani.checkani_timer = timestamp;
+
+	mod_timer(&sc->ani.timer,
+		  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+}
+
 /*
  * Update tx/rx chainmask. For legacy association,
  * hard code chainmask to 1x1, for 11n association, use
@@ -920,9 +932,7 @@ static void ath9k_bss_assoc_info(struct
 		sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
 		sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
 
-		/* Start ANI */
-		mod_timer(&sc->ani.timer,
-			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+		ath_start_ani(sc);
 	} else {
 		DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
 		sc->curaid = 0;
@@ -1416,7 +1426,8 @@ static int ath_init(u16 devid, struct at
 	for (i = 0; i < sc->keymax; i++)
 		ath9k_hw_keyreset(ah, (u16) i);
 
-	if (ath9k_regd_init(sc->sc_ah))
+	error = ath9k_regd_init(sc->sc_ah);
+	if (error)
 		goto bad;
 
 	/* default to MONITOR mode */
@@ -2270,12 +2281,8 @@ static int ath9k_add_interface(struct ie
 
 	ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
 
-	if (conf->type == NL80211_IFTYPE_AP) {
-		/* TODO: is this a suitable place to start ANI for AP mode? */
-		/* Start ANI */
-		mod_timer(&sc->ani.timer,
-			  jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-	}
+	if (conf->type == NL80211_IFTYPE_AP)
+		ath_start_ani(sc);
 
 out:
 	mutex_unlock(&sc->mutex);
@@ -2771,6 +2778,7 @@ static void ath9k_sw_scan_complete(struc
 	mutex_lock(&sc->mutex);
 	aphy->state = ATH_WIPHY_ACTIVE;
 	sc->sc_flags &= ~SC_OP_SCANNING;
+	sc->sc_flags |= SC_OP_FULL_RESET;
 	mutex_unlock(&sc->mutex);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/pci.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/pci.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/pci.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/pci.c	2009-12-04 01:00:07.000000000 -0500
@@ -87,6 +87,7 @@ static int ath_pci_probe(struct pci_dev
 	struct ath_softc *sc;
 	struct ieee80211_hw *hw;
 	u8 csz;
+	u32 val;
 	int ret = 0;
 	struct ath_hw *ah;
 
@@ -133,6 +134,14 @@ static int ath_pci_probe(struct pci_dev
 
 	pci_set_master(pdev);
 
+	/*
+	 * Disable the RETRY_TIMEOUT register (0x41) to keep
+	 * PCI Tx retries from interfering with C3 CPU state.
+	 */
+	pci_read_config_dword(pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
+
 	ret = pci_request_region(pdev, 0, "ath9k");
 	if (ret) {
 		dev_err(&pdev->dev, "PCI memory region reserve error\n");
@@ -244,12 +253,21 @@ static int ath_pci_resume(struct pci_dev
 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
 	struct ath_wiphy *aphy = hw->priv;
 	struct ath_softc *sc = aphy->sc;
+	u32 val;
 	int err;
 
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
 	pci_restore_state(pdev);
+	/*
+	 * Suspend/Resume resets the PCI configuration space, so we have to
+	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
+	 * PCI Tx retries from interfering with C3 CPU state
+	 */
+	pci_read_config_dword(pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
 
 	/* Enable LED */
 	ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/regd.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/regd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/regd.c	2009-12-04 01:00:07.000000000 -0500
@@ -439,7 +439,7 @@ int ath9k_regd_init(struct ath_hw *ah)
 	u16 regdmn;
 
 	if (!ath9k_regd_is_eeprom_valid(ah)) {
-		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
 			"Invalid EEPROM contents\n");
 		return -EINVAL;
 	}
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/xmit.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/xmit.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/ath9k/xmit.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/ath9k/xmit.c	2009-12-04 01:00:07.000000000 -0500
@@ -1573,8 +1573,9 @@ static int ath_tx_setup_buffer(struct ie
 					   skb->len, DMA_TO_DEVICE);
 	if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
 		bf->bf_mpdu = NULL;
-		DPRINTF(sc, ATH_DBG_CONFIG,
-			"dma_mapping_error() on TX\n");
+		kfree(tx_info_priv);
+		tx_info->rate_driver_data[0] = NULL;
+		DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
 		return -ENOMEM;
 	}
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 16:48:21.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl3945-base.c	2013-05-03 17:27:09.000000000 -0400
@@ -4623,27 +4623,10 @@ static ssize_t show_power_level(struct d
 				struct device_attribute *attr, char *buf)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
-	int mode = priv->power_data.user_power_setting;
-	int system = priv->power_data.system_power_setting;
 	int level = priv->power_data.power_mode;
 	char *p = buf;
 
-	switch (system) {
-	case IWL_POWER_SYS_AUTO:
-		p += sprintf(p, "SYSTEM:auto");
-		break;
-	case IWL_POWER_SYS_AC:
-		p += sprintf(p, "SYSTEM:ac");
-		break;
-	case IWL_POWER_SYS_BATTERY:
-		p += sprintf(p, "SYSTEM:battery");
-		break;
-	}
-
-	p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
-			"fixed" : "auto");
-	p += sprintf(p, "\tINDEX:%d", level);
-	p += sprintf(p, "\n");
+	p += sprintf(p, "%d\n", level);
 	return p - buf + 1;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 16:48:26.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-agn.c	2013-05-03 17:27:15.000000000 -0400
@@ -3101,27 +3101,10 @@ static ssize_t show_power_level(struct d
 				struct device_attribute *attr, char *buf)
 {
 	struct iwl_priv *priv = dev_get_drvdata(d);
-	int mode = priv->power_data.user_power_setting;
-	int system = priv->power_data.system_power_setting;
 	int level = priv->power_data.power_mode;
 	char *p = buf;
 
-	switch (system) {
-	case IWL_POWER_SYS_AUTO:
-		p += sprintf(p, "SYSTEM:auto");
-		break;
-	case IWL_POWER_SYS_AC:
-		p += sprintf(p, "SYSTEM:ac");
-		break;
-	case IWL_POWER_SYS_BATTERY:
-		p += sprintf(p, "SYSTEM:battery");
-		break;
-	}
-
-	p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
-			"fixed" : "auto");
-	p += sprintf(p, "\tINDEX:%d", level);
-	p += sprintf(p, "\n");
+	p += sprintf(p, "%d\n", level);
 	return p - buf + 1;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-rfkill.c	2009-12-04 01:00:07.000000000 -0500
@@ -53,22 +53,31 @@ static int iwl_rfkill_soft_rf_kill(void
 	switch (state) {
 	case RFKILL_STATE_UNBLOCKED:
 		if (iwl_is_rfkill_hw(priv)) {
+			/* pass error to rfkill core, make it state HARD
+			 * BLOCKED (rfkill->mutex taken) and disable
+			 * software kill switch */
 			err = -EBUSY;
-			goto out_unlock;
+			priv->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
 		}
 		iwl_radio_kill_sw_enable_radio(priv);
 		break;
 	case RFKILL_STATE_SOFT_BLOCKED:
 		iwl_radio_kill_sw_disable_radio(priv);
+		/* rfkill->mutex is taken */
+		if (priv->rfkill->state == RFKILL_STATE_HARD_BLOCKED) {
+			/* force rfkill core state to be SOFT BLOCKED,
+			 * otherwise core will be unable to disable software
+			 * kill switch */
+			priv->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
+		}
 		break;
 	default:
 		IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
 			state);
 		break;
 	}
-out_unlock:
-	mutex_unlock(&priv->mutex);
 
+	mutex_unlock(&priv->mutex);
 	return err;
 }
 
@@ -132,14 +141,11 @@ void iwl_rfkill_set_hw_state(struct iwl_
 	if (!priv->rfkill)
 		return;
 
-	if (iwl_is_rfkill_hw(priv)) {
+	if (iwl_is_rfkill_sw(priv))
+		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+	else if (iwl_is_rfkill_hw(priv))
 		rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
-		return;
-	}
-
-	if (!iwl_is_rfkill_sw(priv))
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
 	else
-		rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
+		rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
 }
 EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/iwlwifi/iwl-sta.c	2009-12-04 01:00:07.000000000 -0500
@@ -560,6 +560,8 @@ int iwl_remove_default_wep_key(struct iw
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->sta_lock, flags);
+	IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
+		      keyconf->keyidx);
 
 	if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
 		IWL_ERR(priv, "index %d not used in uCode key table.\n",
@@ -567,6 +569,11 @@ int iwl_remove_default_wep_key(struct iw
 
 	priv->default_wep_key--;
 	memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+		return 0;
+	}
 	ret = iwl_send_static_wepkey_cmd(priv, 1);
 	IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
 		      keyconf->keyidx, ret);
@@ -847,6 +854,11 @@ int iwl_remove_dynamic_key(struct iwl_pr
 	priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
 	priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
 
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n");
+		spin_unlock_irqrestore(&priv->sta_lock, flags);
+		return 0;
+	}
 	ret =  iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return ret;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/orinoco/main.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/orinoco/main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/orinoco/main.c	2009-12-04 01:00:07.000000000 -0500
@@ -2521,6 +2521,8 @@ static const struct net_device_ops orino
 	.ndo_start_xmit		= orinoco_xmit,
 	.ndo_set_multicast_list	= orinoco_set_multicast_list,
 	.ndo_change_mtu		= orinoco_change_mtu,
+	.ndo_set_mac_address	= eth_mac_addr,
+	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_tx_timeout		= orinoco_tx_timeout,
 	.ndo_get_stats		= orinoco_get_stats,
 };
@@ -2555,7 +2557,6 @@ struct net_device
 	priv->wireless_data.spy_data = &priv->spy_data;
 	dev->wireless_data = &priv->wireless_data;
 #endif
-	/* we use the default eth_mac_addr for setting the MAC addr */
 
 	/* Reserve space in skb for the SNAP header */
 	dev->hard_header_len += ENCAPS_OVERHEAD;
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.c linux-libre-2.6.30.10-gnu1/drivers/net/wireless/p54/p54usb.c
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 16:48:56.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/p54/p54usb.c	2013-05-03 17:27:45.000000000 -0400
@@ -65,6 +65,7 @@ static struct usb_device_id p54u_table[]
 	{USB_DEVICE(0x0bf8, 0x1009)},   /* FUJITSU E-5400 USB D1700*/
 	{USB_DEVICE(0x0cde, 0x0006)},   /* Medion MD40900 */
 	{USB_DEVICE(0x0cde, 0x0008)},	/* Sagem XG703A */
+	{USB_DEVICE(0x0cde, 0x0015)},	/* Zcomax XG-705A */
 	{USB_DEVICE(0x0d8e, 0x3762)},	/* DLink DWL-G120 Cohiba */
 	{USB_DEVICE(0x124a, 0x4025)},	/* IOGear GWU513 (GW3887IK chip) */
 	{USB_DEVICE(0x1260, 0xee22)},	/* SMC 2862W-G version 2 */
diff -druNp linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00.h linux-libre-2.6.30.10-gnu1/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-libre-2.6.30-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/net/wireless/rt2x00/rt2x00.h	2009-12-04 01:00:07.000000000 -0500
@@ -814,13 +814,15 @@ struct rt2x00_dev {
 static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
 				  const unsigned int word, u32 *data)
 {
-	*data = rt2x00dev->rf[word];
+	BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+	*data = rt2x00dev->rf[word - 1];
 }
 
 static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
 				   const unsigned int word, u32 data)
 {
-	rt2x00dev->rf[word] = data;
+	BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+	rt2x00dev->rf[word - 1] = data;
 }
 
 /*
diff -druNp linux-libre-2.6.30-gnu1/drivers/parisc/eisa_eeprom.c linux-libre-2.6.30.10-gnu1/drivers/parisc/eisa_eeprom.c
--- linux-libre-2.6.30-gnu1/drivers/parisc/eisa_eeprom.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/parisc/eisa_eeprom.c	2009-12-04 01:00:07.000000000 -0500
@@ -55,7 +55,7 @@ static ssize_t eisa_eeprom_read(struct f
 	ssize_t ret;
 	int i;
 	
-	if (*ppos >= HPEE_MAX_LENGTH)
+	if (*ppos < 0 || *ppos >= HPEE_MAX_LENGTH)
 		return 0;
 	
 	count = *ppos + count < HPEE_MAX_LENGTH ? count : HPEE_MAX_LENGTH - *ppos;
diff -druNp linux-libre-2.6.30-gnu1/drivers/parport/parport_pc.c linux-libre-2.6.30.10-gnu1/drivers/parport/parport_pc.c
--- linux-libre-2.6.30-gnu1/drivers/parport/parport_pc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/parport/parport_pc.c	2009-12-04 01:00:07.000000000 -0500
@@ -1413,11 +1413,13 @@ static void __devinit decode_smsc(int ef
 
 static void __devinit winbond_check(int io, int key)
 {
-	int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
+	int origval, devid, devrev, oldid, x_devid, x_devrev, x_oldid;
 
 	if (!request_region(io, 3, __func__))
 		return;
 
+	origval = inb(io); /* Save original value */
+
 	/* First probe without key */
 	outb(0x20,io);
 	x_devid=inb(io+1);
@@ -1437,6 +1439,8 @@ static void __devinit winbond_check(int
 	oldid=inb(io+1);
 	outb(0xaa,io);    /* Magic Seal */
 
+	outb(origval, io); /* in case we poked some entirely different hardware */
+
 	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
 		goto out; /* protection against false positives */
 
@@ -1447,11 +1451,15 @@ out:
 
 static void __devinit winbond_check2(int io,int key)
 {
-        int devid,devrev,oldid,x_devid,x_devrev,x_oldid;
+	int origval[3], devid, devrev, oldid, x_devid, x_devrev, x_oldid;
 
 	if (!request_region(io, 3, __func__))
 		return;
 
+	origval[0] = inb(io); /* Save original values */
+	origval[1] = inb(io + 1);
+	origval[2] = inb(io + 2);
+
 	/* First probe without the key */
 	outb(0x20,io+2);
 	x_devid=inb(io+2);
@@ -1470,6 +1478,10 @@ static void __devinit winbond_check2(int
         oldid=inb(io+2);
         outb(0xaa,io);    /* Magic Seal */
 
+	outb(origval[0], io); /* in case we poked some entirely different hardware */
+	outb(origval[1], io + 1);
+	outb(origval[2], io + 2);
+
 	if ((x_devid == devid) && (x_devrev == devrev) && (x_oldid == oldid))
 		goto out; /* protection against false positives */
 
@@ -1480,11 +1492,13 @@ out:
 
 static void __devinit smsc_check(int io, int key)
 {
-        int id,rev,oldid,oldrev,x_id,x_rev,x_oldid,x_oldrev;
+	int origval, id, rev, oldid, oldrev, x_id, x_rev, x_oldid, x_oldrev;
 
 	if (!request_region(io, 3, __func__))
 		return;
 
+	origval = inb(io); /* Save original value */
+
 	/* First probe without the key */
 	outb(0x0d,io);
 	x_oldid=inb(io+1);
@@ -1508,6 +1522,8 @@ static void __devinit smsc_check(int io,
 	rev=inb(io+1);
         outb(0xaa,io);    /* Magic Seal */
 
+	outb(origval, io); /* in case we poked some entirely different hardware */
+
 	if ((x_id == id) && (x_oldrev == oldrev) &&
 	    (x_oldid == oldid) && (x_rev == rev))
 		goto out; /* protection against false positives */
@@ -1544,11 +1560,12 @@ static void __devinit detect_and_report_
 static void __devinit detect_and_report_it87(void)
 {
 	u16 dev;
-	u8 r;
+	u8 origval, r;
 	if (verbose_probing)
 		printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
-	if (!request_region(0x2e, 1, __func__))
+	if (!request_region(0x2e, 2, __func__))
 		return;
+	origval = inb(0x2e);		/* Save original value */
 	outb(0x87, 0x2e);
 	outb(0x01, 0x2e);
 	outb(0x55, 0x2e);
@@ -1568,8 +1585,10 @@ static void __devinit detect_and_report_
 		outb(r | 8, 0x2F);
 		outb(0x02, 0x2E);	/* Lock */
 		outb(0x02, 0x2F);
+	} else {
+		outb(origval, 0x2e);	/* Oops, sorry to disturb */
 	}
-	release_region(0x2e, 1);
+	release_region(0x2e, 2);
 }
 #endif /* CONFIG_PARPORT_PC_SUPERIO */
 
@@ -2193,6 +2212,9 @@ struct parport *parport_pc_probe_port(un
 		if (IS_ERR(pdev))
 			return NULL;
 		dev = &pdev->dev;
+
+		dev->coherent_dma_mask = DMA_BIT_MASK(24);
+		dev->dma_mask = &dev->coherent_dma_mask;
 	}
 
 	ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/iova.c linux-libre-2.6.30.10-gnu1/drivers/pci/iova.c
--- linux-libre-2.6.30-gnu1/drivers/pci/iova.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/iova.c	2009-12-04 01:00:07.000000000 -0500
@@ -1,9 +1,19 @@
 /*
- * Copyright (c) 2006, Intel Corporation.
+ * Copyright © 2006-2009, Intel Corporation.
  *
- * This file is released under the GPLv2.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
  *
- * Copyright (C) 2006-2008 Intel Corporation
  * Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
  */
 
@@ -123,7 +133,15 @@ move_left:
 	/* Insert the new_iova into domain rbtree by holding writer lock */
 	/* Add new node and rebalance tree. */
 	{
-		struct rb_node **entry = &((prev)), *parent = NULL;
+		struct rb_node **entry, *parent = NULL;
+
+		/* If we have 'prev', it's a valid place to start the
+		   insertion. Otherwise, start from the root. */
+		if (prev)
+			entry = &prev;
+		else
+			entry = &iovad->rbroot.rb_node;
+
 		/* Figure out where to put new node */
 		while (*entry) {
 			struct iova *this = container_of(*entry,
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/iov.c linux-libre-2.6.30.10-gnu1/drivers/pci/iov.c
--- linux-libre-2.6.30-gnu1/drivers/pci/iov.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/iov.c	2009-12-04 01:00:07.000000000 -0500
@@ -595,6 +595,29 @@ int pci_iov_resource_bar(struct pci_dev
 }
 
 /**
+ * pci_sriov_resource_alignment - get resource alignment for VF BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ *
+ * Returns the alignment of the VF BAR found in the SR-IOV capability.
+ * This is not the same as the resource size which is defined as
+ * the VF BAR size multiplied by the number of VFs.  The alignment
+ * is just the VF BAR size.
+ */
+int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
+{
+	struct resource tmp;
+	enum pci_bar_type type;
+	int reg = pci_iov_resource_bar(dev, resno, &type);
+
+	if (!reg)
+		return 0;
+
+	 __pci_read_base(dev, type, &tmp, reg);
+	return resource_alignment(&tmp);
+}
+
+/**
  * pci_restore_iov_state - restore the state of the IOV capability
  * @dev: the PCI device
  */
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/pci.c linux-libre-2.6.30.10-gnu1/drivers/pci/pci.c
--- linux-libre-2.6.30-gnu1/drivers/pci/pci.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/pci.c	2009-12-04 01:00:07.000000000 -0500
@@ -480,6 +480,8 @@ static int pci_raw_set_power_state(struc
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= state;
 		break;
+	case PCI_D3hot:
+	case PCI_D3cold:
 	case PCI_UNKNOWN: /* Boot-up */
 		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
 		 && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
@@ -1282,15 +1284,14 @@ pci_power_t pci_target_state(struct pci_
 		default:
 			target_state = state;
 		}
+	} else if (!dev->pm_cap) {
+		target_state = PCI_D0;
 	} else if (device_may_wakeup(&dev->dev)) {
 		/*
 		 * Find the deepest state from which the device can generate
 		 * wake-up events, make it the target state and enable device
 		 * to generate PME#.
 		 */
-		if (!dev->pm_cap)
-			return PCI_POWER_ERROR;
-
 		if (dev->pme_support) {
 			while (target_state
 			      && !(dev->pme_support & (1 << target_state)))
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/pcie/aspm.c linux-libre-2.6.30.10-gnu1/drivers/pci/pcie/aspm.c
--- linux-libre-2.6.30-gnu1/drivers/pci/pcie/aspm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/pcie/aspm.c	2009-12-04 01:00:07.000000000 -0500
@@ -638,6 +638,10 @@ void pcie_aspm_init_link_state(struct pc
 	if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
 		pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
 		return;
+	/* VIA has a strange chipset, root port is under a bridge */
+	if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
+		pdev->bus->self)
+		return;
 	down_read(&pci_bus_sem);
 	if (list_empty(&pdev->subordinate->devices))
 		goto out;
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/pci.h linux-libre-2.6.30.10-gnu1/drivers/pci/pci.h
--- linux-libre-2.6.30-gnu1/drivers/pci/pci.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/pci.h	2009-12-04 01:00:07.000000000 -0500
@@ -234,6 +234,7 @@ extern int pci_iov_init(struct pci_dev *
 extern void pci_iov_release(struct pci_dev *dev);
 extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
 				enum pci_bar_type *type);
+extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
 extern void pci_restore_iov_state(struct pci_dev *dev);
 extern int pci_iov_bus_range(struct pci_bus *bus);
 #else
@@ -259,4 +260,16 @@ static inline int pci_iov_bus_range(stru
 }
 #endif /* CONFIG_PCI_IOV */
 
+static inline int pci_resource_alignment(struct pci_dev *dev,
+					 struct resource *res)
+{
+#ifdef CONFIG_PCI_IOV
+	int resno = res - dev->resource;
+
+	if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
+		return pci_sriov_resource_alignment(dev, resno);
+#endif
+	return resource_alignment(res);
+}
+
 #endif /* DRIVERS_PCI_H */
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/quirks.c linux-libre-2.6.30.10-gnu1/drivers/pci/quirks.c
--- linux-libre-2.6.30-gnu1/drivers/pci/quirks.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/quirks.c	2009-12-04 01:00:07.000000000 -0500
@@ -1194,6 +1194,7 @@ static void __init asus_hides_smbus_host
 			switch(dev->subsystem_device) {
 			case 0x00b8: /* Compaq Evo D510 CMT */
 			case 0x00b9: /* Compaq Evo D510 SFF */
+			case 0x00ba: /* Compaq Evo D510 USDT */
 				/* Motherboard doesn't have Host bridge
 				 * subvendor/subdevice IDs and on-board VGA
 				 * controller is disabled if an AGP card is
@@ -2353,8 +2354,10 @@ static void __devinit nv_msi_ht_cap_quir
 }
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
 
 static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
 {
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/setup-bus.c linux-libre-2.6.30.10-gnu1/drivers/pci/setup-bus.c
--- linux-libre-2.6.30-gnu1/drivers/pci/setup-bus.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/setup-bus.c	2009-12-04 01:00:07.000000000 -0500
@@ -25,7 +25,7 @@
 #include <linux/ioport.h>
 #include <linux/cache.h>
 #include <linux/slab.h>
-
+#include "pci.h"
 
 static void pbus_assign_resources_sorted(const struct pci_bus *bus)
 {
@@ -355,7 +355,7 @@ static int pbus_size_mem(struct pci_bus
 				continue;
 			r_size = resource_size(r);
 			/* For bridges size != alignment */
-			align = resource_alignment(r);
+			align = pci_resource_alignment(dev, r);
 			order = __ffs(align) - 20;
 			if (order > 11) {
 				dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
diff -druNp linux-libre-2.6.30-gnu1/drivers/pci/setup-res.c linux-libre-2.6.30.10-gnu1/drivers/pci/setup-res.c
--- linux-libre-2.6.30-gnu1/drivers/pci/setup-res.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pci/setup-res.c	2009-12-04 01:00:07.000000000 -0500
@@ -145,7 +145,7 @@ int pci_assign_resource(struct pci_dev *
 	size = resource_size(res);
 	min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
 
-	align = resource_alignment(res);
+	align = pci_resource_alignment(dev, res);
 	if (!align) {
 		dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
 			"alignment) %pR flags %#lx\n",
@@ -236,7 +236,7 @@ void pdev_sort_resources(struct pci_dev
 		if (!(r->flags) || r->parent)
 			continue;
 
-		r_align = resource_alignment(r);
+		r_align = pci_resource_alignment(dev, r);
 		if (!r_align) {
 			dev_warn(&dev->dev, "BAR %d: bogus alignment "
 				"%pR flags %#lx\n",
@@ -248,7 +248,7 @@ void pdev_sort_resources(struct pci_dev
 			struct resource_list *ln = list->next;
 
 			if (ln)
-				align = resource_alignment(ln->res);
+				align = pci_resource_alignment(ln->dev, ln->res);
 
 			if (r_align > align) {
 				tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/at91_cf.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/at91_cf.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/at91_cf.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/at91_cf.c	2009-12-04 01:00:07.000000000 -0500
@@ -363,7 +363,7 @@ static int at91_cf_suspend(struct platfo
 	struct at91_cf_socket	*cf = platform_get_drvdata(pdev);
 	struct at91_cf_data	*board = cf->board;
 
-	pcmcia_socket_dev_suspend(&pdev->dev, mesg);
+	pcmcia_socket_dev_suspend(&pdev->dev);
 	if (device_may_wakeup(&pdev->dev)) {
 		enable_irq_wake(board->det_pin);
 		if (board->irq_pin)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/au1000_generic.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/au1000_generic.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/au1000_generic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/au1000_generic.c	2009-12-04 01:00:07.000000000 -0500
@@ -515,7 +515,7 @@ static int au1x00_drv_pcmcia_probe(struc
 static int au1x00_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int au1x00_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/bfin_cf_pcmcia.c	2009-12-04 01:00:07.000000000 -0500
@@ -302,7 +302,7 @@ static int __devexit bfin_cf_remove(stru
 
 static int bfin_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
-	return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
+	return pcmcia_socket_dev_suspend(&pdev->dev);
 }
 
 static int bfin_cf_resume(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/cs.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/cs.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/cs.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/cs.c	2009-12-04 01:00:07.000000000 -0500
@@ -101,7 +101,7 @@ EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
 static int socket_resume(struct pcmcia_socket *skt);
 static int socket_suspend(struct pcmcia_socket *skt);
 
-int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
+int pcmcia_socket_dev_suspend(struct device *dev)
 {
 	struct pcmcia_socket *socket;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/i82092.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/i82092.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/i82092.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/i82092.c	2009-12-04 01:00:07.000000000 -0500
@@ -42,7 +42,7 @@ MODULE_DEVICE_TABLE(pci, i82092aa_pci_id
 #ifdef CONFIG_PM
 static int i82092aa_socket_suspend (struct pci_dev *dev, pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int i82092aa_socket_resume (struct pci_dev *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/i82365.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/i82365.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/i82365.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/i82365.c	2009-12-04 01:00:07.000000000 -0500
@@ -1241,7 +1241,7 @@ static int pcic_init(struct pcmcia_socke
 static int i82365_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int i82365_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_cfc.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m32r_cfc.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_cfc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m32r_cfc.c	2009-12-04 01:00:07.000000000 -0500
@@ -699,7 +699,7 @@ static struct pccard_operations pcc_oper
 static int cfc_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int cfc_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_pcc.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m32r_pcc.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/m32r_pcc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m32r_pcc.c	2009-12-04 01:00:07.000000000 -0500
@@ -675,7 +675,7 @@ static struct pccard_operations pcc_oper
 static int pcc_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int pcc_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/m8xx_pcmcia.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m8xx_pcmcia.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/m8xx_pcmcia.c	2009-12-04 01:00:07.000000000 -0500
@@ -1296,7 +1296,7 @@ static int m8xx_remove(struct of_device
 #ifdef CONFIG_PM
 static int m8xx_suspend(struct platform_device *pdev, pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&pdev->dev, state);
+	return pcmcia_socket_dev_suspend(&pdev->dev);
 }
 
 static int m8xx_resume(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/omap_cf.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/omap_cf.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/omap_cf.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/omap_cf.c	2009-12-04 01:00:07.000000000 -0500
@@ -334,7 +334,7 @@ static int __exit omap_cf_remove(struct
 
 static int omap_cf_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
-	return pcmcia_socket_dev_suspend(&pdev->dev, mesg);
+	return pcmcia_socket_dev_suspend(&pdev->dev);
 }
 
 static int omap_cf_resume(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/pd6729.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/pd6729.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/pd6729.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/pd6729.c	2009-12-04 01:00:07.000000000 -0500
@@ -758,7 +758,7 @@ static void __devexit pd6729_pci_remove(
 #ifdef CONFIG_PM
 static int pd6729_socket_suspend(struct pci_dev *dev, pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int pd6729_socket_resume(struct pci_dev *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_base.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/pxa2xx_base.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/pxa2xx_base.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/pxa2xx_base.c	2009-12-04 01:00:07.000000000 -0500
@@ -302,7 +302,7 @@ static int pxa2xx_drv_pcmcia_remove(stru
 
 static int pxa2xx_drv_pcmcia_suspend(struct platform_device *dev, pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int pxa2xx_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_generic.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/sa1100_generic.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1100_generic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/sa1100_generic.c	2009-12-04 01:00:07.000000000 -0500
@@ -89,7 +89,7 @@ static int sa11x0_drv_pcmcia_remove(stru
 static int sa11x0_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int sa11x0_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1111_generic.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/sa1111_generic.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/sa1111_generic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/sa1111_generic.c	2009-12-04 01:00:07.000000000 -0500
@@ -159,7 +159,7 @@ static int __devexit pcmcia_remove(struc
 
 static int pcmcia_suspend(struct sa1111_dev *dev, pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int pcmcia_resume(struct sa1111_dev *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/tcic.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/tcic.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/tcic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/tcic.c	2009-12-04 01:00:07.000000000 -0500
@@ -366,7 +366,7 @@ static int __init get_tcic_id(void)
 static int tcic_drv_pcmcia_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int tcic_drv_pcmcia_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/vrc4171_card.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/vrc4171_card.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/vrc4171_card.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/vrc4171_card.c	2009-12-04 01:00:07.000000000 -0500
@@ -707,7 +707,7 @@ __setup("vrc4171_card=", vrc4171_card_se
 static int vrc4171_card_suspend(struct platform_device *dev,
 				     pm_message_t state)
 {
-	return pcmcia_socket_dev_suspend(&dev->dev, state);
+	return pcmcia_socket_dev_suspend(&dev->dev);
 }
 
 static int vrc4171_card_resume(struct platform_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/pcmcia/yenta_socket.c linux-libre-2.6.30.10-gnu1/drivers/pcmcia/yenta_socket.c
--- linux-libre-2.6.30-gnu1/drivers/pcmcia/yenta_socket.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/pcmcia/yenta_socket.c	2009-12-04 01:00:07.000000000 -0500
@@ -1225,60 +1225,71 @@ static int __devinit yenta_probe (struct
 }
 
 #ifdef CONFIG_PM
-static int yenta_dev_suspend (struct pci_dev *dev, pm_message_t state)
+static int yenta_dev_suspend_noirq(struct device *dev)
 {
-	struct yenta_socket *socket = pci_get_drvdata(dev);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct yenta_socket *socket = pci_get_drvdata(pdev);
 	int ret;
 
-	ret = pcmcia_socket_dev_suspend(&dev->dev, state);
+	ret = pcmcia_socket_dev_suspend(dev);
 
-	if (socket) {
-		if (socket->type && socket->type->save_state)
-			socket->type->save_state(socket);
+	if (!socket)
+		return ret;
 
-		/* FIXME: pci_save_state needs to have a better interface */
-		pci_save_state(dev);
-		pci_read_config_dword(dev, 16*4, &socket->saved_state[0]);
-		pci_read_config_dword(dev, 17*4, &socket->saved_state[1]);
-		pci_disable_device(dev);
+	if (socket->type && socket->type->save_state)
+		socket->type->save_state(socket);
 
-		/*
-		 * Some laptops (IBM T22) do not like us putting the Cardbus
-		 * bridge into D3.  At a guess, some other laptop will
-		 * probably require this, so leave it commented out for now.
-		 */
-		/* pci_set_power_state(dev, 3); */
-	}
+	pci_save_state(pdev);
+	pci_read_config_dword(pdev, 16*4, &socket->saved_state[0]);
+	pci_read_config_dword(pdev, 17*4, &socket->saved_state[1]);
+	pci_disable_device(pdev);
+
+	/*
+	 * Some laptops (IBM T22) do not like us putting the Cardbus
+	 * bridge into D3.  At a guess, some other laptop will
+	 * probably require this, so leave it commented out for now.
+	 */
+	/* pci_set_power_state(dev, 3); */
 
 	return ret;
 }
 
-
-static int yenta_dev_resume (struct pci_dev *dev)
+static int yenta_dev_resume_noirq(struct device *dev)
 {
-	struct yenta_socket *socket = pci_get_drvdata(dev);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct yenta_socket *socket = pci_get_drvdata(pdev);
+	int ret;
 
-	if (socket) {
-		int rc;
+	if (!socket)
+		return 0;
 
-		pci_set_power_state(dev, 0);
-		/* FIXME: pci_restore_state needs to have a better interface */
-		pci_restore_state(dev);
-		pci_write_config_dword(dev, 16*4, socket->saved_state[0]);
-		pci_write_config_dword(dev, 17*4, socket->saved_state[1]);
+	pci_write_config_dword(pdev, 16*4, socket->saved_state[0]);
+	pci_write_config_dword(pdev, 17*4, socket->saved_state[1]);
 
-		rc = pci_enable_device(dev);
-		if (rc)
-			return rc;
+	ret = pci_enable_device(pdev);
+	if (ret)
+		return ret;
 
-		pci_set_master(dev);
+	pci_set_master(pdev);
 
-		if (socket->type && socket->type->restore_state)
-			socket->type->restore_state(socket);
-	}
+	if (socket->type && socket->type->restore_state)
+		socket->type->restore_state(socket);
 
-	return pcmcia_socket_dev_resume(&dev->dev);
+	return pcmcia_socket_dev_resume(dev);
 }
+
+static struct dev_pm_ops yenta_pm_ops = {
+	.suspend_noirq = yenta_dev_suspend_noirq,
+	.resume_noirq = yenta_dev_resume_noirq,
+	.freeze_noirq = yenta_dev_suspend_noirq,
+	.thaw_noirq = yenta_dev_resume_noirq,
+	.poweroff_noirq = yenta_dev_suspend_noirq,
+	.restore_noirq = yenta_dev_resume_noirq,
+};
+
+#define YENTA_PM_OPS	(&yenta_pm_ops)
+#else
+#define YENTA_PM_OPS	NULL
 #endif
 
 #define CB_ID(vend,dev,type)				\
@@ -1376,10 +1387,7 @@ static struct pci_driver yenta_cardbus_d
 	.id_table	= yenta_table,
 	.probe		= yenta_probe,
 	.remove		= __devexit_p(yenta_close),
-#ifdef CONFIG_PM
-	.suspend	= yenta_dev_suspend,
-	.resume		= yenta_dev_resume,
-#endif
+	.driver.pm	= YENTA_PM_OPS,
 };
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/platform/x86/Kconfig linux-libre-2.6.30.10-gnu1/drivers/platform/x86/Kconfig
--- linux-libre-2.6.30-gnu1/drivers/platform/x86/Kconfig	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/platform/x86/Kconfig	2009-12-04 01:00:07.000000000 -0500
@@ -265,6 +265,7 @@ config THINKPAD_ACPI_DOCK
 	bool "Legacy Docking Station Support"
 	depends on THINKPAD_ACPI
 	depends on ACPI_DOCK=n
+	depends on BROKEN
 	default n
 	---help---
 	  Allows the thinkpad_acpi driver to handle docking station events.
@@ -278,7 +279,8 @@ config THINKPAD_ACPI_DOCK
 config THINKPAD_ACPI_BAY
 	bool "Legacy Removable Bay Support"
 	depends on THINKPAD_ACPI
-	default y
+	depends on BROKEN
+	default n
 	---help---
 	  Allows the thinkpad_acpi driver to handle removable bays.  It will
 	  electrically disable the device in the bay, and also generate
diff -druNp linux-libre-2.6.30-gnu1/drivers/platform/x86/thinkpad_acpi.c linux-libre-2.6.30.10-gnu1/drivers/platform/x86/thinkpad_acpi.c
--- linux-libre-2.6.30-gnu1/drivers/platform/x86/thinkpad_acpi.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/platform/x86/thinkpad_acpi.c	2009-12-04 01:00:07.000000000 -0500
@@ -286,6 +286,8 @@ struct thinkpad_id_data {
 
 	u16 bios_model;		/* Big Endian, TP-1Y = 0x5931, 0 = unknown */
 	u16 ec_model;
+	u16 bios_release;	/* 1ZETK1WW = 0x314b, 0 = unknown */
+	u16 ec_release;
 
 	char *model_str;	/* ThinkPad T43 */
 	char *nummodel_str;	/* 9384A9C for a 9384-A9C model */
@@ -362,6 +364,45 @@ static void tpacpi_log_usertask(const ch
 		} \
 	} while (0)
 
+#define TPACPI_MATCH_ANY		0xffffU
+#define TPACPI_MATCH_UNKNOWN		0U
+
+/* TPID('1', 'Y') == 0x5931 */
+#define TPID(__c1, __c2) (((__c2) << 8) | (__c1))
+
+#define TPACPI_Q_IBM(__id1, __id2, __quirk)	\
+	{ .vendor = PCI_VENDOR_ID_IBM,		\
+	  .bios = TPID(__id1, __id2),		\
+	  .ec = TPACPI_MATCH_ANY,		\
+	  .quirks = (__quirk) }
+
+struct tpacpi_quirk {
+	unsigned int vendor;
+	u16 bios;
+	u16 ec;
+	unsigned long quirks;
+};
+
+static unsigned long __init tpacpi_check_quirks(
+			const struct tpacpi_quirk *qlist,
+			unsigned int qlist_size)
+{
+	while (qlist_size) {
+		if ((qlist->vendor == thinkpad_id.vendor ||
+				qlist->vendor == TPACPI_MATCH_ANY) &&
+		    (qlist->bios == thinkpad_id.bios_model ||
+				qlist->bios == TPACPI_MATCH_ANY) &&
+		    (qlist->ec == thinkpad_id.ec_model ||
+				qlist->ec == TPACPI_MATCH_ANY))
+			return qlist->quirks;
+
+		qlist_size--;
+		qlist++;
+	}
+	return 0;
+}
+
+
 /****************************************************************************
  ****************************************************************************
  *
@@ -5757,14 +5798,27 @@ static struct backlight_ops ibm_backligh
 
 /* --------------------------------------------------------------------- */
 
+#define TPACPI_BRGHT_Q_EC	0x0002  /* Should or must use EC HBRV */
+
+static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
+	TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC),
+	TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_EC),
+};
+
 static int __init brightness_init(struct ibm_init_struct *iibm)
 {
 	int b;
+	unsigned long quirks;
 
 	vdbg_printk(TPACPI_DBG_INIT, "initializing brightness subdriver\n");
 
 	mutex_init(&brightness_mutex);
 
+	quirks = tpacpi_check_quirks(brightness_quirk_table,
+				ARRAY_SIZE(brightness_quirk_table));
+
 	/*
 	 * We always attempt to detect acpi support, so as to switch
 	 * Lenovo Vista BIOS to ACPI brightness mode even if we are not
@@ -5821,19 +5875,9 @@ static int __init brightness_init(struct
 	/* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
 	if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
 	    brightness_mode == TPACPI_BRGHT_MODE_MAX) {
-		if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
-			/*
-			 * IBM models that define HBRV probably have
-			 * EC-based backlight level control
-			 */
-			if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
-				/* T40-T43, R50-R52, R50e, R51e, X31-X41 */
-				brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
-			else
-				/* all other IBM ThinkPads */
-				brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
-		} else
-			/* All Lenovo ThinkPads */
+		if (quirks & TPACPI_BRGHT_Q_EC)
+			brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+		else
 			brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
 
 		dbg_printk(TPACPI_DBG_BRGHT,
@@ -7387,6 +7431,8 @@ static int __must_check __init get_think
 		return 0;
 	tp->bios_model = tp->bios_version_str[0]
 			 | (tp->bios_version_str[1] << 8);
+	tp->bios_release = (tp->bios_version_str[4] << 8)
+			 | tp->bios_version_str[5];
 
 	/*
 	 * ThinkPad T23 or newer, A31 or newer, R50e or newer,
@@ -7407,6 +7453,8 @@ static int __must_check __init get_think
 				return -ENOMEM;
 			tp->ec_model = ec_fw_string[0]
 					| (ec_fw_string[1] << 8);
+			tp->ec_release = (ec_fw_string[4] << 8)
+					| ec_fw_string[5];
 			break;
 		}
 	}
diff -druNp linux-libre-2.6.30-gnu1/drivers/platform/x86/wmi.c linux-libre-2.6.30.10-gnu1/drivers/platform/x86/wmi.c
--- linux-libre-2.6.30-gnu1/drivers/platform/x86/wmi.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/platform/x86/wmi.c	2009-12-04 01:00:07.000000000 -0500
@@ -270,7 +270,7 @@ u32 method_id, const struct acpi_buffer
 	acpi_status status;
 	struct acpi_object_list input;
 	union acpi_object params[3];
-	char method[4] = "WM";
+	char method[5] = "WM";
 
 	if (!find_guid(guid_string, &wblock))
 		return AE_ERROR;
@@ -328,8 +328,8 @@ struct acpi_buffer *out)
 	acpi_status status, wc_status = AE_ERROR;
 	struct acpi_object_list input, wc_input;
 	union acpi_object wc_params[1], wq_params[1];
-	char method[4];
-	char wc_method[4] = "WC";
+	char method[5];
+	char wc_method[5] = "WC";
 
 	if (!guid_string || !out)
 		return AE_BAD_PARAMETER;
@@ -410,7 +410,7 @@ const struct acpi_buffer *in)
 	acpi_handle handle;
 	struct acpi_object_list input;
 	union acpi_object params[2];
-	char method[4] = "WS";
+	char method[5] = "WS";
 
 	if (!guid_string || !in)
 		return AE_BAD_DATA;
diff -druNp linux-libre-2.6.30-gnu1/drivers/ps3/ps3stor_lib.c linux-libre-2.6.30.10-gnu1/drivers/ps3/ps3stor_lib.c
--- linux-libre-2.6.30-gnu1/drivers/ps3/ps3stor_lib.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/ps3/ps3stor_lib.c	2009-12-04 01:00:07.000000000 -0500
@@ -23,6 +23,65 @@
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
 
+/*
+ * A workaround for flash memory I/O errors when the internal hard disk
+ * has not been formatted for OtherOS use.  Delay disk close until flash
+ * memory is closed.
+ */
+
+static struct ps3_flash_workaround {
+	int flash_open;
+	int disk_open;
+	struct ps3_system_bus_device *disk_sbd;
+} ps3_flash_workaround;
+
+static int ps3stor_open_hv_device(struct ps3_system_bus_device *sbd)
+{
+	int error = ps3_open_hv_device(sbd);
+
+	if (error)
+		return error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH)
+		ps3_flash_workaround.flash_open = 1;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK)
+		ps3_flash_workaround.disk_open = 1;
+
+	return 0;
+}
+
+static int ps3stor_close_hv_device(struct ps3_system_bus_device *sbd)
+{
+	int error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK
+		&& ps3_flash_workaround.disk_open
+		&& ps3_flash_workaround.flash_open) {
+		ps3_flash_workaround.disk_sbd = sbd;
+		return 0;
+	}
+
+	error = ps3_close_hv_device(sbd);
+
+	if (error)
+		return error;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_DISK)
+		ps3_flash_workaround.disk_open = 0;
+
+	if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH) {
+		ps3_flash_workaround.flash_open = 0;
+
+		if (ps3_flash_workaround.disk_sbd) {
+			ps3_close_hv_device(ps3_flash_workaround.disk_sbd);
+			ps3_flash_workaround.disk_open = 0;
+			ps3_flash_workaround.disk_sbd = NULL;
+		}
+	}
+
+	return 0;
+}
 
 static int ps3stor_probe_access(struct ps3_storage_device *dev)
 {
@@ -90,7 +149,7 @@ int ps3stor_setup(struct ps3_storage_dev
 	int error, res, alignment;
 	enum ps3_dma_page_size page_size;
 
-	error = ps3_open_hv_device(&dev->sbd);
+	error = ps3stor_open_hv_device(&dev->sbd);
 	if (error) {
 		dev_err(&dev->sbd.core,
 			"%s:%u: ps3_open_hv_device failed %d\n", __func__,
@@ -166,7 +225,7 @@ fail_free_irq:
 fail_sb_event_receive_port_destroy:
 	ps3_sb_event_receive_port_destroy(&dev->sbd, dev->irq);
 fail_close_device:
-	ps3_close_hv_device(&dev->sbd);
+	ps3stor_close_hv_device(&dev->sbd);
 fail:
 	return error;
 }
@@ -193,7 +252,7 @@ void ps3stor_teardown(struct ps3_storage
 			"%s:%u: destroy event receive port failed %d\n",
 			__func__, __LINE__, error);
 
-	error = ps3_close_hv_device(&dev->sbd);
+	error = ps3stor_close_hv_device(&dev->sbd);
 	if (error)
 		dev_err(&dev->sbd.core,
 			"%s:%u: ps3_close_hv_device failed %d\n", __func__,
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/libsas/sas_port.c linux-libre-2.6.30.10-gnu1/drivers/scsi/libsas/sas_port.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/libsas/sas_port.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/libsas/sas_port.c	2009-12-04 01:00:07.000000000 -0500
@@ -56,7 +56,7 @@ static void sas_form_port(struct asd_sas
 		}
 	}
 
-	/* find a port */
+	/* see if the phy should be part of a wide port */
 	spin_lock_irqsave(&sas_ha->phy_port_lock, flags);
 	for (i = 0; i < sas_ha->num_phys; i++) {
 		port = sas_ha->sas_port[i];
@@ -69,12 +69,23 @@ static void sas_form_port(struct asd_sas
 			SAS_DPRINTK("phy%d matched wide port%d\n", phy->id,
 				    port->id);
 			break;
-		} else if (*(u64 *) port->sas_addr == 0 && port->num_phys==0) {
-			memcpy(port->sas_addr, phy->sas_addr, SAS_ADDR_SIZE);
-			break;
 		}
 		spin_unlock(&port->phy_list_lock);
 	}
+	/* The phy does not match any existing port, create a new one */
+	if (i == sas_ha->num_phys) {
+		for (i = 0; i < sas_ha->num_phys; i++) {
+			port = sas_ha->sas_port[i];
+			spin_lock(&port->phy_list_lock);
+			if (*(u64 *)port->sas_addr == 0
+				&& port->num_phys == 0) {
+				memcpy(port->sas_addr, phy->sas_addr,
+					SAS_ADDR_SIZE);
+				break;
+			}
+			spin_unlock(&port->phy_list_lock);
+		}
+	}
 
 	if (i >= sas_ha->num_phys) {
 		printk(KERN_NOTICE "%s: couldn't find a free port, bug?\n",
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.c	2009-12-04 01:00:07.000000000 -0500
@@ -119,6 +119,64 @@ _base_fault_reset_work(struct work_struc
 	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
 }
 
+/**
+ * mpt2sas_base_start_watchdog - start the fault_reset_work_q
+ * @ioc: pointer to scsi command object
+ * Context: sleep.
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc)
+{
+	unsigned long	 flags;
+
+	if (ioc->fault_reset_work_q)
+		return;
+
+	/* initialize fault polling */
+	INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
+	snprintf(ioc->fault_reset_work_q_name,
+	    sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
+	ioc->fault_reset_work_q =
+		create_singlethread_workqueue(ioc->fault_reset_work_q_name);
+	if (!ioc->fault_reset_work_q) {
+		printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
+		    ioc->name, __func__, __LINE__);
+			return;
+	}
+	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
+	if (ioc->fault_reset_work_q)
+		queue_delayed_work(ioc->fault_reset_work_q,
+		    &ioc->fault_reset_work,
+		    msecs_to_jiffies(FAULT_POLLING_INTERVAL));
+	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+}
+
+/**
+ * mpt2sas_base_stop_watchdog - stop the fault_reset_work_q
+ * @ioc: pointer to scsi command object
+ * Context: sleep.
+ *
+ * Return nothing.
+ */
+void
+mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc)
+{
+	unsigned long	 flags;
+	struct workqueue_struct *wq;
+
+	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
+	wq = ioc->fault_reset_work_q;
+	ioc->fault_reset_work_q = NULL;
+	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	if (wq) {
+		if (!cancel_delayed_work(&ioc->fault_reset_work))
+			flush_workqueue(wq);
+		destroy_workqueue(wq);
+	}
+}
+
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 /**
  * _base_sas_ioc_info - verbose translation of the ioc status
@@ -440,6 +498,10 @@ _base_sas_log_info(struct MPT2SAS_ADAPTE
 	if (sas_loginfo.dw.bus_type != 3 /*SAS*/)
 		return;
 
+	/* each nexus loss loginfo */
+	if (log_info == 0x31170000)
+		return;
+
 	/* eat the loginfos associated with task aborts */
 	if (ioc->ignore_loginfos && (log_info == 30050000 || log_info ==
 	    0x31140000 || log_info == 0x31130000))
@@ -1109,7 +1171,6 @@ mpt2sas_base_map_resources(struct MPT2SA
 		}
 	}
 
-	pci_set_drvdata(pdev, ioc->shost);
 	_base_mask_interrupts(ioc);
 	r = _base_enable_msix(ioc);
 	if (r)
@@ -1132,7 +1193,6 @@ mpt2sas_base_map_resources(struct MPT2SA
 	ioc->pci_irq = -1;
 	pci_release_selected_regions(ioc->pdev, ioc->bars);
 	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
 	return r;
 }
 
@@ -3191,7 +3251,6 @@ mpt2sas_base_free_resources(struct MPT2S
 	ioc->chip_phys = 0;
 	pci_release_selected_regions(ioc->pdev, ioc->bars);
 	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
 	return;
 }
 
@@ -3205,7 +3264,6 @@ int
 mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc)
 {
 	int r, i;
-	unsigned long	 flags;
 
 	dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
@@ -3214,6 +3272,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 	if (r)
 		return r;
 
+	pci_set_drvdata(ioc->pdev, ioc->shost);
 	r = _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
 	if (r)
 		goto out_free_resources;
@@ -3288,23 +3347,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 	if (r)
 		goto out_free_resources;
 
-	/* initialize fault polling */
-	INIT_DELAYED_WORK(&ioc->fault_reset_work, _base_fault_reset_work);
-	snprintf(ioc->fault_reset_work_q_name,
-	    sizeof(ioc->fault_reset_work_q_name), "poll_%d_status", ioc->id);
-	ioc->fault_reset_work_q =
-		create_singlethread_workqueue(ioc->fault_reset_work_q_name);
-	if (!ioc->fault_reset_work_q) {
-		printk(MPT2SAS_ERR_FMT "%s: failed (line=%d)\n",
-		    ioc->name, __func__, __LINE__);
-			goto out_free_resources;
-	}
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	if (ioc->fault_reset_work_q)
-		queue_delayed_work(ioc->fault_reset_work_q,
-		    &ioc->fault_reset_work,
-		    msecs_to_jiffies(FAULT_POLLING_INTERVAL));
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
+	mpt2sas_base_start_watchdog(ioc);
 	return 0;
 
  out_free_resources:
@@ -3312,6 +3355,7 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 	ioc->remove_host = 1;
 	mpt2sas_base_free_resources(ioc);
 	_base_release_memory_pools(ioc);
+	pci_set_drvdata(ioc->pdev, NULL);
 	kfree(ioc->tm_cmds.reply);
 	kfree(ioc->transport_cmds.reply);
 	kfree(ioc->config_cmds.reply);
@@ -3337,22 +3381,14 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPT
 void
 mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc)
 {
-	unsigned long	 flags;
-	struct workqueue_struct *wq;
 
 	dexitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
 	    __func__));
 
-	spin_lock_irqsave(&ioc->ioc_reset_in_progress_lock, flags);
-	wq = ioc->fault_reset_work_q;
-	ioc->fault_reset_work_q = NULL;
-	spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
-	if (!cancel_delayed_work(&ioc->fault_reset_work))
-		flush_workqueue(wq);
-	destroy_workqueue(wq);
-
+	mpt2sas_base_stop_watchdog(ioc);
 	mpt2sas_base_free_resources(ioc);
 	_base_release_memory_pools(ioc);
+	pci_set_drvdata(ioc->pdev, NULL);
 	kfree(ioc->pfacts);
 	kfree(ioc->ctl_cmds.reply);
 	kfree(ioc->base_cmds.reply);
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h
--- linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_base.h	2009-12-04 01:00:07.000000000 -0500
@@ -672,6 +672,8 @@ typedef void (*MPT_CALLBACK)(struct MPT2
 
 /* base shared API */
 extern struct list_head mpt2sas_ioc_list;
+void mpt2sas_base_start_watchdog(struct MPT2SAS_ADAPTER *ioc);
+void mpt2sas_base_stop_watchdog(struct MPT2SAS_ADAPTER *ioc);
 
 int mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc);
 void mpt2sas_base_detach(struct MPT2SAS_ADAPTER *ioc);
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_config.c	2009-12-04 01:00:07.000000000 -0500
@@ -236,17 +236,25 @@ _config_request(struct MPT2SAS_ADAPTER *
 	Mpi2ConfigRequest_t *config_request;
 	int r;
 	u8 retry_count;
-	u8 issue_reset;
+	u8 issue_host_reset = 0;
 	u16 wait_state_count;
 
+	mutex_lock(&ioc->config_cmds.mutex);
 	if (ioc->config_cmds.status != MPT2_CMD_NOT_USED) {
 		printk(MPT2SAS_ERR_FMT "%s: config_cmd in use\n",
 		    ioc->name, __func__);
+		mutex_unlock(&ioc->config_cmds.mutex);
 		return -EAGAIN;
 	}
 	retry_count = 0;
 
  retry_config:
+	if (retry_count) {
+		if (retry_count > 2) /* attempt only 2 retries */
+			return -EFAULT;
+		printk(MPT2SAS_INFO_FMT "%s: attempting retry (%d)\n",
+		    ioc->name, __func__, retry_count);
+	}
 	wait_state_count = 0;
 	ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
 	while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
@@ -254,8 +262,8 @@ _config_request(struct MPT2SAS_ADAPTER *
 			printk(MPT2SAS_ERR_FMT
 			    "%s: failed due to ioc not operational\n",
 			    ioc->name, __func__);
-			ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-			return -EFAULT;
+			r = -EFAULT;
+			goto out;
 		}
 		ssleep(1);
 		ioc_state = mpt2sas_base_get_iocstate(ioc, 1);
@@ -271,8 +279,8 @@ _config_request(struct MPT2SAS_ADAPTER *
 	if (!smid) {
 		printk(MPT2SAS_ERR_FMT "%s: failed obtaining a smid\n",
 		    ioc->name, __func__);
-		ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-		return -EAGAIN;
+		r = -EAGAIN;
+		goto out;
 	}
 
 	r = 0;
@@ -292,9 +300,15 @@ _config_request(struct MPT2SAS_ADAPTER *
 		    ioc->name, __func__);
 		_debug_dump_mf(mpi_request,
 		    sizeof(Mpi2ConfigRequest_t)/4);
-		if (!(ioc->config_cmds.status & MPT2_CMD_RESET))
-			issue_reset = 1;
-		goto issue_host_reset;
+		retry_count++;
+		if (ioc->config_cmds.smid == smid)
+			mpt2sas_base_free_smid(ioc, smid);
+		if ((ioc->shost_recovery) ||
+		    (ioc->config_cmds.status & MPT2_CMD_RESET))
+			goto retry_config;
+		issue_host_reset = 1;
+		r = -EFAULT;
+		goto out;
 	}
 	if (ioc->config_cmds.status & MPT2_CMD_REPLY_VALID)
 		memcpy(mpi_reply, ioc->config_cmds.reply,
@@ -302,21 +316,13 @@ _config_request(struct MPT2SAS_ADAPTER *
 	if (retry_count)
 		printk(MPT2SAS_INFO_FMT "%s: retry completed!!\n",
 		    ioc->name, __func__);
+out:
 	ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-	return r;
-
- issue_host_reset:
-	if (issue_reset)
+	mutex_unlock(&ioc->config_cmds.mutex);
+	if (issue_host_reset)
 		mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
 		    FORCE_BIG_HAMMER);
-	ioc->config_cmds.status = MPT2_CMD_NOT_USED;
-	if (!retry_count) {
-		printk(MPT2SAS_INFO_FMT "%s: attempting retry\n",
-		    ioc->name, __func__);
-		retry_count++;
-		goto retry_config;
-	}
-	return -EFAULT;
+	return r;
 }
 
 /**
@@ -375,7 +381,6 @@ mpt2sas_config_get_manufacturing_pg0(str
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2ManufacturingPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -417,7 +422,6 @@ mpt2sas_config_get_manufacturing_pg0(str
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -438,7 +442,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2S
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2BiosPage2_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -480,7 +483,6 @@ mpt2sas_config_get_bios_pg2(struct MPT2S
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -501,7 +503,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2S
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2BiosPage3_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -543,7 +544,6 @@ mpt2sas_config_get_bios_pg3(struct MPT2S
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -564,7 +564,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2IOUnitPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -606,7 +605,6 @@ mpt2sas_config_get_iounit_pg0(struct MPT
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -627,7 +625,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2IOUnitPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -669,7 +666,6 @@ mpt2sas_config_get_iounit_pg1(struct MPT
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -690,7 +686,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -732,7 +727,6 @@ mpt2sas_config_set_iounit_pg1(struct MPT
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -753,7 +747,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SA
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2IOCPage8_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -795,7 +788,6 @@ mpt2sas_config_get_ioc_pg8(struct MPT2SA
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -818,7 +810,6 @@ mpt2sas_config_get_sas_device_pg0(struct
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2SasDevicePage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -863,7 +854,6 @@ mpt2sas_config_get_sas_device_pg0(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -886,7 +876,6 @@ mpt2sas_config_get_sas_device_pg1(struct
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2SasDevicePage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -931,7 +920,6 @@ mpt2sas_config_get_sas_device_pg1(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -953,7 +941,6 @@ mpt2sas_config_get_number_hba_phys(struc
 	Mpi2ConfigReply_t mpi_reply;
 	Mpi2SasIOUnitPage0_t config_page;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
 	mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
@@ -1002,7 +989,6 @@ mpt2sas_config_get_number_hba_phys(struc
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1026,8 +1012,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct
 	Mpi2ConfigRequest_t mpi_request;
 	int r;
 	struct config_request mem;
-
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sz);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1070,7 +1054,6 @@ mpt2sas_config_get_sas_iounit_pg0(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1095,7 +1078,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sz);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1138,7 +1120,6 @@ mpt2sas_config_get_sas_iounit_pg1(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1161,7 +1142,6 @@ mpt2sas_config_get_expander_pg0(struct M
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2ExpanderPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1206,7 +1186,6 @@ mpt2sas_config_get_expander_pg0(struct M
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1230,7 +1209,6 @@ mpt2sas_config_get_expander_pg1(struct M
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2ExpanderPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1277,7 +1255,6 @@ mpt2sas_config_get_expander_pg1(struct M
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1300,7 +1277,6 @@ mpt2sas_config_get_enclosure_pg0(struct
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2SasEnclosurePage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1345,7 +1321,6 @@ mpt2sas_config_get_enclosure_pg0(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1367,7 +1342,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SA
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2SasPhyPage0_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1413,7 +1387,6 @@ mpt2sas_config_get_phy_pg0(struct MPT2SA
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1435,7 +1408,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SA
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2SasPhyPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1481,7 +1453,6 @@ mpt2sas_config_get_phy_pg1(struct MPT2SA
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1505,7 +1476,6 @@ mpt2sas_config_get_raid_volume_pg1(struc
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(config_page, 0, sizeof(Mpi2RaidVolPage1_t));
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1548,7 +1518,6 @@ mpt2sas_config_get_raid_volume_pg1(struc
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1572,7 +1541,6 @@ mpt2sas_config_get_number_pds(struct MPT
 	struct config_request mem;
 	u16 ioc_status;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	*num_pds = 0;
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1620,7 +1588,6 @@ mpt2sas_config_get_number_pds(struct MPT
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1645,7 +1612,6 @@ mpt2sas_config_get_raid_volume_pg0(struc
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	memset(config_page, 0, sz);
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1687,7 +1653,6 @@ mpt2sas_config_get_raid_volume_pg0(struc
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1711,7 +1676,6 @@ mpt2sas_config_get_phys_disk_pg0(struct
 	int r;
 	struct config_request mem;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	memset(config_page, 0, sizeof(Mpi2RaidPhysDiskPage0_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1754,7 +1718,6 @@ mpt2sas_config_get_phys_disk_pg0(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
@@ -1778,7 +1741,6 @@ mpt2sas_config_get_volume_handle(struct
 	struct config_request mem;
 	u16 ioc_status;
 
-	mutex_lock(&ioc->config_cmds.mutex);
 	*volume_handle = 0;
 	memset(&mpi_request, 0, sizeof(Mpi2ConfigRequest_t));
 	mpi_request.Function = MPI2_FUNCTION_CONFIG;
@@ -1842,7 +1804,6 @@ mpt2sas_config_get_volume_handle(struct
 		_config_free_config_dma_memory(ioc, &mem);
 
  out:
-	mutex_unlock(&ioc->config_cmds.mutex);
 	return r;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2009-12-04 01:00:07.000000000 -0500
@@ -2560,6 +2560,10 @@ _scsih_scsi_ioc_info(struct MPT2SAS_ADAP
 	char *desc_ioc_state = NULL;
 	char *desc_scsi_status = NULL;
 	char *desc_scsi_state = ioc->tmp_string;
+	u32 log_info = le32_to_cpu(mpi_reply->IOCLogInfo);
+
+	if (log_info == 0x31170000)
+		return;
 
 	switch (ioc_status) {
 	case MPI2_IOCSTATUS_SUCCESS:
@@ -3205,7 +3209,7 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 	__le64 sas_address;
 	int i;
 	unsigned long flags;
-	struct _sas_port *mpt2sas_port;
+	struct _sas_port *mpt2sas_port = NULL;
 	int rc = 0;
 
 	if (!handle)
@@ -3297,12 +3301,20 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 		    &expander_pg1, i, handle))) {
 			printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
 			    ioc->name, __FILE__, __LINE__, __func__);
-			continue;
+			rc = -1;
+			goto out_fail;
 		}
 		sas_expander->phy[i].handle = handle;
 		sas_expander->phy[i].phy_id = i;
-		mpt2sas_transport_add_expander_phy(ioc, &sas_expander->phy[i],
-		    expander_pg1, sas_expander->parent_dev);
+
+		if ((mpt2sas_transport_add_expander_phy(ioc,
+		    &sas_expander->phy[i], expander_pg1,
+		    sas_expander->parent_dev))) {
+			printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+			    ioc->name, __FILE__, __LINE__, __func__);
+			rc = -1;
+			goto out_fail;
+		}
 	}
 
 	if (sas_expander->enclosure_handle) {
@@ -3319,8 +3331,9 @@ _scsih_expander_add(struct MPT2SAS_ADAPT
 
  out_fail:
 
-	if (sas_expander)
-		kfree(sas_expander->phy);
+	if (mpt2sas_port)
+		mpt2sas_transport_port_remove(ioc, sas_expander->sas_address,
+		    sas_expander->parent_handle);
 	kfree(sas_expander);
 	return rc;
 }
@@ -3442,12 +3455,11 @@ _scsih_add_device(struct MPT2SAS_ADAPTER
 	sas_device->hidden_raid_component = is_pd;
 
 	/* get enclosure_logical_id */
-	if (!(mpt2sas_config_get_enclosure_pg0(ioc, &mpi_reply, &enclosure_pg0,
-	   MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
-	   sas_device->enclosure_handle))) {
+	if (sas_device->enclosure_handle && !(mpt2sas_config_get_enclosure_pg0(
+	   ioc, &mpi_reply, &enclosure_pg0, MPI2_SAS_ENCLOS_PGAD_FORM_HANDLE,
+	   sas_device->enclosure_handle)))
 		sas_device->enclosure_logical_id =
 		    le64_to_cpu(enclosure_pg0.EnclosureLogicalID);
-	}
 
 	/* get device name */
 	sas_device->device_name = le64_to_cpu(sas_device_pg0.DeviceName);
@@ -4029,12 +4041,6 @@ _scsih_sas_volume_add(struct MPT2SAS_ADA
 	u16 handle = le16_to_cpu(element->VolDevHandle);
 	int rc;
 
-#if 0 /* RAID_HACKS */
-	if (le32_to_cpu(event_data->Flags) &
-	    MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
-		return;
-#endif
-
 	mpt2sas_config_get_volume_wwid(ioc, handle, &wwid);
 	if (!wwid) {
 		printk(MPT2SAS_ERR_FMT
@@ -4089,12 +4095,6 @@ _scsih_sas_volume_delete(struct MPT2SAS_
 	unsigned long flags;
 	struct MPT2SAS_TARGET *sas_target_priv_data;
 
-#if 0 /* RAID_HACKS */
-	if (le32_to_cpu(event_data->Flags) &
-	    MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG)
-		return;
-#endif
-
 	spin_lock_irqsave(&ioc->raid_device_lock, flags);
 	raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
 	spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -4207,14 +4207,38 @@ _scsih_sas_pd_add(struct MPT2SAS_ADAPTER
 	struct _sas_device *sas_device;
 	unsigned long flags;
 	u16 handle = le16_to_cpu(element->PhysDiskDevHandle);
+	Mpi2ConfigReply_t mpi_reply;
+	Mpi2SasDevicePage0_t sas_device_pg0;
+	u32 ioc_status;
 
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
-	if (sas_device)
+	if (sas_device) {
 		sas_device->hidden_raid_component = 1;
-	else
-		_scsih_add_device(ioc, handle, 0, 1);
+		return;
+	}
+
+	if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply, &sas_device_pg0,
+	    MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle))) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return;
+	}
+
+	ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+	    MPI2_IOCSTATUS_MASK;
+	if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+		    ioc->name, __FILE__, __LINE__, __func__);
+		return;
+	}
+
+	_scsih_link_change(ioc,
+	    le16_to_cpu(sas_device_pg0.ParentDevHandle),
+	    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+
+	_scsih_add_device(ioc, handle, 0, 1);
 }
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
@@ -4314,12 +4338,15 @@ _scsih_sas_ir_config_change_event(struct
 {
 	Mpi2EventIrConfigElement_t *element;
 	int i;
+	u8 foreign_config;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
 	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
 		_scsih_sas_ir_config_change_event_debug(ioc, event_data);
 
 #endif
+	foreign_config = (le32_to_cpu(event_data->Flags) &
+	    MPI2_EVENT_IR_CHANGE_FLAGS_FOREIGN_CONFIG) ? 1 : 0;
 
 	element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
 	for (i = 0; i < event_data->NumElements; i++, element++) {
@@ -4327,11 +4354,13 @@ _scsih_sas_ir_config_change_event(struct
 		switch (element->ReasonCode) {
 		case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED:
 		case MPI2_EVENT_IR_CHANGE_RC_ADDED:
-			_scsih_sas_volume_add(ioc, element);
+			if (!foreign_config)
+				_scsih_sas_volume_add(ioc, element);
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED:
 		case MPI2_EVENT_IR_CHANGE_RC_REMOVED:
-			_scsih_sas_volume_delete(ioc, element);
+			if (!foreign_config)
+				_scsih_sas_volume_delete(ioc, element);
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
 			_scsih_sas_pd_hide(ioc, element);
@@ -4450,6 +4479,9 @@ _scsih_sas_ir_physical_disk_event(struct
 	u32 state;
 	struct _sas_device *sas_device;
 	unsigned long flags;
+	Mpi2ConfigReply_t mpi_reply;
+	Mpi2SasDevicePage0_t sas_device_pg0;
+	u32 ioc_status;
 
 	if (event_data->ReasonCode != MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED)
 		return;
@@ -4466,22 +4498,40 @@ _scsih_sas_ir_physical_disk_event(struct
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
 	switch (state) {
-#if 0
-	case MPI2_RAID_PD_STATE_OFFLINE:
-		if (sas_device)
-			_scsih_remove_device(ioc, handle);
-		break;
-#endif
 	case MPI2_RAID_PD_STATE_ONLINE:
 	case MPI2_RAID_PD_STATE_DEGRADED:
 	case MPI2_RAID_PD_STATE_REBUILDING:
 	case MPI2_RAID_PD_STATE_OPTIMAL:
-		if (sas_device)
+		if (sas_device) {
 			sas_device->hidden_raid_component = 1;
-		else
-			_scsih_add_device(ioc, handle, 0, 1);
+			return;
+		}
+
+		if ((mpt2sas_config_get_sas_device_pg0(ioc, &mpi_reply,
+		    &sas_device_pg0, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
+		    handle))) {
+			printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+			    ioc->name, __FILE__, __LINE__, __func__);
+			return;
+		}
+
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+		    MPI2_IOCSTATUS_MASK;
+		if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
+			printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
+			    ioc->name, __FILE__, __LINE__, __func__);
+			return;
+		}
+
+		_scsih_link_change(ioc,
+		    le16_to_cpu(sas_device_pg0.ParentDevHandle),
+		    handle, sas_device_pg0.PhyNum, MPI2_SAS_NEG_LINK_RATE_1_5);
+
+		_scsih_add_device(ioc, handle, 0, 1);
+
 		break;
 
+	case MPI2_RAID_PD_STATE_OFFLINE:
 	case MPI2_RAID_PD_STATE_NOT_CONFIGURED:
 	case MPI2_RAID_PD_STATE_NOT_COMPATIBLE:
 	case MPI2_RAID_PD_STATE_HOT_SPARE:
@@ -5549,6 +5599,7 @@ scsih_suspend(struct pci_dev *pdev, pm_m
 	struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
 	u32 device_state;
 
+	mpt2sas_base_stop_watchdog(ioc);
 	flush_scheduled_work();
 	scsi_block_requests(shost);
 	device_state = pci_choose_state(pdev, state);
@@ -5591,6 +5642,7 @@ scsih_resume(struct pci_dev *pdev)
 
 	mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP, SOFT_RESET);
 	scsi_unblock_requests(shost);
+	mpt2sas_base_start_watchdog(ioc);
 	return 0;
 }
 #endif /* CONFIG_PM */
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/qla2xxx/qla_dbg.c linux-libre-2.6.30.10-gnu1/drivers/scsi/qla2xxx/qla_dbg.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/qla2xxx/qla_dbg.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/qla2xxx/qla_dbg.c	2009-12-04 01:00:07.000000000 -0500
@@ -218,7 +218,7 @@ qla24xx_soft_reset(struct qla_hw_data *h
 
 static int
 qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
-    uint16_t ram_words, void **nxt)
+    uint32_t ram_words, void **nxt)
 {
 	int rval;
 	uint32_t cnt, stat, timer, words, idx;
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/sd.c linux-libre-2.6.30.10-gnu1/drivers/scsi/sd.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/sd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/sd.c	2009-12-04 01:00:07.000000000 -0500
@@ -1902,24 +1902,6 @@ static void sd_probe_async(void *data, a
 	index = sdkp->index;
 	dev = &sdp->sdev_gendev;
 
-	if (!sdp->request_queue->rq_timeout) {
-		if (sdp->type != TYPE_MOD)
-			blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
-		else
-			blk_queue_rq_timeout(sdp->request_queue,
-					     SD_MOD_TIMEOUT);
-	}
-
-	device_initialize(&sdkp->dev);
-	sdkp->dev.parent = &sdp->sdev_gendev;
-	sdkp->dev.class = &sd_disk_class;
-	dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
-
-	if (device_add(&sdkp->dev))
-		goto out_free_index;
-
-	get_device(&sdp->sdev_gendev);
-
 	if (index < SD_MAX_DISKS) {
 		gd->major = sd_major((index & 0xf0) >> 4);
 		gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
@@ -1954,11 +1936,6 @@ static void sd_probe_async(void *data, a
 
 	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
 		  sdp->removable ? "removable " : "");
-
-	return;
-
- out_free_index:
-	ida_remove(&sd_index_ida, index);
 }
 
 /**
@@ -2026,6 +2003,24 @@ static int sd_probe(struct device *dev)
 	sdkp->openers = 0;
 	sdkp->previous_state = 1;
 
+	if (!sdp->request_queue->rq_timeout) {
+		if (sdp->type != TYPE_MOD)
+			blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
+		else
+			blk_queue_rq_timeout(sdp->request_queue,
+					     SD_MOD_TIMEOUT);
+	}
+
+	device_initialize(&sdkp->dev);
+	sdkp->dev.parent = &sdp->sdev_gendev;
+	sdkp->dev.class = &sd_disk_class;
+	dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev));
+
+	if (device_add(&sdkp->dev))
+		goto out_free_index;
+
+	get_device(&sdp->sdev_gendev);
+
 	async_schedule(sd_probe_async, sdkp);
 
 	return 0;
@@ -2055,8 +2050,10 @@ static int sd_probe(struct device *dev)
  **/
 static int sd_remove(struct device *dev)
 {
-	struct scsi_disk *sdkp = dev_get_drvdata(dev);
+	struct scsi_disk *sdkp;
 
+	async_synchronize_full();
+	sdkp = dev_get_drvdata(dev);
 	device_del(&sdkp->dev);
 	del_gendisk(sdkp->disk);
 	sd_shutdown(dev);
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/sg.c linux-libre-2.6.30.10-gnu1/drivers/scsi/sg.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/sg.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/sg.c	2009-12-04 01:00:07.000000000 -0500
@@ -1656,6 +1656,10 @@ static int sg_start_req(Sg_request *srp,
 		md->nr_entries = req_schp->k_use_sg;
 		md->offset = 0;
 		md->null_mapped = hp->dxferp ? 0 : 1;
+		if (dxfer_dir == SG_DXFER_TO_FROM_DEV)
+			md->from_user = 1;
+		else
+			md->from_user = 0;
 	}
 
 	if (iov_count) {
@@ -1807,7 +1811,7 @@ retry:
 	return 0;
 out:
 	for (i = 0; i < k; i++)
-		__free_pages(schp->pages[k], order);
+		__free_pages(schp->pages[i], order);
 
 	if (--order >= 0)
 		goto retry;
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/sym53c8xx_2/sym_hipd.c linux-libre-2.6.30.10-gnu1/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/sym53c8xx_2/sym_hipd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/sym53c8xx_2/sym_hipd.c	2009-12-04 01:00:07.000000000 -0500
@@ -2312,8 +2312,9 @@ static void sym_int_par (struct sym_hcb
 	int phase	= cmd & 7;
 	struct sym_ccb *cp	= sym_ccb_from_dsa(np, dsa);
 
-	printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
-		sym_name(np), hsts, dbc, sbcl);
+	if (printk_ratelimit())
+		printf("%s: SCSI parity error detected: SCR1=%d DBC=%x SBCL=%x\n",
+			sym_name(np), hsts, dbc, sbcl);
 
 	/*
 	 *  Check that the chip is connected to the SCSI BUS.
diff -druNp linux-libre-2.6.30-gnu1/drivers/scsi/zalon.c linux-libre-2.6.30.10-gnu1/drivers/scsi/zalon.c
--- linux-libre-2.6.30-gnu1/drivers/scsi/zalon.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/scsi/zalon.c	2009-12-04 01:00:07.000000000 -0500
@@ -134,7 +134,7 @@ zalon_probe(struct parisc_device *dev)
 
 	host = ncr_attach(&zalon7xx_template, unit, &device);
 	if (!host)
-		goto fail;
+		return -ENODEV;
 
 	if (request_irq(dev->irq, ncr53c8xx_intr, IRQF_SHARED, "zalon", host)) {
 	  dev_printk(KERN_ERR, &dev->dev, "irq problem with %d, detaching\n ",
diff -druNp linux-libre-2.6.30-gnu1/drivers/serial/bfin_5xx.c linux-libre-2.6.30.10-gnu1/drivers/serial/bfin_5xx.c
--- linux-libre-2.6.30-gnu1/drivers/serial/bfin_5xx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/serial/bfin_5xx.c	2009-12-04 01:00:07.000000000 -0500
@@ -38,6 +38,10 @@
 #include <asm/cacheflush.h>
 #endif
 
+#ifdef CONFIG_SERIAL_BFIN_MODULE
+# undef CONFIG_EARLY_PRINTK
+#endif
+
 /* UART name and device definitions */
 #define BFIN_SERIAL_NAME	"ttyBF"
 #define BFIN_SERIAL_MAJOR	204
@@ -1058,6 +1062,7 @@ static void __init bfin_serial_init_port
 	bfin_serial_hw_init();
 
 	for (i = 0; i < nr_active_ports; i++) {
+		spin_lock_init(&bfin_serial_ports[i].port.lock);
 		bfin_serial_ports[i].port.uartclk   = get_sclk();
 		bfin_serial_ports[i].port.fifosize  = BFIN_UART_TX_FIFO_SIZE;
 		bfin_serial_ports[i].port.ops       = &bfin_serial_pops;
diff -druNp linux-libre-2.6.30-gnu1/drivers/spi/spi_mpc83xx.c linux-libre-2.6.30.10-gnu1/drivers/spi/spi_mpc83xx.c
--- linux-libre-2.6.30-gnu1/drivers/spi/spi_mpc83xx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/spi/spi_mpc83xx.c	2009-12-04 01:00:07.000000000 -0500
@@ -711,12 +711,12 @@ static int of_mpc83xx_spi_get_chipselect
 		return 0;
 	}
 
-	pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
+	pinfo->gpios = kmalloc(ngpios * sizeof(*pinfo->gpios), GFP_KERNEL);
 	if (!pinfo->gpios)
 		return -ENOMEM;
-	memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
+	memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios));
 
-	pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
+	pinfo->alow_flags = kzalloc(ngpios * sizeof(*pinfo->alow_flags),
 				    GFP_KERNEL);
 	if (!pinfo->alow_flags) {
 		ret = -ENOMEM;
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/2870_main_dev.c linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/2870_main_dev.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/2870_main_dev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/2870_main_dev.c	2009-12-04 01:00:07.000000000 -0500
@@ -265,7 +265,7 @@ INT MlmeThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-	pObj->MLMEThr_task = NULL;
+	pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
 
 	complete_and_exit (&pAd->mlmeComplete, 0);
 	return 0;
@@ -373,7 +373,7 @@ INT RTUSBCmdThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
 
-	pObj->RTUSBCmdThr_task = NULL;
+	pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
 
 	complete_and_exit (&pAd->CmdQComplete, 0);
 	return 0;
@@ -467,7 +467,7 @@ INT TimerQThread(
 	 */
 	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
 
-	pObj->TimerQThr_task = NULL;
+	pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
 
 	complete_and_exit(&pAd->TimerQComplete, 0);
 	return 0;
@@ -944,46 +944,69 @@ VOID RT28xxThreadTerminate(
 	RTUSBCancelPendingIRPs(pAd);
 
 	// Terminate Threads
-	BUG_ON(pObj->TimerQThr_task == NULL);
-	CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task))
+	CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
 	{
 		POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
 
-		printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n",
-			pid_nr(task_pid(pObj->TimerQThr_task)));
+		printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
 		mb();
 		pAd->TimerFunc_kill = 1;
 		mb();
-		kthread_stop(pObj->TimerQThr_task);
-		pObj->TimerQThr_task = NULL;
+		ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
+		}
+		else
+		{
+			wait_for_completion(&pAd->TimerQComplete);
+			pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
+		}
 	}
 
-	BUG_ON(pObj->MLMEThr_task == NULL);
-	CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))
+	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
 	{
-		printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n",
-			pid_nr(task_pid(pObj->MLMEThr_task)));
+		printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
 		mb();
 		pAd->mlme_kill = 1;
 		//RT28XX_MLME_HANDLER(pAd);
 		mb();
-		kthread_stop(pObj->MLMEThr_task);
-		pObj->MLMEThr_task = NULL;
+		ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret);
+		}
+		else
+		{
+			//wait_for_completion (&pAd->notify);
+			wait_for_completion (&pAd->mlmeComplete);
+			pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
+		}
 	}
 
-	BUG_ON(pObj->RTUSBCmdThr_task == NULL);
-	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
+	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
 	{
-		printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n",
-			pid_nr(task_pid(pObj->RTUSBCmdThr_task)));
+		printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
 		mb();
 		NdisAcquireSpinLock(&pAd->CmdQLock);
 		pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
 		NdisReleaseSpinLock(&pAd->CmdQLock);
 		mb();
 		//RTUSBCMDUp(pAd);
-		kthread_stop(pObj->RTUSBCmdThr_task);
-		pObj->RTUSBCmdThr_task = NULL;
+		ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
+		if (ret)
+		{
+			printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
+					pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret);
+		}
+		else
+		{
+			//wait_for_completion (&pAd->notify);
+			wait_for_completion (&pAd->CmdQComplete);
+			pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+	}
 	}
 
 
@@ -1044,7 +1067,7 @@ BOOLEAN RT28XXChipsetCheck(
 		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
 			dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
 		{
-			printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+			printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
 					dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
 			break;
 		}
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/2870_rtmp_init.c linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/2870_rtmp_init.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/2870_rtmp_init.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/2870_rtmp_init.c	2009-12-04 01:00:07.000000000 -0500
@@ -727,8 +727,8 @@ NDIS_STATUS AdapterBlockAllocateMemory(
 
 	usb_dev = pObj->pUsb_Dev;
 
-	pObj->MLMEThr_task		= NULL;
-	pObj->RTUSBCmdThr_task	= NULL;
+	pObj->MLMEThr_pid		= THREAD_PID_INIT_VALUE;
+	pObj->RTUSBCmdThr_pid	= THREAD_PID_INIT_VALUE;
 
 	*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
 
@@ -765,7 +765,7 @@ NDIS_STATUS	 CreateThreads(
 {
 	PRTMP_ADAPTER pAd = net_dev->ml_priv;
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
-	struct task_struct *tsk;
+	pid_t pid_number = -1;
 
 	//init_MUTEX(&(pAd->usbdev_semaphore));
 
@@ -779,39 +779,36 @@ NDIS_STATUS	 CreateThreads(
 	init_completion (&pAd->TimerQComplete);
 
 	// Creat MLME Thread
-	pObj->MLMEThr_task = NULL;
-	tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name);
-
-	if (IS_ERR(tsk)) {
+	pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
+	pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
+	if (pid_number < 0)
+	{
 		printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-
-	pObj->MLMEThr_task = tsk;
+	pObj->MLMEThr_pid = GET_PID(pid_number);
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->mlmeComplete));
 
 	// Creat Command Thread
-	pObj->RTUSBCmdThr_task = NULL;
-	tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name);
-
-	if (IS_ERR(tsk) < 0)
+	pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
+	pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
+	if (pid_number < 0)
 	{
 		printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-
-	pObj->RTUSBCmdThr_task = tsk;
+	pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
 	wait_for_completion(&(pAd->CmdQComplete));
 
-	pObj->TimerQThr_task = NULL;
-	tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name);
-	if (IS_ERR(tsk) < 0)
+	pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
+	pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
+	if (pid_number < 0)
 	{
 		printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
 		return NDIS_STATUS_FAILURE;
 	}
-	pObj->TimerQThr_task = tsk;
+	pObj->TimerQThr_pid = GET_PID(pid_number);
 	// Wait for the thread to start
 	wait_for_completion(&(pAd->TimerQComplete));
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/cmm_data.c linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/cmm_data.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/cmm_data.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/cmm_data.c	2009-12-04 01:00:07.000000000 -0500
@@ -709,6 +709,9 @@ BOOLEAN RTMP_FillTxBlkInfo(
 	}
 
 	return TRUE;
+
+FillTxBlkErr:
+	return FALSE;
 }
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/rtmp_init.c linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/rtmp_init.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/rtmp_init.c	2013-05-03 16:50:09.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/rtmp_init.c	2013-05-03 17:28:58.000000000 -0400
@@ -3659,7 +3659,7 @@ VOID	UserCfgInit(
 #ifdef RALINK_28xx_QA
 	//pAd->ate.Repeat = 0;
 	pAd->ate.TxStatus = 0;
-	pAd->ate.AtePid = NULL;
+	pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
 #endif // RALINK_28xx_QA //
 #endif // RALINK_ATE //
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/rtusb_io.c linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/rtusb_io.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/common/rtusb_io.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/common/rtusb_io.c	2009-12-04 01:00:07.000000000 -0500
@@ -958,8 +958,7 @@ NDIS_STATUS	RTUSBEnqueueCmdFromNdis(
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
 
 
-	BUG_ON(pObj->RTUSBCmdThr_task == NULL);
-	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
+	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
 		return (NDIS_STATUS_RESOURCES);
 
 	status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/rt2870.h linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/rt2870.h
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/rt2870.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/rt2870.h	2009-12-04 01:00:07.000000000 -0500
@@ -97,6 +97,7 @@
 	{USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */		\
 	{USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */		\
 	{USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom */		\
+	{USB_DEVICE(0x0DF6,0x003F)}, /* Sitecom WL-608 */	\
 	{USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */		\
 	{USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */		\
 	{USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */		\
@@ -579,16 +580,14 @@ VOID RTUSBBulkRxComplete(purbb_t pUrb, s
 #define RTUSBMlmeUp(pAd)	        \
 {								    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	BUG_ON(pObj->MLMEThr_task == NULL);		    \
-	CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))		    \
+	CHECK_PID_LEGALITY(pObj->MLMEThr_pid)		    \
         up(&(pAd->mlme_semaphore)); \
 }
 
 #define RTUSBCMDUp(pAd)	                \
 {									    \
 	POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;	\
-	BUG_ON(pObj->RTUSBCmdThr_task == NULL);	    \
-	CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))	    \
+	CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)	    \
 	    up(&(pAd->RTUSBCmd_semaphore)); \
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rt2870/rt_linux.h linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/rt_linux.h
--- linux-libre-2.6.30-gnu1/drivers/staging/rt2870/rt_linux.h	2013-05-03 16:50:00.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rt2870/rt_linux.h	2013-05-03 17:28:49.000000000 -0400
@@ -44,7 +44,6 @@
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
-#include <linux/kthread.h>
 
 #include <linux/spinlock.h>
 #include <linux/init.h>
@@ -166,12 +165,14 @@ typedef int (*HARD_START_XMIT_FUNC)(stru
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 typedef	struct pid *	THREAD_PID;
+#define	THREAD_PID_INIT_VALUE	NULL
 #define	GET_PID(_v)	find_get_pid(_v)
 #define	GET_PID_NUMBER(_v)	pid_nr(_v)
 #define CHECK_PID_LEGALITY(_pid)	if (pid_nr(_pid) >= 0)
 #define KILL_THREAD_PID(_A, _B, _C)	kill_pid(_A, _B, _C)
 #else
 typedef	pid_t	THREAD_PID;
+#define	THREAD_PID_INIT_VALUE	-1
 #define	GET_PID(_v)	_v
 #define	GET_PID_NUMBER(_v)	_v
 #define CHECK_PID_LEGALITY(_pid)	if (_pid >= 0)
@@ -187,11 +188,11 @@ struct os_lock  {
 struct os_cookie {
 
 #ifdef RT2870
-	struct usb_device	*pUsb_Dev;
+	struct usb_device		*pUsb_Dev;
 
-	struct task_struct	*MLMEThr_task;
-	struct task_struct	*RTUSBCmdThr_task;
-	struct task_struct	*TimerQThr_task;
+	THREAD_PID				MLMEThr_pid;
+	THREAD_PID				RTUSBCmdThr_pid;
+	THREAD_PID				TimerQThr_pid;
 #endif // RT2870 //
 
 	struct tasklet_struct 	rx_done_task;
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c linux-libre-2.6.30.10-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
--- linux-libre-2.6.30-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c	2009-12-04 01:00:07.000000000 -0500
@@ -461,19 +461,19 @@ int ieee80211_wx_get_name(struct ieee802
 			     struct iw_request_info *info,
 			     union iwreq_data *wrqu, char *extra)
 {
-	strcpy(wrqu->name, "802.11");
+	strlcpy(wrqu->name, "802.11", IFNAMSIZ);
 	if(ieee->modulation & IEEE80211_CCK_MODULATION){
-		strcat(wrqu->name, "b");
+		strlcat(wrqu->name, "b", IFNAMSIZ);
 		if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-			strcat(wrqu->name, "/g");
+			strlcat(wrqu->name, "/g", IFNAMSIZ);
 	}else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
-		strcat(wrqu->name, "g");
+		strlcat(wrqu->name, "g", IFNAMSIZ);
 
 	if((ieee->state == IEEE80211_LINKED) ||
 		(ieee->state == IEEE80211_LINKED_SCANNING))
-		strcat(wrqu->name," linked");
+		strlcat(wrqu->name,"  link", IFNAMSIZ);
 	else if(ieee->state != IEEE80211_NOLINK)
-		strcat(wrqu->name," link..");
+		strlcat(wrqu->name," .....", IFNAMSIZ);
 
 
 	return 0;
diff -druNp linux-libre-2.6.30-gnu1/drivers/staging/uc2322/aten2011.c linux-libre-2.6.30.10-gnu1/drivers/staging/uc2322/aten2011.c
--- linux-libre-2.6.30-gnu1/drivers/staging/uc2322/aten2011.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/staging/uc2322/aten2011.c	2009-12-04 01:00:07.000000000 -0500
@@ -2336,7 +2336,7 @@ static int ATEN2011_startup(struct usb_s
 	return 0;
 }
 
-static void ATEN2011_shutdown(struct usb_serial *serial)
+static void ATEN2011_release(struct usb_serial *serial)
 {
 	int i;
 	struct ATENINTL_port *ATEN2011_port;
@@ -2382,7 +2382,7 @@ static struct usb_serial_driver aten_ser
 	.tiocmget =		ATEN2011_tiocmget,
 	.tiocmset =		ATEN2011_tiocmset,
 	.attach =		ATEN2011_startup,
-	.shutdown =		ATEN2011_shutdown,
+	.release =		ATEN2011_release,
 	.read_bulk_callback =	ATEN2011_bulk_in_callback,
 	.read_int_callback =	ATEN2011_interrupt_callback,
 };
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/class/usbtmc.c linux-libre-2.6.30.10-gnu1/drivers/usb/class/usbtmc.c
--- linux-libre-2.6.30-gnu1/drivers/usb/class/usbtmc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/class/usbtmc.c	2009-12-04 01:00:07.000000000 -0500
@@ -927,21 +927,27 @@ static long usbtmc_ioctl(struct file *fi
 	switch (cmd) {
 	case USBTMC_IOCTL_CLEAR_OUT_HALT:
 		retval = usbtmc_ioctl_clear_out_halt(data);
+		break;
 
 	case USBTMC_IOCTL_CLEAR_IN_HALT:
 		retval = usbtmc_ioctl_clear_in_halt(data);
+		break;
 
 	case USBTMC_IOCTL_INDICATOR_PULSE:
 		retval = usbtmc_ioctl_indicator_pulse(data);
+		break;
 
 	case USBTMC_IOCTL_CLEAR:
 		retval = usbtmc_ioctl_clear(data);
+		break;
 
 	case USBTMC_IOCTL_ABORT_BULK_OUT:
 		retval = usbtmc_ioctl_abort_bulk_out(data);
+		break;
 
 	case USBTMC_IOCTL_ABORT_BULK_IN:
 		retval = usbtmc_ioctl_abort_bulk_in(data);
+		break;
 	}
 
 	mutex_unlock(&data->io_mutex);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/core/devio.c linux-libre-2.6.30.10-gnu1/drivers/usb/core/devio.c
--- linux-libre-2.6.30-gnu1/drivers/usb/core/devio.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/core/devio.c	2009-12-04 01:00:07.000000000 -0500
@@ -582,7 +582,7 @@ static int usbdev_open(struct inode *ino
 	if (!ps)
 		goto out;
 
-	ret = -ENOENT;
+	ret = -ENODEV;
 
 	/* usbdev device-node */
 	if (imajor(inode) == USB_DEVICE_MAJOR)
@@ -982,7 +982,7 @@ static int proc_do_submiturb(struct dev_
 				USBDEVFS_URB_ZERO_PACKET |
 				USBDEVFS_URB_NO_INTERRUPT))
 		return -EINVAL;
-	if (!uurb->buffer)
+	if (uurb->buffer_length > 0 && !uurb->buffer)
 		return -EINVAL;
 	if (!(uurb->type == USBDEVFS_URB_TYPE_CONTROL &&
 	    (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) == 0)) {
@@ -1038,11 +1038,6 @@ static int proc_do_submiturb(struct dev_
 			is_in = 0;
 			uurb->endpoint &= ~USB_DIR_IN;
 		}
-		if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-				uurb->buffer, uurb->buffer_length)) {
-			kfree(dr);
-			return -EFAULT;
-		}
 		snoop(&ps->dev->dev, "control urb: bRequest=%02x "
 			"bRrequestType=%02x wValue=%04x "
 			"wIndex=%04x wLength=%04x\n",
@@ -1062,9 +1057,6 @@ static int proc_do_submiturb(struct dev_
 		uurb->number_of_packets = 0;
 		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
-		if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-				uurb->buffer, uurb->buffer_length))
-			return -EFAULT;
 		snoop(&ps->dev->dev, "bulk urb\n");
 		break;
 
@@ -1106,28 +1098,35 @@ static int proc_do_submiturb(struct dev_
 			return -EINVAL;
 		if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE)
 			return -EINVAL;
-		if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
-				uurb->buffer, uurb->buffer_length))
-			return -EFAULT;
 		snoop(&ps->dev->dev, "interrupt urb\n");
 		break;
 
 	default:
 		return -EINVAL;
 	}
-	as = alloc_async(uurb->number_of_packets);
-	if (!as) {
+	if (uurb->buffer_length > 0 &&
+			!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ,
+				uurb->buffer, uurb->buffer_length)) {
 		kfree(isopkt);
 		kfree(dr);
-		return -ENOMEM;
+		return -EFAULT;
 	}
-	as->urb->transfer_buffer = kmalloc(uurb->buffer_length, GFP_KERNEL);
-	if (!as->urb->transfer_buffer) {
+	as = alloc_async(uurb->number_of_packets);
+	if (!as) {
 		kfree(isopkt);
 		kfree(dr);
-		free_async(as);
 		return -ENOMEM;
 	}
+	if (uurb->buffer_length > 0) {
+		as->urb->transfer_buffer = kmalloc(uurb->buffer_length,
+				GFP_KERNEL);
+		if (!as->urb->transfer_buffer) {
+			kfree(isopkt);
+			kfree(dr);
+			free_async(as);
+			return -ENOMEM;
+		}
+	}
 	as->urb->dev = ps->dev;
 	as->urb->pipe = (uurb->type << 30) |
 			__create_pipe(ps->dev, uurb->endpoint & 0xf) |
@@ -1169,7 +1168,7 @@ static int proc_do_submiturb(struct dev_
 	kfree(isopkt);
 	as->ps = ps;
 	as->userurb = arg;
-	if (uurb->endpoint & USB_DIR_IN)
+	if (is_in && uurb->buffer_length > 0)
 		as->userbuffer = uurb->buffer;
 	else
 		as->userbuffer = NULL;
@@ -1179,9 +1178,9 @@ static int proc_do_submiturb(struct dev_
 	as->uid = cred->uid;
 	as->euid = cred->euid;
 	security_task_getsecid(current, &as->secid);
-	if (!is_in) {
+	if (!is_in && uurb->buffer_length > 0) {
 		if (copy_from_user(as->urb->transfer_buffer, uurb->buffer,
-				as->urb->transfer_buffer_length)) {
+				uurb->buffer_length)) {
 			free_async(as);
 			return -EFAULT;
 		}
@@ -1231,22 +1230,22 @@ static int processcompl(struct async *as
 	if (as->userbuffer)
 		if (copy_to_user(as->userbuffer, urb->transfer_buffer,
 				 urb->transfer_buffer_length))
-			return -EFAULT;
+			goto err_out;
 	if (put_user(as->status, &userurb->status))
-		return -EFAULT;
+		goto err_out;
 	if (put_user(urb->actual_length, &userurb->actual_length))
-		return -EFAULT;
+		goto err_out;
 	if (put_user(urb->error_count, &userurb->error_count))
-		return -EFAULT;
+		goto err_out;
 
 	if (usb_endpoint_xfer_isoc(&urb->ep->desc)) {
 		for (i = 0; i < urb->number_of_packets; i++) {
 			if (put_user(urb->iso_frame_desc[i].actual_length,
 				     &userurb->iso_frame_desc[i].actual_length))
-				return -EFAULT;
+				goto err_out;
 			if (put_user(urb->iso_frame_desc[i].status,
 				     &userurb->iso_frame_desc[i].status))
-				return -EFAULT;
+				goto err_out;
 		}
 	}
 
@@ -1255,6 +1254,10 @@ static int processcompl(struct async *as
 	if (put_user(addr, (void __user * __user *)arg))
 		return -EFAULT;
 	return 0;
+
+err_out:
+	free_async(as);
+	return -EFAULT;
 }
 
 static struct async *reap_as(struct dev_state *ps)
@@ -1305,7 +1308,8 @@ static int get_urb32(struct usbdevfs_urb
 		     struct usbdevfs_urb32 __user *uurb)
 {
 	__u32  uptr;
-	if (get_user(kurb->type, &uurb->type) ||
+	if (!access_ok(VERIFY_READ, uurb, sizeof(*uurb)) ||
+	    __get_user(kurb->type, &uurb->type) ||
 	    __get_user(kurb->endpoint, &uurb->endpoint) ||
 	    __get_user(kurb->status, &uurb->status) ||
 	    __get_user(kurb->flags, &uurb->flags) ||
@@ -1520,8 +1524,9 @@ static int proc_ioctl_compat(struct dev_
 	u32 udata;
 
 	uioc = compat_ptr((long)arg);
-	if (get_user(ctrl.ifno, &uioc->ifno) ||
-	    get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
+	if (!access_ok(VERIFY_READ, uioc, sizeof(*uioc)) ||
+	    __get_user(ctrl.ifno, &uioc->ifno) ||
+	    __get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
 	    __get_user(udata, &uioc->data))
 		return -EFAULT;
 	ctrl.data = compat_ptr(udata);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/core/hcd.h linux-libre-2.6.30.10-gnu1/drivers/usb/core/hcd.h
--- linux-libre-2.6.30-gnu1/drivers/usb/core/hcd.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/core/hcd.h	2009-12-04 01:00:07.000000000 -0500
@@ -224,6 +224,10 @@ struct hc_driver {
 	void	(*relinquish_port)(struct usb_hcd *, int);
 		/* has a port been handed over to a companion? */
 	int	(*port_handed_over)(struct usb_hcd *, int);
+
+		/* CLEAR_TT_BUFFER completion callback */
+	void	(*clear_tt_buffer_complete)(struct usb_hcd *,
+				struct usb_host_endpoint *);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/core/hub.c linux-libre-2.6.30.10-gnu1/drivers/usb/core/hub.c
--- linux-libre-2.6.30-gnu1/drivers/usb/core/hub.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/core/hub.c	2009-12-04 01:00:07.000000000 -0500
@@ -448,10 +448,10 @@ hub_clear_tt_buffer (struct usb_device *
  * talking to TTs must queue control transfers (not just bulk and iso), so
  * both can talk to the same hub concurrently.
  */
-static void hub_tt_kevent (struct work_struct *work)
+static void hub_tt_work(struct work_struct *work)
 {
 	struct usb_hub		*hub =
-		container_of(work, struct usb_hub, tt.kevent);
+		container_of(work, struct usb_hub, tt.clear_work);
 	unsigned long		flags;
 	int			limit = 100;
 
@@ -460,6 +460,7 @@ static void hub_tt_kevent (struct work_s
 		struct list_head	*temp;
 		struct usb_tt_clear	*clear;
 		struct usb_device	*hdev = hub->hdev;
+		const struct hc_driver	*drv;
 		int			status;
 
 		temp = hub->tt.clear_list.next;
@@ -469,21 +470,25 @@ static void hub_tt_kevent (struct work_s
 		/* drop lock so HCD can concurrently report other TT errors */
 		spin_unlock_irqrestore (&hub->tt.lock, flags);
 		status = hub_clear_tt_buffer (hdev, clear->devinfo, clear->tt);
-		spin_lock_irqsave (&hub->tt.lock, flags);
-
 		if (status)
 			dev_err (&hdev->dev,
 				"clear tt %d (%04x) error %d\n",
 				clear->tt, clear->devinfo, status);
+
+		/* Tell the HCD, even if the operation failed */
+		drv = clear->hcd->driver;
+		if (drv->clear_tt_buffer_complete)
+			(drv->clear_tt_buffer_complete)(clear->hcd, clear->ep);
+
 		kfree(clear);
+		spin_lock_irqsave(&hub->tt.lock, flags);
 	}
 	spin_unlock_irqrestore (&hub->tt.lock, flags);
 }
 
 /**
- * usb_hub_tt_clear_buffer - clear control/bulk TT state in high speed hub
- * @udev: the device whose split transaction failed
- * @pipe: identifies the endpoint of the failed transaction
+ * usb_hub_clear_tt_buffer - clear control/bulk TT state in high speed hub
+ * @urb: an URB associated with the failed or incomplete split transaction
  *
  * High speed HCDs use this to tell the hub driver that some split control or
  * bulk transaction failed in a way that requires clearing internal state of
@@ -493,8 +498,10 @@ static void hub_tt_kevent (struct work_s
  * It may not be possible for that hub to handle additional full (or low)
  * speed transactions until that state is fully cleared out.
  */
-void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
+int usb_hub_clear_tt_buffer(struct urb *urb)
 {
+	struct usb_device	*udev = urb->dev;
+	int			pipe = urb->pipe;
 	struct usb_tt		*tt = udev->tt;
 	unsigned long		flags;
 	struct usb_tt_clear	*clear;
@@ -506,7 +513,7 @@ void usb_hub_tt_clear_buffer (struct usb
 	if ((clear = kmalloc (sizeof *clear, GFP_ATOMIC)) == NULL) {
 		dev_err (&udev->dev, "can't save CLEAR_TT_BUFFER state\n");
 		/* FIXME recover somehow ... RESET_TT? */
-		return;
+		return -ENOMEM;
 	}
 
 	/* info that CLEAR_TT_BUFFER needs */
@@ -518,14 +525,19 @@ void usb_hub_tt_clear_buffer (struct usb
 			: (USB_ENDPOINT_XFER_BULK << 11);
 	if (usb_pipein (pipe))
 		clear->devinfo |= 1 << 15;
-	
+
+	/* info for completion callback */
+	clear->hcd = bus_to_hcd(udev->bus);
+	clear->ep = urb->ep;
+
 	/* tell keventd to clear state for this TT */
 	spin_lock_irqsave (&tt->lock, flags);
 	list_add_tail (&clear->clear_list, &tt->clear_list);
-	schedule_work (&tt->kevent);
+	schedule_work(&tt->clear_work);
 	spin_unlock_irqrestore (&tt->lock, flags);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
+EXPORT_SYMBOL_GPL(usb_hub_clear_tt_buffer);
 
 /* If do_delay is false, return the number of milliseconds the caller
  * needs to delay.
@@ -816,7 +828,7 @@ static void hub_quiesce(struct usb_hub *
 	if (hub->has_indicators)
 		cancel_delayed_work_sync(&hub->leds);
 	if (hub->tt.hub)
-		cancel_work_sync(&hub->tt.kevent);
+		cancel_work_sync(&hub->tt.clear_work);
 }
 
 /* caller has locked the hub device */
@@ -933,7 +945,7 @@ static int hub_configure(struct usb_hub
 
 	spin_lock_init (&hub->tt.lock);
 	INIT_LIST_HEAD (&hub->tt.clear_list);
-	INIT_WORK (&hub->tt.kevent, hub_tt_kevent);
+	INIT_WORK(&hub->tt.clear_work, hub_tt_work);
 	switch (hdev->descriptor.bDeviceProtocol) {
 		case 0:
 			break;
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/core/hub.h linux-libre-2.6.30.10-gnu1/drivers/usb/core/hub.h
--- linux-libre-2.6.30-gnu1/drivers/usb/core/hub.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/core/hub.h	2009-12-04 01:00:07.000000000 -0500
@@ -185,16 +185,18 @@ struct usb_tt {
 	/* for control/bulk error recovery (CLEAR_TT_BUFFER) */
 	spinlock_t		lock;
 	struct list_head	clear_list;	/* of usb_tt_clear */
-	struct work_struct			kevent;
+	struct work_struct	clear_work;
 };
 
 struct usb_tt_clear {
 	struct list_head	clear_list;
 	unsigned		tt;
 	u16			devinfo;
+	struct usb_hcd		*hcd;
+	struct usb_host_endpoint	*ep;
 };
 
-extern void usb_hub_tt_clear_buffer(struct usb_device *dev, int pipe);
+extern int usb_hub_clear_tt_buffer(struct urb *urb);
 extern void usb_ep0_reinit(struct usb_device *);
 
 #endif /* __LINUX_HUB_H */
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/core/message.c linux-libre-2.6.30.10-gnu1/drivers/usb/core/message.c
--- linux-libre-2.6.30-gnu1/drivers/usb/core/message.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/core/message.c	2009-12-04 01:00:07.000000000 -0500
@@ -758,6 +758,48 @@ static int usb_string_sub(struct usb_dev
 	return rc;
 }
 
+static int usb_get_langid(struct usb_device *dev, unsigned char *tbuf)
+{
+	int err;
+
+	if (dev->have_langid)
+		return 0;
+
+	if (dev->string_langid < 0)
+		return -EPIPE;
+
+	err = usb_string_sub(dev, 0, 0, tbuf);
+
+	/* If the string was reported but is malformed, default to english
+	 * (0x0409) */
+	if (err == -ENODATA || (err > 0 && err < 4)) {
+		dev->string_langid = 0x0409;
+		dev->have_langid = 1;
+		dev_err(&dev->dev,
+			"string descriptor 0 malformed (err = %d), "
+			"defaulting to 0x%04x\n",
+				err, dev->string_langid);
+		return 0;
+	}
+
+	/* In case of all other errors, we assume the device is not able to
+	 * deal with strings at all. Set string_langid to -1 in order to
+	 * prevent any string to be retrieved from the device */
+	if (err < 0) {
+		dev_err(&dev->dev, "string descriptor 0 read error: %d\n",
+					err);
+		dev->string_langid = -1;
+		return -EPIPE;
+	}
+
+	/* always use the first langid listed */
+	dev->string_langid = tbuf[2] | (tbuf[3] << 8);
+	dev->have_langid = 1;
+	dev_dbg(&dev->dev, "default language 0x%04x\n",
+				dev->string_langid);
+	return 0;
+}
+
 /**
  * usb_string - returns ISO 8859-1 version of a string descriptor
  * @dev: the device whose string descriptor is being retrieved
@@ -797,24 +839,9 @@ int usb_string(struct usb_device *dev, i
 	if (!tbuf)
 		return -ENOMEM;
 
-	/* get langid for strings if it's not yet known */
-	if (!dev->have_langid) {
-		err = usb_string_sub(dev, 0, 0, tbuf);
-		if (err < 0) {
-			dev_err(&dev->dev,
-				"string descriptor 0 read error: %d\n",
-				err);
-		} else if (err < 4) {
-			dev_err(&dev->dev, "string descriptor 0 too short\n");
-		} else {
-			dev->string_langid = tbuf[2] | (tbuf[3] << 8);
-			/* always use the first langid listed */
-			dev_dbg(&dev->dev, "default language 0x%04x\n",
-				dev->string_langid);
-		}
-
-		dev->have_langid = 1;
-	}
+	err = usb_get_langid(dev, tbuf);
+	if (err < 0)
+		goto errout;
 
 	err = usb_string_sub(dev, dev->string_langid, index, tbuf);
 	if (err < 0)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/gadget/ether.c linux-libre-2.6.30.10-gnu1/drivers/usb/gadget/ether.c
--- linux-libre-2.6.30-gnu1/drivers/usb/gadget/ether.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/gadget/ether.c	2009-12-04 01:00:07.000000000 -0500
@@ -293,15 +293,16 @@ static int __init eth_bind(struct usb_co
 		/* CDC Subset */
 		eth_config_driver.label = "CDC Subset/SAFE";
 
-		device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM),
-		device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM),
-		device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
+		device_desc.idVendor = cpu_to_le16(SIMPLE_VENDOR_NUM);
+		device_desc.idProduct = cpu_to_le16(SIMPLE_PRODUCT_NUM);
+		if (!has_rndis())
+			device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC;
 	}
 
 	if (has_rndis()) {
 		/* RNDIS plus ECM-or-Subset */
-		device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM),
-		device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM),
+		device_desc.idVendor = cpu_to_le16(RNDIS_VENDOR_NUM);
+		device_desc.idProduct = cpu_to_le16(RNDIS_PRODUCT_NUM);
 		device_desc.bNumConfigurations = 2;
 	}
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-au1xxx.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-au1xxx.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-au1xxx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-au1xxx.c	2009-12-04 01:00:07.000000000 -0500
@@ -112,6 +112,8 @@ static const struct hc_driver ehci_au1xx
 	.bus_resume		= ehci_bus_resume,
 	.relinquish_port	= ehci_relinquish_port,
 	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-fsl.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-fsl.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-fsl.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-fsl.c	2009-12-04 01:00:07.000000000 -0500
@@ -324,6 +324,8 @@ static const struct hc_driver ehci_fsl_h
 	.bus_resume = ehci_bus_resume,
 	.relinquish_port = ehci_relinquish_port,
 	.port_handed_over = ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static int ehci_fsl_drv_probe(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci.h linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci.h
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci.h	2009-12-04 01:00:07.000000000 -0500
@@ -353,7 +353,9 @@ struct ehci_qh {
 	unsigned short		period;		/* polling interval */
 	unsigned short		start;		/* where polling starts */
 #define NO_FRAME ((unsigned short)~0)			/* pick new start */
+
 	struct usb_device	*dev;		/* access to TT */
+	unsigned		clearing_tt:1;	/* Clear-TT-Buf in progress */
 } __attribute__ ((aligned (32)));
 
 /*-------------------------------------------------------------------------*/
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-hcd.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-hcd.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-hcd.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-hcd.c	2009-12-04 01:00:07.000000000 -0500
@@ -903,7 +903,8 @@ static int ehci_urb_dequeue(struct usb_h
 			/* already started */
 			break;
 		case QH_STATE_IDLE:
-			WARN_ON(1);
+			/* QH might be waiting for a Clear-TT-Buffer */
+			qh_completions(ehci, qh);
 			break;
 		}
 		break;
@@ -1003,6 +1004,8 @@ idle_timeout:
 		schedule_timeout_uninterruptible(1);
 		goto rescan;
 	case QH_STATE_IDLE:		/* fully unlinked */
+		if (qh->clearing_tt)
+			goto idle_timeout;
 		if (list_empty (&qh->qtd_list)) {
 			qh_put (qh);
 			break;
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ixp4xx.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ixp4xx.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ixp4xx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ixp4xx.c	2009-12-04 01:00:07.000000000 -0500
@@ -60,6 +60,8 @@ static const struct hc_driver ixp4xx_ehc
 #endif
 	.relinquish_port	= ehci_relinquish_port,
 	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
 static int ixp4xx_ehci_probe(struct platform_device *pdev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-orion.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-orion.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-orion.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-orion.c	2009-12-04 01:00:07.000000000 -0500
@@ -164,6 +164,8 @@ static const struct hc_driver ehci_orion
 	.bus_resume = ehci_bus_resume,
 	.relinquish_port = ehci_relinquish_port,
 	.port_handed_over = ehci_port_handed_over,
+
+	.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
 };
 
 static void __init
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-pci.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-pci.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-pci.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-pci.c	2009-12-04 01:00:07.000000000 -0500
@@ -408,6 +408,8 @@ static const struct hc_driver ehci_pci_h
 	.bus_resume =		ehci_bus_resume,
 	.relinquish_port =	ehci_relinquish_port,
 	.port_handed_over =	ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
 /*-------------------------------------------------------------------------*/
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ppc-of.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ppc-of.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ppc-of.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ppc-of.c	2009-12-04 01:00:07.000000000 -0500
@@ -78,6 +78,8 @@ static const struct hc_driver ehci_ppc_o
 #endif
 	.relinquish_port	= ehci_relinquish_port,
 	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ps3.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ps3.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-ps3.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-ps3.c	2009-12-04 01:00:07.000000000 -0500
@@ -74,6 +74,8 @@ static const struct hc_driver ps3_ehci_h
 #endif
 	.relinquish_port	= ehci_relinquish_port,
 	.port_handed_over	= ehci_port_handed_over,
+
+	.clear_tt_buffer_complete	= ehci_clear_tt_buffer_complete,
 };
 
 static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-q.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-q.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-q.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-q.c	2009-12-04 01:00:07.000000000 -0500
@@ -139,6 +139,55 @@ qh_refresh (struct ehci_hcd *ehci, struc
 
 /*-------------------------------------------------------------------------*/
 
+static void qh_link_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
+
+static void ehci_clear_tt_buffer_complete(struct usb_hcd *hcd,
+		struct usb_host_endpoint *ep)
+{
+	struct ehci_hcd		*ehci = hcd_to_ehci(hcd);
+	struct ehci_qh		*qh = ep->hcpriv;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&ehci->lock, flags);
+	qh->clearing_tt = 0;
+	if (qh->qh_state == QH_STATE_IDLE && !list_empty(&qh->qtd_list)
+			&& HC_IS_RUNNING(hcd->state))
+		qh_link_async(ehci, qh);
+	spin_unlock_irqrestore(&ehci->lock, flags);
+}
+
+static void ehci_clear_tt_buffer(struct ehci_hcd *ehci, struct ehci_qh *qh,
+		struct urb *urb, u32 token)
+{
+
+	/* If an async split transaction gets an error or is unlinked,
+	 * the TT buffer may be left in an indeterminate state.  We
+	 * have to clear the TT buffer.
+	 *
+	 * Note: this routine is never called for Isochronous transfers.
+	 */
+	if (urb->dev->tt && !usb_pipeint(urb->pipe) && !qh->clearing_tt) {
+#ifdef DEBUG
+		struct usb_device *tt = urb->dev->tt->hub;
+		dev_dbg(&tt->dev,
+			"clear tt buffer port %d, a%d ep%d t%08x\n",
+			urb->dev->ttport, urb->dev->devnum,
+			usb_pipeendpoint(urb->pipe), token);
+#endif /* DEBUG */
+		if (!ehci_is_TDI(ehci)
+				|| urb->dev->tt->hub !=
+				   ehci_to_hcd(ehci)->self.root_hub) {
+			if (usb_hub_clear_tt_buffer(urb) == 0)
+				qh->clearing_tt = 1;
+		} else {
+
+			/* REVISIT ARC-derived cores don't clear the root
+			 * hub TT buffer in this way...
+			 */
+		}
+	}
+}
+
 static int qtd_copy_status (
 	struct ehci_hcd *ehci,
 	struct urb *urb,
@@ -195,28 +244,6 @@ static int qtd_copy_status (
 			usb_pipeendpoint (urb->pipe),
 			usb_pipein (urb->pipe) ? "in" : "out",
 			token, status);
-
-		/* if async CSPLIT failed, try cleaning out the TT buffer */
-		if (status != -EPIPE
-				&& urb->dev->tt
-				&& !usb_pipeint(urb->pipe)
-				&& ((token & QTD_STS_MMF) != 0
-					|| QTD_CERR(token) == 0)
-				&& (!ehci_is_TDI(ehci)
-			                || urb->dev->tt->hub !=
-					   ehci_to_hcd(ehci)->self.root_hub)) {
-#ifdef DEBUG
-			struct usb_device *tt = urb->dev->tt->hub;
-			dev_dbg (&tt->dev,
-				"clear tt buffer port %d, a%d ep%d t%08x\n",
-				urb->dev->ttport, urb->dev->devnum,
-				usb_pipeendpoint (urb->pipe), token);
-#endif /* DEBUG */
-			/* REVISIT ARC-derived cores don't clear the root
-			 * hub TT buffer in this way...
-			 */
-			usb_hub_tt_clear_buffer (urb->dev, urb->pipe);
-		}
 	}
 
 	return status;
@@ -407,9 +434,16 @@ qh_completions (struct ehci_hcd *ehci, s
 			/* qh unlinked; token in overlay may be most current */
 			if (state == QH_STATE_IDLE
 					&& cpu_to_hc32(ehci, qtd->qtd_dma)
-						== qh->hw_current)
+						== qh->hw_current) {
 				token = hc32_to_cpu(ehci, qh->hw_token);
 
+				/* An unlink may leave an incomplete
+				 * async transaction in the TT buffer.
+				 * We have to clear it.
+				 */
+				ehci_clear_tt_buffer(ehci, qh, urb, token);
+			}
+
 			/* force halt for unlinked or blocked qh, so we'll
 			 * patch the qh later and so that completions can't
 			 * activate it while we "know" it's stopped.
@@ -435,6 +469,13 @@ halt:
 					&& (qtd->hw_alt_next
 						& EHCI_LIST_END(ehci)))
 				last_status = -EINPROGRESS;
+
+			/* As part of low/full-speed endpoint-halt processing
+			 * we must clear the TT buffer (11.17.5).
+			 */
+			if (unlikely(last_status != -EINPROGRESS &&
+					last_status != -EREMOTEIO))
+				ehci_clear_tt_buffer(ehci, qh, urb, token);
 		}
 
 		/* if we're removing something not at the queue head,
@@ -864,6 +905,10 @@ static void qh_link_async (struct ehci_h
 	__hc32		dma = QH_NEXT(ehci, qh->qh_dma);
 	struct ehci_qh	*head;
 
+	/* Don't link a QH if there's a Clear-TT-Buffer pending */
+	if (unlikely(qh->clearing_tt))
+		return;
+
 	/* (re)start the async schedule? */
 	head = ehci->async;
 	timer_action_done (ehci, TIMER_ASYNC_OFF);
@@ -893,6 +938,7 @@ static void qh_link_async (struct ehci_h
 	head->qh_next.qh = qh;
 	head->hw_next = dma;
 
+	qh_get(qh);
 	qh->xacterrs = QH_XACTERR_MAX;
 	qh->qh_state = QH_STATE_LINKED;
 	/* qtd completions reported later by interrupt */
@@ -1033,7 +1079,7 @@ submit_async (
 	 * the HC and TT handle it when the TT has a buffer ready.
 	 */
 	if (likely (qh->qh_state == QH_STATE_IDLE))
-		qh_link_async (ehci, qh_get (qh));
+		qh_link_async(ehci, qh);
  done:
 	spin_unlock_irqrestore (&ehci->lock, flags);
 	if (unlikely (qh == NULL))
@@ -1068,8 +1114,6 @@ static void end_unlink_async (struct ehc
 			&& HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
 		qh_link_async (ehci, qh);
 	else {
-		qh_put (qh);		// refcount from async list
-
 		/* it's not free to turn the async schedule on/off; leave it
 		 * active but idle for a while once it empties.
 		 */
@@ -1077,6 +1121,7 @@ static void end_unlink_async (struct ehc
 				&& ehci->async->qh_next.qh == NULL)
 			timer_action (ehci, TIMER_ASYNC_OFF);
 	}
+	qh_put(qh);			/* refcount from async list */
 
 	if (next) {
 		ehci->reclaim = NULL;
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-sched.c linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-sched.c
--- linux-libre-2.6.30-gnu1/drivers/usb/host/ehci-sched.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/host/ehci-sched.c	2009-12-04 01:00:07.000000000 -0500
@@ -1617,11 +1617,14 @@ itd_complete (
 				desc->status = -EPROTO;
 
 			/* HC need not update length with this error */
-			if (!(t & EHCI_ISOC_BABBLE))
-				desc->actual_length = EHCI_ITD_LENGTH (t);
+			if (!(t & EHCI_ISOC_BABBLE)) {
+				desc->actual_length = EHCI_ITD_LENGTH(t);
+				urb->actual_length += desc->actual_length;
+			}
 		} else if (likely ((t & EHCI_ISOC_ACTIVE) == 0)) {
 			desc->status = 0;
-			desc->actual_length = EHCI_ITD_LENGTH (t);
+			desc->actual_length = EHCI_ITD_LENGTH(t);
+			urb->actual_length += desc->actual_length;
 		} else {
 			/* URB was too late */
 			desc->status = -EXDEV;
@@ -2012,7 +2015,8 @@ sitd_complete (
 			desc->status = -EPROTO;
 	} else {
 		desc->status = 0;
-		desc->actual_length = desc->length - SITD_LENGTH (t);
+		desc->actual_length = desc->length - SITD_LENGTH(t);
+		urb->actual_length += desc->actual_length;
 	}
 	stream->depth -= stream->interval << 3;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/aircable.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/aircable.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/aircable.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/aircable.c	2009-12-04 01:00:07.000000000 -0500
@@ -364,7 +364,7 @@ static int aircable_attach(struct usb_se
 	return 0;
 }
 
-static void aircable_shutdown(struct usb_serial *serial)
+static void aircable_release(struct usb_serial *serial)
 {
 
 	struct usb_serial_port *port = serial->port[0];
@@ -375,7 +375,6 @@ static void aircable_shutdown(struct usb
 	if (priv) {
 		serial_buf_free(priv->tx_buf);
 		serial_buf_free(priv->rx_buf);
-		usb_set_serial_port_data(port, NULL);
 		kfree(priv);
 	}
 }
@@ -601,7 +600,7 @@ static struct usb_serial_driver aircable
 	.num_ports =		1,
 	.attach =		aircable_attach,
 	.probe =		aircable_probe,
-	.shutdown =		aircable_shutdown,
+	.release =		aircable_release,
 	.write =		aircable_write,
 	.write_room =		aircable_write_room,
 	.write_bulk_callback =	aircable_write_bulk_callback,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/belkin_sa.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/belkin_sa.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/belkin_sa.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/belkin_sa.c	2009-12-04 01:00:07.000000000 -0500
@@ -90,7 +90,7 @@ static int debug;
 
 /* function prototypes for a Belkin USB Serial Adapter F5U103 */
 static int  belkin_sa_startup(struct usb_serial *serial);
-static void belkin_sa_shutdown(struct usb_serial *serial);
+static void belkin_sa_release(struct usb_serial *serial);
 static int  belkin_sa_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void belkin_sa_close(struct tty_struct *tty,
@@ -143,7 +143,7 @@ static struct usb_serial_driver belkin_d
 	.tiocmget =		belkin_sa_tiocmget,
 	.tiocmset =		belkin_sa_tiocmset,
 	.attach =		belkin_sa_startup,
-	.shutdown =		belkin_sa_shutdown,
+	.release =		belkin_sa_release,
 };
 
 
@@ -198,14 +198,13 @@ static int belkin_sa_startup(struct usb_
 }
 
 
-static void belkin_sa_shutdown(struct usb_serial *serial)
+static void belkin_sa_release(struct usb_serial *serial)
 {
 	struct belkin_sa_private *priv;
 	int i;
 
 	dbg("%s", __func__);
 
-	/* stop reads and writes on all ports */
 	for (i = 0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		priv = usb_get_serial_port_data(serial->port[i]);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/cp210x.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cp210x.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/cp210x.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cp210x.c	2009-12-04 01:00:07.000000000 -0500
@@ -51,7 +51,7 @@ static int cp2101_tiocmset_port(struct u
 		unsigned int, unsigned int);
 static void cp2101_break_ctl(struct tty_struct *, int);
 static int cp2101_startup(struct usb_serial *);
-static void cp2101_shutdown(struct usb_serial *);
+static void cp2101_disconnect(struct usb_serial *);
 
 static int debug;
 
@@ -131,7 +131,7 @@ static struct usb_serial_driver cp2101_d
 	.tiocmget 		= cp2101_tiocmget,
 	.tiocmset		= cp2101_tiocmset,
 	.attach			= cp2101_startup,
-	.shutdown		= cp2101_shutdown,
+	.disconnect		= cp2101_disconnect,
 };
 
 /* Config request types */
@@ -773,7 +773,7 @@ static int cp2101_startup(struct usb_ser
 	return 0;
 }
 
-static void cp2101_shutdown(struct usb_serial *serial)
+static void cp2101_disconnect(struct usb_serial *serial)
 {
 	int i;
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/cyberjack.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cyberjack.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/cyberjack.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cyberjack.c	2009-12-04 01:00:07.000000000 -0500
@@ -58,7 +58,8 @@ static int debug;
 
 /* Function prototypes */
 static int cyberjack_startup(struct usb_serial *serial);
-static void cyberjack_shutdown(struct usb_serial *serial);
+static void cyberjack_disconnect(struct usb_serial *serial);
+static void cyberjack_release(struct usb_serial *serial);
 static int  cyberjack_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void cyberjack_close(struct tty_struct *tty,
@@ -95,7 +96,8 @@ static struct usb_serial_driver cyberjac
 	.id_table =		id_table,
 	.num_ports =		1,
 	.attach =		cyberjack_startup,
-	.shutdown =		cyberjack_shutdown,
+	.disconnect =		cyberjack_disconnect,
+	.release =		cyberjack_release,
 	.open =			cyberjack_open,
 	.close =		cyberjack_close,
 	.write =		cyberjack_write,
@@ -149,17 +151,25 @@ static int cyberjack_startup(struct usb_
 	return 0;
 }
 
-static void cyberjack_shutdown(struct usb_serial *serial)
+static void cyberjack_disconnect(struct usb_serial *serial)
 {
 	int i;
 
 	dbg("%s", __func__);
 
-	for (i = 0; i < serial->num_ports; ++i) {
+	for (i = 0; i < serial->num_ports; ++i)
 		usb_kill_urb(serial->port[i]->interrupt_in_urb);
+}
+
+static void cyberjack_release(struct usb_serial *serial)
+{
+	int i;
+
+	dbg("%s", __func__);
+
+	for (i = 0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i], NULL);
 	}
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/cypress_m8.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cypress_m8.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/cypress_m8.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/cypress_m8.c	2009-12-04 01:00:07.000000000 -0500
@@ -171,7 +171,7 @@ struct cypress_buf {
 static int  cypress_earthmate_startup(struct usb_serial *serial);
 static int  cypress_hidcom_startup(struct usb_serial *serial);
 static int  cypress_ca42v2_startup(struct usb_serial *serial);
-static void cypress_shutdown(struct usb_serial *serial);
+static void cypress_release(struct usb_serial *serial);
 static int  cypress_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void cypress_close(struct tty_struct *tty,
@@ -215,7 +215,7 @@ static struct usb_serial_driver cypress_
 	.id_table =			id_table_earthmate,
 	.num_ports =			1,
 	.attach =			cypress_earthmate_startup,
-	.shutdown =			cypress_shutdown,
+	.release =			cypress_release,
 	.open =				cypress_open,
 	.close =			cypress_close,
 	.write =			cypress_write,
@@ -241,7 +241,7 @@ static struct usb_serial_driver cypress_
 	.id_table =			id_table_cyphidcomrs232,
 	.num_ports =			1,
 	.attach =			cypress_hidcom_startup,
-	.shutdown =			cypress_shutdown,
+	.release =			cypress_release,
 	.open =				cypress_open,
 	.close =			cypress_close,
 	.write =			cypress_write,
@@ -267,7 +267,7 @@ static struct usb_serial_driver cypress_
 	.id_table =			id_table_nokiaca42v2,
 	.num_ports =			1,
 	.attach =			cypress_ca42v2_startup,
-	.shutdown =			cypress_shutdown,
+	.release =			cypress_release,
 	.open =				cypress_open,
 	.close =			cypress_close,
 	.write =			cypress_write,
@@ -613,7 +613,7 @@ static int cypress_ca42v2_startup(struct
 } /* cypress_ca42v2_startup */
 
 
-static void cypress_shutdown(struct usb_serial *serial)
+static void cypress_release(struct usb_serial *serial)
 {
 	struct cypress_private *priv;
 
@@ -626,7 +626,6 @@ static void cypress_shutdown(struct usb_
 	if (priv) {
 		cypress_buf_free(priv->buf);
 		kfree(priv);
-		usb_set_serial_port_data(serial->port[0], NULL);
 	}
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/digi_acceleport.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/digi_acceleport.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/digi_acceleport.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/digi_acceleport.c	2009-12-04 01:00:07.000000000 -0500
@@ -460,7 +460,8 @@ static void digi_close(struct tty_struct
 	struct file *filp);
 static int digi_startup_device(struct usb_serial *serial);
 static int digi_startup(struct usb_serial *serial);
-static void digi_shutdown(struct usb_serial *serial);
+static void digi_disconnect(struct usb_serial *serial);
+static void digi_release(struct usb_serial *serial);
 static void digi_read_bulk_callback(struct urb *urb);
 static int digi_read_inb_callback(struct urb *urb);
 static int digi_read_oob_callback(struct urb *urb);
@@ -522,7 +523,8 @@ static struct usb_serial_driver digi_acc
 	.tiocmget =			digi_tiocmget,
 	.tiocmset =			digi_tiocmset,
 	.attach =			digi_startup,
-	.shutdown =			digi_shutdown,
+	.disconnect =			digi_disconnect,
+	.release =			digi_release,
 };
 
 static struct usb_serial_driver digi_acceleport_4_device = {
@@ -548,7 +550,8 @@ static struct usb_serial_driver digi_acc
 	.tiocmget =			digi_tiocmget,
 	.tiocmset =			digi_tiocmset,
 	.attach =			digi_startup,
-	.shutdown =			digi_shutdown,
+	.disconnect =			digi_disconnect,
+	.release =			digi_release,
 };
 
 
@@ -1589,16 +1592,23 @@ static int digi_startup(struct usb_seria
 }
 
 
-static void digi_shutdown(struct usb_serial *serial)
+static void digi_disconnect(struct usb_serial *serial)
 {
 	int i;
-	dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt());
+	dbg("digi_disconnect: TOP, in_interrupt()=%ld", in_interrupt());
 
 	/* stop reads and writes on all ports */
 	for (i = 0; i < serial->type->num_ports + 1; i++) {
 		usb_kill_urb(serial->port[i]->read_urb);
 		usb_kill_urb(serial->port[i]->write_urb);
 	}
+}
+
+
+static void digi_release(struct usb_serial *serial)
+{
+	int i;
+	dbg("digi_release: TOP, in_interrupt()=%ld", in_interrupt());
 
 	/* free the private data structures for all ports */
 	/* number of regular ports + 1 for the out-of-band port */
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/empeg.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/empeg.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/empeg.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/empeg.c	2009-12-04 01:00:07.000000000 -0500
@@ -91,7 +91,6 @@ static int  empeg_chars_in_buffer(struct
 static void empeg_throttle(struct tty_struct *tty);
 static void empeg_unthrottle(struct tty_struct *tty);
 static int  empeg_startup(struct usb_serial *serial);
-static void empeg_shutdown(struct usb_serial *serial);
 static void empeg_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios);
 static void empeg_write_bulk_callback(struct urb *urb);
@@ -125,7 +124,6 @@ static struct usb_serial_driver empeg_de
 	.throttle =		empeg_throttle,
 	.unthrottle =		empeg_unthrottle,
 	.attach =		empeg_startup,
-	.shutdown =		empeg_shutdown,
 	.set_termios =		empeg_set_termios,
 	.write =		empeg_write,
 	.write_room =		empeg_write_room,
@@ -429,12 +427,6 @@ static int  empeg_startup(struct usb_ser
 }
 
 
-static void empeg_shutdown(struct usb_serial *serial)
-{
-	dbg("%s", __func__);
-}
-
-
 static void empeg_set_termios(struct tty_struct *tty,
 		struct usb_serial_port *port, struct ktermios *old_termios)
 {
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/ftdi_sio.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ftdi_sio.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/ftdi_sio.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ftdi_sio.c	2009-12-04 01:00:07.000000000 -0500
@@ -672,6 +672,9 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(JETI_VID, JETI_SPC1201_PID) },
 	{ USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) },
+	{ USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
 };
@@ -714,7 +717,6 @@ static const char *ftdi_chip_name[] = {
 /* function prototypes for a FTDI serial converter */
 static int  ftdi_sio_probe(struct usb_serial *serial,
 					const struct usb_device_id *id);
-static void ftdi_shutdown(struct usb_serial *serial);
 static int  ftdi_sio_port_probe(struct usb_serial_port *port);
 static int  ftdi_sio_port_remove(struct usb_serial_port *port);
 static int  ftdi_open(struct tty_struct *tty,
@@ -770,7 +772,6 @@ static struct usb_serial_driver ftdi_sio
 	.ioctl =		ftdi_ioctl,
 	.set_termios =		ftdi_set_termios,
 	.break_ctl =		ftdi_break_ctl,
-	.shutdown =		ftdi_shutdown,
 };
 
 
@@ -1460,18 +1461,6 @@ static int ftdi_mtxorb_hack_setup(struct
 	return 0;
 }
 
-/* ftdi_shutdown is called from usbserial:usb_serial_disconnect
- *   it is called when the usb device is disconnected
- *
- *   usbserial:usb_serial_disconnect
- *      calls __serial_close for each open of the port
- *      shutdown is called then (ie ftdi_shutdown)
- */
-static void ftdi_shutdown(struct usb_serial *serial)
-{
-	dbg("%s", __func__);
-}
-
 static void ftdi_sio_priv_release(struct kref *k)
 {
 	struct ftdi_private *priv = container_of(k, struct ftdi_private, kref);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/ftdi_sio.h linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ftdi_sio.h
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/ftdi_sio.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ftdi_sio.h	2009-12-04 01:00:07.000000000 -0500
@@ -926,6 +926,20 @@
 #define MARVELL_SHEEVAPLUG_PID	0x9e8f
 
 /*
+ * Bayer Ascensia Contour blood glucose meter USB-converter cable.
+ * http://winglucofacts.com/cables/
+ */
+#define BAYER_VID                      0x1A79
+#define BAYER_CONTOUR_CABLE_PID        0x6001
+
+/*
+ * Marvell OpenRD Base, Client
+ * http://www.open-rd.org
+ * OpenRD Base, Client use VID 0x0403
+ */
+#define MARVELL_OPENRD_PID	0x9e90
+
+/*
  *   BmRequestType:  1100 0000b
  *   bRequest:       FTDI_E2_READ
  *   wValue:         0
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/garmin_gps.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/garmin_gps.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/garmin_gps.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/garmin_gps.c	2009-12-04 01:00:07.000000000 -0500
@@ -1528,7 +1528,7 @@ static int garmin_attach(struct usb_seri
 }
 
 
-static void garmin_shutdown(struct usb_serial *serial)
+static void garmin_disconnect(struct usb_serial *serial)
 {
 	struct usb_serial_port *port = serial->port[0];
 	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
@@ -1537,8 +1537,17 @@ static void garmin_shutdown(struct usb_s
 
 	usb_kill_urb(port->interrupt_in_urb);
 	del_timer_sync(&garmin_data_p->timer);
+}
+
+
+static void garmin_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port = serial->port[0];
+	struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
+
+	dbg("%s", __func__);
+
 	kfree(garmin_data_p);
-	usb_set_serial_port_data(port, NULL);
 }
 
 
@@ -1557,7 +1566,8 @@ static struct usb_serial_driver garmin_d
 	.throttle            = garmin_throttle,
 	.unthrottle          = garmin_unthrottle,
 	.attach              = garmin_attach,
-	.shutdown            = garmin_shutdown,
+	.disconnect          = garmin_disconnect,
+	.release             = garmin_release,
 	.write               = garmin_write,
 	.write_room          = garmin_write_room,
 	.write_bulk_callback = garmin_write_bulk_callback,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/generic.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/generic.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/generic.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/generic.c	2009-12-04 01:00:07.000000000 -0500
@@ -63,7 +63,8 @@ struct usb_serial_driver usb_serial_gene
 	.id_table =		generic_device_ids,
 	.usb_driver = 		&generic_driver,
 	.num_ports =		1,
-	.shutdown =		usb_serial_generic_shutdown,
+	.disconnect =		usb_serial_generic_disconnect,
+	.release =		usb_serial_generic_release,
 	.throttle =		usb_serial_generic_throttle,
 	.unthrottle =		usb_serial_generic_unthrottle,
 	.resume =		usb_serial_generic_resume,
@@ -413,7 +414,7 @@ void usb_serial_generic_unthrottle(struc
 	}
 }
 
-void usb_serial_generic_shutdown(struct usb_serial *serial)
+void usb_serial_generic_disconnect(struct usb_serial *serial)
 {
 	int i;
 
@@ -424,3 +425,7 @@ void usb_serial_generic_shutdown(struct
 		generic_cleanup(serial->port[i]);
 }
 
+void usb_serial_generic_release(struct usb_serial *serial)
+{
+	dbg("%s", __func__);
+}
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/io_edgeport.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_edgeport.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/io_edgeport.c	2013-05-03 16:51:41.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_edgeport.c	2013-05-03 17:30:30.000000000 -0400
@@ -225,7 +225,8 @@ static int  edge_tiocmget(struct tty_str
 static int  edge_tiocmset(struct tty_struct *tty, struct file *file,
 					unsigned int set, unsigned int clear);
 static int  edge_startup(struct usb_serial *serial);
-static void edge_shutdown(struct usb_serial *serial);
+static void edge_disconnect(struct usb_serial *serial);
+static void edge_release(struct usb_serial *serial);
 
 #include "io_tables.h"	/* all of the devices that this driver supports */
 
@@ -3195,21 +3196,16 @@ static int edge_startup(struct usb_seria
 
 
 /****************************************************************************
- * edge_shutdown
+ * edge_disconnect
  *	This function is called whenever the device is removed from the usb bus.
  ****************************************************************************/
-static void edge_shutdown(struct usb_serial *serial)
+static void edge_disconnect(struct usb_serial *serial)
 {
 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
-	int i;
 
 	dbg("%s", __func__);
 
 	/* stop reads and writes on all ports */
-	for (i = 0; i < serial->num_ports; ++i) {
-		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i],  NULL);
-	}
 	/* free up our endpoint stuff */
 	if (edge_serial->is_epic) {
 		usb_kill_urb(edge_serial->interrupt_read_urb);
@@ -3220,9 +3216,24 @@ static void edge_shutdown(struct usb_ser
 		usb_free_urb(edge_serial->read_urb);
 		kfree(edge_serial->bulk_in_buffer);
 	}
+}
+
+
+/****************************************************************************
+ * edge_release
+ *	This function is called when the device structure is deallocated.
+ ****************************************************************************/
+static void edge_release(struct usb_serial *serial)
+{
+	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+	int i;
+
+	dbg("%s", __func__);
+
+	for (i = 0; i < serial->num_ports; ++i)
+		kfree(usb_get_serial_port_data(serial->port[i]));
 
 	kfree(edge_serial);
-	usb_set_serial_data(serial, NULL);
 }
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/io_tables.h linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_tables.h
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/io_tables.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_tables.h	2009-12-04 01:00:07.000000000 -0500
@@ -117,7 +117,8 @@ static struct usb_serial_driver edgeport
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
 	.tiocmget		= edge_tiocmget,
@@ -145,7 +146,8 @@ static struct usb_serial_driver edgeport
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
 	.tiocmget		= edge_tiocmget,
@@ -173,7 +175,8 @@ static struct usb_serial_driver edgeport
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
 	.tiocmget		= edge_tiocmget,
@@ -200,7 +203,8 @@ static struct usb_serial_driver epic_dev
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
 	.tiocmget		= edge_tiocmget,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/io_ti.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_ti.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/io_ti.c	2013-05-03 16:51:46.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/io_ti.c	2013-05-03 17:30:34.000000000 -0400
@@ -2664,7 +2664,7 @@ cleanup:
 	return -ENOMEM;
 }
 
-static void edge_shutdown(struct usb_serial *serial)
+static void edge_disconnect(struct usb_serial *serial)
 {
 	int i;
 	struct edgeport_port *edge_port;
@@ -2674,12 +2674,22 @@ static void edge_shutdown(struct usb_ser
 	for (i = 0; i < serial->num_ports; ++i) {
 		edge_port = usb_get_serial_port_data(serial->port[i]);
 		edge_remove_sysfs_attrs(edge_port->port);
+	}
+}
+
+static void edge_release(struct usb_serial *serial)
+{
+	int i;
+	struct edgeport_port *edge_port;
+
+	dbg("%s", __func__);
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		edge_port = usb_get_serial_port_data(serial->port[i]);
 		edge_buf_free(edge_port->ep_out_buf);
 		kfree(edge_port);
-		usb_set_serial_port_data(serial->port[i], NULL);
 	}
 	kfree(usb_get_serial_data(serial));
-	usb_set_serial_data(serial, NULL);
 }
 
 
@@ -2916,7 +2926,8 @@ static struct usb_serial_driver edgeport
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.port_probe		= edge_create_sysfs_attrs,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
@@ -2945,7 +2956,8 @@ static struct usb_serial_driver edgeport
 	.throttle		= edge_throttle,
 	.unthrottle		= edge_unthrottle,
 	.attach			= edge_startup,
-	.shutdown		= edge_shutdown,
+	.disconnect		= edge_disconnect,
+	.release		= edge_release,
 	.port_probe		= edge_create_sysfs_attrs,
 	.ioctl			= edge_ioctl,
 	.set_termios		= edge_set_termios,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/ipaq.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ipaq.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/ipaq.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ipaq.c	2009-12-04 01:00:07.000000000 -0500
@@ -80,7 +80,6 @@ static void ipaq_close(struct tty_struct
 			struct usb_serial_port *port, struct file *filp);
 static int  ipaq_calc_num_ports(struct usb_serial *serial);
 static int  ipaq_startup(struct usb_serial *serial);
-static void ipaq_shutdown(struct usb_serial *serial);
 static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
 			const unsigned char *buf, int count);
 static int ipaq_write_bulk(struct usb_serial_port *port,
@@ -577,7 +576,6 @@ static struct usb_serial_driver ipaq_dev
 	.close =		ipaq_close,
 	.attach =		ipaq_startup,
 	.calc_num_ports =	ipaq_calc_num_ports,
-	.shutdown =		ipaq_shutdown,
 	.write =		ipaq_write,
 	.write_room =		ipaq_write_room,
 	.chars_in_buffer =	ipaq_chars_in_buffer,
@@ -992,11 +990,6 @@ static int ipaq_startup(struct usb_seria
 	return usb_reset_configuration(serial->dev);
 }
 
-static void ipaq_shutdown(struct usb_serial *serial)
-{
-	dbg("%s", __func__);
-}
-
 static int __init ipaq_init(void)
 {
 	int retval;
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/iuu_phoenix.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/iuu_phoenix.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/iuu_phoenix.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/iuu_phoenix.c	2009-12-04 01:00:07.000000000 -0500
@@ -122,8 +122,8 @@ static int iuu_startup(struct usb_serial
 	return 0;
 }
 
-/* Shutdown function */
-static void iuu_shutdown(struct usb_serial *serial)
+/* Release function */
+static void iuu_release(struct usb_serial *serial)
 {
 	struct usb_serial_port *port = serial->port[0];
 	struct iuu_private *priv = usb_get_serial_port_data(port);
@@ -1176,7 +1176,7 @@ static struct usb_serial_driver iuu_devi
 	.tiocmget = iuu_tiocmget,
 	.tiocmset = iuu_tiocmset,
 	.attach = iuu_startup,
-	.shutdown = iuu_shutdown,
+	.release = iuu_release,
 };
 
 static int __init iuu_init(void)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan.c	2013-05-03 16:51:31.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan.c	2013-05-03 17:30:19.000000000 -0400
@@ -2682,7 +2682,7 @@ static int keyspan_startup(struct usb_se
 	return 0;
 }
 
-static void keyspan_shutdown(struct usb_serial *serial)
+static void keyspan_disconnect(struct usb_serial *serial)
 {
 	int				i, j;
 	struct usb_serial_port		*port;
@@ -2722,6 +2722,17 @@ static void keyspan_shutdown(struct usb_
 			usb_free_urb(p_priv->out_urbs[j]);
 		}
 	}
+}
+
+static void keyspan_release(struct usb_serial *serial)
+{
+	int				i;
+	struct usb_serial_port		*port;
+	struct keyspan_serial_private 	*s_priv;
+
+	dbg("%s", __func__);
+
+	s_priv = usb_get_serial_data(serial);
 
 	/*  dbg("Freeing serial->private."); */
 	kfree(s_priv);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan.h linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan.h
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan.h	2009-12-04 01:00:07.000000000 -0500
@@ -42,7 +42,8 @@ static void keyspan_close		(struct tty_s
 					 struct usb_serial_port *port,
 					 struct file *filp);
 static int  keyspan_startup		(struct usb_serial *serial);
-static void keyspan_shutdown		(struct usb_serial *serial);
+static void keyspan_disconnect		(struct usb_serial *serial);
+static void keyspan_release		(struct usb_serial *serial);
 static int  keyspan_write_room		(struct tty_struct *tty);
 
 static int  keyspan_write		(struct tty_struct *tty,
@@ -569,7 +570,8 @@ static struct usb_serial_driver keyspan_
 	.tiocmget		= keyspan_tiocmget,
 	.tiocmset		= keyspan_tiocmset,
 	.attach			= keyspan_startup,
-	.shutdown		= keyspan_shutdown,
+	.disconnect		= keyspan_disconnect,
+	.release		= keyspan_release,
 };
 
 static struct usb_serial_driver keyspan_2port_device = {
@@ -589,7 +591,8 @@ static struct usb_serial_driver keyspan_
 	.tiocmget		= keyspan_tiocmget,
 	.tiocmset		= keyspan_tiocmset,
 	.attach			= keyspan_startup,
-	.shutdown		= keyspan_shutdown,
+	.disconnect		= keyspan_disconnect,
+	.release		= keyspan_release,
 };
 
 static struct usb_serial_driver keyspan_4port_device = {
@@ -609,7 +612,8 @@ static struct usb_serial_driver keyspan_
 	.tiocmget		= keyspan_tiocmget,
 	.tiocmset		= keyspan_tiocmset,
 	.attach			= keyspan_startup,
-	.shutdown		= keyspan_shutdown,
+	.disconnect		= keyspan_disconnect,
+	.release		= keyspan_release,
 };
 
 #endif
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan_pda.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan_pda.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/keyspan_pda.c	2013-05-03 16:51:31.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/keyspan_pda.c	2013-05-03 17:30:19.000000000 -0400
@@ -795,7 +795,7 @@ static int keyspan_pda_startup(struct us
 	return 0;
 }
 
-static void keyspan_pda_shutdown(struct usb_serial *serial)
+static void keyspan_pda_release(struct usb_serial *serial)
 {
 	dbg("%s", __func__);
 
@@ -853,7 +853,7 @@ static struct usb_serial_driver keyspan_
 	.tiocmget =		keyspan_pda_tiocmget,
 	.tiocmset =		keyspan_pda_tiocmset,
 	.attach =		keyspan_pda_startup,
-	.shutdown =		keyspan_pda_shutdown,
+	.release =		keyspan_pda_release,
 };
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/kl5kusb105.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/kl5kusb105.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/kl5kusb105.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/kl5kusb105.c	2009-12-04 01:00:07.000000000 -0500
@@ -73,7 +73,8 @@ static int debug;
  * Function prototypes
  */
 static int  klsi_105_startup(struct usb_serial *serial);
-static void klsi_105_shutdown(struct usb_serial *serial);
+static void klsi_105_disconnect(struct usb_serial *serial);
+static void klsi_105_release(struct usb_serial *serial);
 static int  klsi_105_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void klsi_105_close(struct tty_struct *tty,
@@ -132,7 +133,8 @@ static struct usb_serial_driver kl5kusb1
 	.tiocmget =          klsi_105_tiocmget,
 	.tiocmset =          klsi_105_tiocmset,
 	.attach =	     klsi_105_startup,
-	.shutdown =	     klsi_105_shutdown,
+	.disconnect =	     klsi_105_disconnect,
+	.release =	     klsi_105_release,
 	.throttle =	     klsi_105_throttle,
 	.unthrottle =	     klsi_105_unthrottle,
 };
@@ -316,7 +318,7 @@ err_cleanup:
 } /* klsi_105_startup */
 
 
-static void klsi_105_shutdown(struct usb_serial *serial)
+static void klsi_105_disconnect(struct usb_serial *serial)
 {
 	int i;
 
@@ -326,33 +328,36 @@ static void klsi_105_shutdown(struct usb
 	for (i = 0; i < serial->num_ports; ++i) {
 		struct klsi_105_private *priv =
 				usb_get_serial_port_data(serial->port[i]);
-		unsigned long flags;
 
 		if (priv) {
 			/* kill our write urb pool */
 			int j;
 			struct urb **write_urbs = priv->write_urb_pool;
-			spin_lock_irqsave(&priv->lock, flags);
 
 			for (j = 0; j < NUM_URBS; j++) {
 				if (write_urbs[j]) {
-					/* FIXME - uncomment the following
-					 * usb_kill_urb call when the host
-					 * controllers get fixed to set
-					 * urb->dev = NULL after the urb is
-					 * finished.  Otherwise this call
-					 * oopses. */
-					/* usb_kill_urb(write_urbs[j]); */
-					kfree(write_urbs[j]->transfer_buffer);
+					usb_kill_urb(write_urbs[j]);
 					usb_free_urb(write_urbs[j]);
 				}
 			}
-			spin_unlock_irqrestore(&priv->lock, flags);
-			kfree(priv);
-			usb_set_serial_port_data(serial->port[i], NULL);
 		}
 	}
-} /* klsi_105_shutdown */
+} /* klsi_105_disconnect */
+
+
+static void klsi_105_release(struct usb_serial *serial)
+{
+	int i;
+
+	dbg("%s", __func__);
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		struct klsi_105_private *priv =
+				usb_get_serial_port_data(serial->port[i]);
+
+		kfree(priv);
+	}
+} /* klsi_105_release */
 
 static int  klsi_105_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/kobil_sct.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/kobil_sct.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/kobil_sct.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/kobil_sct.c	2009-12-04 01:00:07.000000000 -0500
@@ -69,7 +69,7 @@ static int debug;
 
 /* Function prototypes */
 static int  kobil_startup(struct usb_serial *serial);
-static void kobil_shutdown(struct usb_serial *serial);
+static void kobil_release(struct usb_serial *serial);
 static int  kobil_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void kobil_close(struct tty_struct *tty, struct usb_serial_port *port,
@@ -118,7 +118,7 @@ static struct usb_serial_driver kobil_de
 	.id_table =		id_table,
 	.num_ports =		1,
 	.attach =		kobil_startup,
-	.shutdown =		kobil_shutdown,
+	.release =		kobil_release,
 	.ioctl =		kobil_ioctl,
 	.set_termios =		kobil_set_termios,
 	.tiocmget =		kobil_tiocmget,
@@ -202,17 +202,13 @@ static int kobil_startup(struct usb_seri
 }
 
 
-static void kobil_shutdown(struct usb_serial *serial)
+static void kobil_release(struct usb_serial *serial)
 {
 	int i;
 	dbg("%s - port %d", __func__, serial->port[0]->number);
 
-	for (i = 0; i < serial->num_ports; ++i) {
-		while (serial->port[i]->port.count > 0)
-			kobil_close(NULL, serial->port[i], NULL);
+	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i], NULL);
-	}
 }
 
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/mct_u232.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mct_u232.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/mct_u232.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mct_u232.c	2009-12-04 01:00:07.000000000 -0500
@@ -92,7 +92,7 @@ static int debug;
  * Function prototypes
  */
 static int  mct_u232_startup(struct usb_serial *serial);
-static void mct_u232_shutdown(struct usb_serial *serial);
+static void mct_u232_release(struct usb_serial *serial);
 static int  mct_u232_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void mct_u232_close(struct tty_struct *tty,
@@ -148,7 +148,7 @@ static struct usb_serial_driver mct_u232
 	.tiocmget =	     mct_u232_tiocmget,
 	.tiocmset =	     mct_u232_tiocmset,
 	.attach =	     mct_u232_startup,
-	.shutdown =	     mct_u232_shutdown,
+	.release =	     mct_u232_release,
 };
 
 
@@ -406,7 +406,7 @@ static int mct_u232_startup(struct usb_s
 } /* mct_u232_startup */
 
 
-static void mct_u232_shutdown(struct usb_serial *serial)
+static void mct_u232_release(struct usb_serial *serial)
 {
 	struct mct_u232_private *priv;
 	int i;
@@ -416,12 +416,9 @@ static void mct_u232_shutdown(struct usb
 	for (i = 0; i < serial->num_ports; ++i) {
 		/* My special items, the standard routines free my urbs */
 		priv = usb_get_serial_port_data(serial->port[i]);
-		if (priv) {
-			usb_set_serial_port_data(serial->port[i], NULL);
-			kfree(priv);
-		}
+		kfree(priv);
 	}
-} /* mct_u232_shutdown */
+} /* mct_u232_release */
 
 static int  mct_u232_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/mos7720.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mos7720.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/mos7720.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mos7720.c	2009-12-04 01:00:07.000000000 -0500
@@ -1522,19 +1522,16 @@ static int mos7720_startup(struct usb_se
 	return 0;
 }
 
-static void mos7720_shutdown(struct usb_serial *serial)
+static void mos7720_release(struct usb_serial *serial)
 {
 	int i;
 
 	/* free private structure allocated for serial port */
-	for (i = 0; i < serial->num_ports; ++i) {
+	for (i = 0; i < serial->num_ports; ++i)
 		kfree(usb_get_serial_port_data(serial->port[i]));
-		usb_set_serial_port_data(serial->port[i], NULL);
-	}
 
 	/* free private structure allocated for serial device */
 	kfree(usb_get_serial_data(serial));
-	usb_set_serial_data(serial, NULL);
 }
 
 static struct usb_driver usb_driver = {
@@ -1559,7 +1556,7 @@ static struct usb_serial_driver moschip7
 	.throttle		= mos7720_throttle,
 	.unthrottle		= mos7720_unthrottle,
 	.attach			= mos7720_startup,
-	.shutdown		= mos7720_shutdown,
+	.release		= mos7720_release,
 	.ioctl			= mos7720_ioctl,
 	.set_termios		= mos7720_set_termios,
 	.write			= mos7720_write,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/mos7840.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mos7840.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/mos7840.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/mos7840.c	2009-12-04 01:00:07.000000000 -0500
@@ -2673,16 +2673,16 @@ error:
 }
 
 /****************************************************************************
- * mos7840_shutdown
+ * mos7840_disconnect
  *	This function is called whenever the device is removed from the usb bus.
  ****************************************************************************/
 
-static void mos7840_shutdown(struct usb_serial *serial)
+static void mos7840_disconnect(struct usb_serial *serial)
 {
 	int i;
 	unsigned long flags;
 	struct moschip_port *mos7840_port;
-	dbg("%s \n", " shutdown :entering..........");
+	dbg("%s \n", " disconnect :entering..........");
 
 	if (!serial) {
 		dbg("%s", "Invalid Handler \n");
@@ -2702,11 +2702,42 @@ static void mos7840_shutdown(struct usb_
 			mos7840_port->zombie = 1;
 			spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
 			usb_kill_urb(mos7840_port->control_urb);
+		}
+	}
+
+	dbg("%s", "Thank u :: ");
+
+}
+
+/****************************************************************************
+ * mos7840_release
+ *	This function is called when the usb_serial structure is freed.
+ ****************************************************************************/
+
+static void mos7840_release(struct usb_serial *serial)
+{
+	int i;
+	struct moschip_port *mos7840_port;
+	dbg("%s", " release :entering..........");
+
+	if (!serial) {
+		dbg("%s", "Invalid Handler");
+		return;
+	}
+
+	/* check for the ports to be closed,close the ports and disconnect */
+
+	/* free private structure allocated for serial port  *
+	 * stop reads and writes on all ports                */
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		mos7840_port = mos7840_get_port_private(serial->port[i]);
+		dbg("mos7840_port %d = %p", i, mos7840_port);
+		if (mos7840_port) {
 			kfree(mos7840_port->ctrl_buf);
 			kfree(mos7840_port->dr);
 			kfree(mos7840_port);
 		}
-		mos7840_set_port_private(serial->port[i], NULL);
 	}
 
 	dbg("%s\n", "Thank u :: ");
@@ -2747,7 +2778,8 @@ static struct usb_serial_driver moschip7
 	.tiocmget = mos7840_tiocmget,
 	.tiocmset = mos7840_tiocmset,
 	.attach = mos7840_startup,
-	.shutdown = mos7840_shutdown,
+	.disconnect = mos7840_disconnect,
+	.release = mos7840_release,
 	.read_bulk_callback = mos7840_bulk_in_callback,
 	.read_int_callback = mos7840_interrupt_callback,
 };
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/omninet.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/omninet.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/omninet.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/omninet.c	2009-12-04 01:00:07.000000000 -0500
@@ -73,7 +73,8 @@ static void omninet_write_bulk_callback(
 static int  omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
 				const unsigned char *buf, int count);
 static int  omninet_write_room(struct tty_struct *tty);
-static void omninet_shutdown(struct usb_serial *serial);
+static void omninet_disconnect(struct usb_serial *serial);
+static void omninet_release(struct usb_serial *serial);
 static int omninet_attach(struct usb_serial *serial);
 
 static struct usb_device_id id_table[] = {
@@ -109,7 +110,8 @@ static struct usb_serial_driver zyxel_om
 	.write_room =		omninet_write_room,
 	.read_bulk_callback =	omninet_read_bulk_callback,
 	.write_bulk_callback =	omninet_write_bulk_callback,
-	.shutdown =		omninet_shutdown,
+	.disconnect =		omninet_disconnect,
+	.release =		omninet_release,
 };
 
 
@@ -347,13 +349,22 @@ static void omninet_write_bulk_callback(
 }
 
 
-static void omninet_shutdown(struct usb_serial *serial)
+static void omninet_disconnect(struct usb_serial *serial)
 {
 	struct usb_serial_port *wport = serial->port[1];
-	struct usb_serial_port *port = serial->port[0];
+
 	dbg("%s", __func__);
 
 	usb_kill_urb(wport->write_urb);
+}
+
+
+static void omninet_release(struct usb_serial *serial)
+{
+	struct usb_serial_port *port = serial->port[0];
+
+	dbg("%s", __func__);
+
 	kfree(usb_get_serial_port_data(port));
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/opticon.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/opticon.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/opticon.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/opticon.c	2009-12-04 01:00:07.000000000 -0500
@@ -464,7 +464,7 @@ error:
 	return retval;
 }
 
-static void opticon_shutdown(struct usb_serial *serial)
+static void opticon_disconnect(struct usb_serial *serial)
 {
 	struct opticon_private *priv = usb_get_serial_data(serial);
 
@@ -472,9 +472,16 @@ static void opticon_shutdown(struct usb_
 
 	usb_kill_urb(priv->bulk_read_urb);
 	usb_free_urb(priv->bulk_read_urb);
+}
+
+static void opticon_release(struct usb_serial *serial)
+{
+	struct opticon_private *priv = usb_get_serial_data(serial);
+
+	dbg("%s", __func__);
+
 	kfree(priv->bulk_in_buffer);
 	kfree(priv);
-	usb_set_serial_data(serial, NULL);
 }
 
 static int opticon_suspend(struct usb_interface *intf, pm_message_t message)
@@ -525,7 +532,8 @@ static struct usb_serial_driver opticon_
 	.close =		opticon_close,
 	.write =		opticon_write,
 	.write_room = 		opticon_write_room,
-	.shutdown =		opticon_shutdown,
+	.disconnect =		opticon_disconnect,
+	.release =		opticon_release,
 	.throttle = 		opticon_throttle,
 	.unthrottle =		opticon_unthrottle,
 	.ioctl =		opticon_ioctl,
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/option.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/option.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/option.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/option.c	2009-12-04 01:00:07.000000000 -0500
@@ -48,7 +48,8 @@ static int  option_open(struct tty_struc
 static void option_close(struct tty_struct *tty, struct usb_serial_port *port,
 							struct file *filp);
 static int  option_startup(struct usb_serial *serial);
-static void option_shutdown(struct usb_serial *serial);
+static void option_disconnect(struct usb_serial *serial);
+static void option_release(struct usb_serial *serial);
 static int  option_write_room(struct tty_struct *tty);
 
 static void option_instat_callback(struct urb *urb);
@@ -558,7 +559,8 @@ static struct usb_serial_driver option_1
 	.tiocmget          = option_tiocmget,
 	.tiocmset          = option_tiocmset,
 	.attach            = option_startup,
-	.shutdown          = option_shutdown,
+	.disconnect        = option_disconnect,
+	.release           = option_release,
 	.read_int_callback = option_instat_callback,
 	.suspend           = option_suspend,
 	.resume            = option_resume,
@@ -1129,7 +1131,14 @@ static void stop_read_write_urbs(struct
 	}
 }
 
-static void option_shutdown(struct usb_serial *serial)
+static void option_disconnect(struct usb_serial *serial)
+{
+	dbg("%s", __func__);
+
+	stop_read_write_urbs(serial);
+}
+
+static void option_release(struct usb_serial *serial)
 {
 	int i, j;
 	struct usb_serial_port *port;
@@ -1137,8 +1146,6 @@ static void option_shutdown(struct usb_s
 
 	dbg("%s", __func__);
 
-	stop_read_write_urbs(serial);
-
 	/* Now free them */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/oti6858.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/oti6858.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/oti6858.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/oti6858.c	2009-12-04 01:00:07.000000000 -0500
@@ -160,7 +160,7 @@ static int oti6858_tiocmget(struct tty_s
 static int oti6858_tiocmset(struct tty_struct *tty, struct file *file,
 				unsigned int set, unsigned int clear);
 static int oti6858_startup(struct usb_serial *serial);
-static void oti6858_shutdown(struct usb_serial *serial);
+static void oti6858_release(struct usb_serial *serial);
 
 /* functions operating on buffers */
 static struct oti6858_buf *oti6858_buf_alloc(unsigned int size);
@@ -195,7 +195,7 @@ static struct usb_serial_driver oti6858_
 	.write_room =		oti6858_write_room,
 	.chars_in_buffer =	oti6858_chars_in_buffer,
 	.attach =		oti6858_startup,
-	.shutdown =		oti6858_shutdown,
+	.release =		oti6858_release,
 };
 
 struct oti6858_private {
@@ -829,7 +829,7 @@ static int oti6858_ioctl(struct tty_stru
 }
 
 
-static void oti6858_shutdown(struct usb_serial *serial)
+static void oti6858_release(struct usb_serial *serial)
 {
 	struct oti6858_private *priv;
 	int i;
@@ -841,7 +841,6 @@ static void oti6858_shutdown(struct usb_
 		if (priv) {
 			oti6858_buf_free(priv->buf);
 			kfree(priv);
-			usb_set_serial_port_data(serial->port[i], NULL);
 		}
 	}
 }
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/pl2303.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/pl2303.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/pl2303.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/pl2303.c	2009-12-04 01:00:07.000000000 -0500
@@ -897,7 +897,7 @@ static void pl2303_break_ctl(struct tty_
 		dbg("%s - error sending break = %d", __func__, result);
 }
 
-static void pl2303_shutdown(struct usb_serial *serial)
+static void pl2303_release(struct usb_serial *serial)
 {
 	int i;
 	struct pl2303_private *priv;
@@ -909,7 +909,6 @@ static void pl2303_shutdown(struct usb_s
 		if (priv) {
 			pl2303_buf_free(priv->buf);
 			kfree(priv);
-			usb_set_serial_port_data(serial->port[i], NULL);
 		}
 	}
 }
@@ -1137,7 +1136,7 @@ static struct usb_serial_driver pl2303_d
 	.write_room =		pl2303_write_room,
 	.chars_in_buffer =	pl2303_chars_in_buffer,
 	.attach =		pl2303_startup,
-	.shutdown =		pl2303_shutdown,
+	.release =		pl2303_release,
 };
 
 static int __init pl2303_init(void)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/sierra.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/sierra.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/sierra.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/sierra.c	2009-12-04 01:00:07.000000000 -0500
@@ -699,7 +699,7 @@ static int sierra_startup(struct usb_ser
 	return 0;
 }
 
-static void sierra_shutdown(struct usb_serial *serial)
+static void sierra_disconnect(struct usb_serial *serial)
 {
 	int i, j;
 	struct usb_serial_port *port;
@@ -718,10 +718,29 @@ static void sierra_shutdown(struct usb_s
 		for (j = 0; j < N_IN_URB; j++) {
 			usb_kill_urb(portdata->in_urbs[j]);
 			usb_free_urb(portdata->in_urbs[j]);
-			kfree(portdata->in_buffer[j]);
 		}
+	}
+}
+
+static void sierra_release(struct usb_serial *serial)
+{
+	int i, j;
+	struct usb_serial_port *port;
+	struct sierra_port_private *portdata;
+
+	dev_dbg(&serial->dev->dev, "%s\n", __func__);
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		if (!port)
+			continue;
+		portdata = usb_get_serial_port_data(port);
+		if (!portdata)
+			continue;
+
+		for (j = 0; j < N_IN_URB; j++)
+			kfree(portdata->in_buffer[j]);
 		kfree(portdata);
-		usb_set_serial_port_data(port, NULL);
 	}
 }
 
@@ -743,7 +762,8 @@ static struct usb_serial_driver sierra_d
 	.tiocmget          = sierra_tiocmget,
 	.tiocmset          = sierra_tiocmset,
 	.attach            = sierra_startup,
-	.shutdown          = sierra_shutdown,
+	.disconnect        = sierra_disconnect,
+	.release           = sierra_release,
 	.read_int_callback = sierra_instat_callback,
 };
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/spcp8x5.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/spcp8x5.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/spcp8x5.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/spcp8x5.c	2009-12-04 01:00:07.000000000 -0500
@@ -356,7 +356,7 @@ cleanup:
 }
 
 /* call when the device plug out. free all the memory alloced by probe */
-static void spcp8x5_shutdown(struct usb_serial *serial)
+static void spcp8x5_release(struct usb_serial *serial)
 {
 	int i;
 	struct spcp8x5_private *priv;
@@ -366,7 +366,6 @@ static void spcp8x5_shutdown(struct usb_
 		if (priv) {
 			free_ringbuf(priv->buf);
 			kfree(priv);
-			usb_set_serial_port_data(serial->port[i] , NULL);
 		}
 	}
 }
@@ -1043,7 +1042,7 @@ static struct usb_serial_driver spcp8x5_
 	.write_bulk_callback	= spcp8x5_write_bulk_callback,
 	.chars_in_buffer 	= spcp8x5_chars_in_buffer,
 	.attach 		= spcp8x5_startup,
-	.shutdown 		= spcp8x5_shutdown,
+	.release 		= spcp8x5_release,
 };
 
 static int __init spcp8x5_init(void)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/symbolserial.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/symbolserial.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/symbolserial.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/symbolserial.c	2009-12-04 01:00:07.000000000 -0500
@@ -268,7 +268,7 @@ error:
 	return retval;
 }
 
-static void symbol_shutdown(struct usb_serial *serial)
+static void symbol_disconnect(struct usb_serial *serial)
 {
 	struct symbol_private *priv = usb_get_serial_data(serial);
 
@@ -276,9 +276,16 @@ static void symbol_shutdown(struct usb_s
 
 	usb_kill_urb(priv->int_urb);
 	usb_free_urb(priv->int_urb);
+}
+
+static void symbol_release(struct usb_serial *serial)
+{
+	struct symbol_private *priv = usb_get_serial_data(serial);
+
+	dbg("%s", __func__);
+
 	kfree(priv->int_buffer);
 	kfree(priv);
-	usb_set_serial_data(serial, NULL);
 }
 
 static struct usb_driver symbol_driver = {
@@ -300,7 +307,8 @@ static struct usb_serial_driver symbol_d
 	.attach =		symbol_startup,
 	.open =			symbol_open,
 	.close =		symbol_close,
-	.shutdown =		symbol_shutdown,
+	.disconnect =		symbol_disconnect,
+	.release =		symbol_release,
 	.throttle = 		symbol_throttle,
 	.unthrottle =		symbol_unthrottle,
 };
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/ti_usb_3410_5052.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ti_usb_3410_5052.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/ti_usb_3410_5052.c	2013-05-03 16:51:48.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/ti_usb_3410_5052.c	2013-05-03 17:30:37.000000000 -0400
@@ -97,7 +97,7 @@ struct ti_device {
 /* Function Declarations */
 
 static int ti_startup(struct usb_serial *serial);
-static void ti_shutdown(struct usb_serial *serial);
+static void ti_release(struct usb_serial *serial);
 static int ti_open(struct tty_struct *tty, struct usb_serial_port *port,
 		struct file *file);
 static void ti_close(struct tty_struct *tty, struct usb_serial_port *port,
@@ -192,7 +192,6 @@ static struct usb_device_id ti_id_table_
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
 	{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
-	{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
 };
 
 static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = {
@@ -231,7 +230,7 @@ static struct usb_serial_driver ti_1port
 	.id_table		= ti_id_table_3410,
 	.num_ports		= 1,
 	.attach			= ti_startup,
-	.shutdown		= ti_shutdown,
+	.release		= ti_release,
 	.open			= ti_open,
 	.close			= ti_close,
 	.write			= ti_write,
@@ -259,7 +258,7 @@ static struct usb_serial_driver ti_2port
 	.id_table		= ti_id_table_5052,
 	.num_ports		= 2,
 	.attach			= ti_startup,
-	.shutdown		= ti_shutdown,
+	.release		= ti_release,
 	.open			= ti_open,
 	.close			= ti_close,
 	.write			= ti_write,
@@ -470,7 +469,7 @@ free_tdev:
 }
 
 
-static void ti_shutdown(struct usb_serial *serial)
+static void ti_release(struct usb_serial *serial)
 {
 	int i;
 	struct ti_device *tdev = usb_get_serial_data(serial);
@@ -483,12 +482,10 @@ static void ti_shutdown(struct usb_seria
 		if (tport) {
 			ti_buf_free(tport->tp_write_buf);
 			kfree(tport);
-			usb_set_serial_port_data(serial->port[i], NULL);
 		}
 	}
 
 	kfree(tdev);
-	usb_set_serial_data(serial, NULL);
 }
 
 
@@ -1658,7 +1655,7 @@ static int ti_do_download(struct usb_dev
 	u8 cs = 0;
 	int done;
 	struct ti_firmware_header *header;
-	int status;
+	int status = 0;
 	int len;
 
 	for (pos = sizeof(struct ti_firmware_header); pos < size; pos++)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/usb-serial.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/usb-serial.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/usb-serial.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/usb-serial.c	2009-12-04 01:00:07.000000000 -0500
@@ -141,6 +141,14 @@ static void destroy_serial(struct kref *
 	if (serial->minor != SERIAL_TTY_NO_MINOR)
 		return_serial(serial);
 
+	serial->type->release(serial);
+
+	for (i = 0; i < serial->num_ports; ++i) {
+		port = serial->port[i];
+		if (port)
+			put_device(&port->dev);
+	}
+
 	/* If this is a "fake" port, we have to clean it up here, as it will
 	 * not get cleaned up in port_release() as it was never registered with
 	 * the driver core */
@@ -148,9 +156,8 @@ static void destroy_serial(struct kref *
 		for (i = serial->num_ports;
 					i < serial->num_port_pointers; ++i) {
 			port = serial->port[i];
-			if (!port)
-				continue;
-			port_free(port);
+			if (port)
+				port_free(port);
 		}
 	}
 
@@ -1062,10 +1069,6 @@ void usb_serial_disconnect(struct usb_in
 	serial->disconnected = 1;
 	mutex_unlock(&serial->disc_mutex);
 
-	/* Unfortunately, many of the sub-drivers expect the port structures
-	 * to exist when their shutdown method is called, so we have to go
-	 * through this awkward two-step unregistration procedure.
-	 */
 	for (i = 0; i < serial->num_ports; ++i) {
 		port = serial->port[i];
 		if (port) {
@@ -1079,14 +1082,7 @@ void usb_serial_disconnect(struct usb_in
 			device_del(&port->dev);
 		}
 	}
-	serial->type->shutdown(serial);
-	for (i = 0; i < serial->num_ports; ++i) {
-		port = serial->port[i];
-		if (port) {
-			put_device(&port->dev);
-			serial->port[i] = NULL;
-		}
-	}
+	serial->type->disconnect(serial);
 
 	/* let the last holder of this object
 	 * cause it to be cleaned up */
@@ -1262,7 +1258,8 @@ static void fixup_generic(struct usb_ser
 	set_to_generic_if_null(device, chars_in_buffer);
 	set_to_generic_if_null(device, read_bulk_callback);
 	set_to_generic_if_null(device, write_bulk_callback);
-	set_to_generic_if_null(device, shutdown);
+	set_to_generic_if_null(device, disconnect);
+	set_to_generic_if_null(device, release);
 }
 
 int usb_serial_register(struct usb_serial_driver *driver)
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/visor.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/visor.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/visor.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/visor.c	2009-12-04 01:00:07.000000000 -0500
@@ -48,7 +48,7 @@ static void visor_unthrottle(struct tty_
 static int  visor_probe(struct usb_serial *serial,
 					const struct usb_device_id *id);
 static int  visor_calc_num_ports(struct usb_serial *serial);
-static void visor_shutdown(struct usb_serial *serial);
+static void visor_release(struct usb_serial *serial);
 static void visor_write_bulk_callback(struct urb *urb);
 static void visor_read_bulk_callback(struct urb *urb);
 static void visor_read_int_callback(struct urb *urb);
@@ -203,7 +203,7 @@ static struct usb_serial_driver handspri
 	.attach =		treo_attach,
 	.probe =		visor_probe,
 	.calc_num_ports =	visor_calc_num_ports,
-	.shutdown =		visor_shutdown,
+	.release =		visor_release,
 	.write =		visor_write,
 	.write_room =		visor_write_room,
 	.write_bulk_callback =	visor_write_bulk_callback,
@@ -228,7 +228,7 @@ static struct usb_serial_driver clie_5_d
 	.attach =		clie_5_attach,
 	.probe =		visor_probe,
 	.calc_num_ports =	visor_calc_num_ports,
-	.shutdown =		visor_shutdown,
+	.release =		visor_release,
 	.write =		visor_write,
 	.write_room =		visor_write_room,
 	.write_bulk_callback =	visor_write_bulk_callback,
@@ -920,7 +920,7 @@ static int clie_5_attach(struct usb_seri
 	return generic_startup(serial);
 }
 
-static void visor_shutdown(struct usb_serial *serial)
+static void visor_release(struct usb_serial *serial)
 {
 	struct visor_private *priv;
 	int i;
@@ -929,10 +929,7 @@ static void visor_shutdown(struct usb_se
 
 	for (i = 0; i < serial->num_ports; i++) {
 		priv = usb_get_serial_port_data(serial->port[i]);
-		if (priv) {
-			usb_set_serial_port_data(serial->port[i], NULL);
-			kfree(priv);
-		}
+		kfree(priv);
 	}
 }
 
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/serial/whiteheat.c linux-libre-2.6.30.10-gnu1/drivers/usb/serial/whiteheat.c
--- linux-libre-2.6.30-gnu1/drivers/usb/serial/whiteheat.c	2013-05-03 16:51:56.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/serial/whiteheat.c	2013-05-03 17:30:45.000000000 -0400
@@ -144,7 +144,7 @@ static int  whiteheat_firmware_attach(st
 
 /* function prototypes for the Connect Tech WhiteHEAT serial converter */
 static int  whiteheat_attach(struct usb_serial *serial);
-static void whiteheat_shutdown(struct usb_serial *serial);
+static void whiteheat_release(struct usb_serial *serial);
 static int  whiteheat_open(struct tty_struct *tty,
 			struct usb_serial_port *port, struct file *filp);
 static void whiteheat_close(struct tty_struct *tty,
@@ -190,7 +190,7 @@ static struct usb_serial_driver whitehea
 	.id_table =		id_table_std,
 	.num_ports =		4,
 	.attach =		whiteheat_attach,
-	.shutdown =		whiteheat_shutdown,
+	.release =		whiteheat_release,
 	.open =			whiteheat_open,
 	.close =		whiteheat_close,
 	.write =		whiteheat_write,
@@ -618,7 +618,7 @@ no_command_buffer:
 }
 
 
-static void whiteheat_shutdown(struct usb_serial *serial)
+static void whiteheat_release(struct usb_serial *serial)
 {
 	struct usb_serial_port *command_port;
 	struct usb_serial_port *port;
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/storage/transport.c linux-libre-2.6.30.10-gnu1/drivers/usb/storage/transport.c
--- linux-libre-2.6.30-gnu1/drivers/usb/storage/transport.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/storage/transport.c	2009-12-04 01:00:07.000000000 -0500
@@ -961,7 +961,7 @@ int usb_stor_Bulk_max_lun(struct us_data
 				 US_BULK_GET_MAX_LUN, 
 				 USB_DIR_IN | USB_TYPE_CLASS | 
 				 USB_RECIP_INTERFACE,
-				 0, us->ifnum, us->iobuf, 1, HZ);
+				 0, us->ifnum, us->iobuf, 1, 10*HZ);
 
 	US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", 
 		  result, us->iobuf[0]);
diff -druNp linux-libre-2.6.30-gnu1/drivers/usb/storage/unusual_devs.h linux-libre-2.6.30.10-gnu1/drivers/usb/storage/unusual_devs.h
--- linux-libre-2.6.30-gnu1/drivers/usb/storage/unusual_devs.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/usb/storage/unusual_devs.h	2009-12-04 01:00:07.000000000 -0500
@@ -838,6 +838,13 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Reported by Rogerio Brito <rbrito@ime.usp.br> */
+UNUSUAL_DEV( 0x067b, 0x2317, 0x0001, 0x001,
+		"Prolific Technology, Inc.",
+		"Mass Storage Device",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_NOT_LOCKABLE ),
+
 /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */
 /* Change to bcdDeviceMin (0x0100 to 0x0001) reported by
  * Thomas Bartosik <tbartdev@gmx-topmail.de> */
diff -druNp linux-libre-2.6.30-gnu1/drivers/video/fbmon.c linux-libre-2.6.30.10-gnu1/drivers/video/fbmon.c
--- linux-libre-2.6.30-gnu1/drivers/video/fbmon.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/video/fbmon.c	2009-12-04 01:00:07.000000000 -0500
@@ -256,8 +256,8 @@ static void fix_edid(unsigned char *edid
 
 static int edid_checksum(unsigned char *edid)
 {
-	unsigned char i, csum = 0, all_null = 0;
-	int err = 0, fix = check_edid(edid);
+	unsigned char csum = 0, all_null = 0;
+	int i, err = 0, fix = check_edid(edid);
 
 	if (fix)
 		fix_edid(edid, fix);
diff -druNp linux-libre-2.6.30-gnu1/drivers/video/xen-fbfront.c linux-libre-2.6.30.10-gnu1/drivers/video/xen-fbfront.c
--- linux-libre-2.6.30-gnu1/drivers/video/xen-fbfront.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/drivers/video/xen-fbfront.c	2009-12-04 01:00:07.000000000 -0500
@@ -454,6 +454,10 @@ static int __devinit xenfb_probe(struct
 
 	xenfb_init_shared_page(info, fb_info);
 
+	ret = xenfb_connect_backend(dev, info);
+	if (ret < 0)
+		goto error;
+
 	ret = register_framebuffer(fb_info);
 	if (ret) {
 		fb_deferred_io_cleanup(fb_info);
@@ -464,10 +468,6 @@ static int __devinit xenfb_probe(struct
 	}
 	info->fb_info = fb_info;
 
-	ret = xenfb_connect_backend(dev, info);
-	if (ret < 0)
-		goto error;
-
 	xenfb_make_preferred_console();
 	return 0;
 
diff -druNp linux-libre-2.6.30-gnu1/fs/binfmt_elf.c linux-libre-2.6.30.10-gnu1/fs/binfmt_elf.c
--- linux-libre-2.6.30-gnu1/fs/binfmt_elf.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/binfmt_elf.c	2009-12-04 01:00:07.000000000 -0500
@@ -501,22 +501,22 @@ static unsigned long load_elf_interp(str
 		}
 	}
 
-	/*
-	 * Now fill out the bss section.  First pad the last page up
-	 * to the page boundary, and then perform a mmap to make sure
-	 * that there are zero-mapped pages up to and including the 
-	 * last bss page.
-	 */
-	if (padzero(elf_bss)) {
-		error = -EFAULT;
-		goto out_close;
-	}
+	if (last_bss > elf_bss) {
+		/*
+		 * Now fill out the bss section.  First pad the last page up
+		 * to the page boundary, and then perform a mmap to make sure
+		 * that there are zero-mapped pages up to and including the
+		 * last bss page.
+		 */
+		if (padzero(elf_bss)) {
+			error = -EFAULT;
+			goto out_close;
+		}
 
-	/* What we have mapped so far */
-	elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
+		/* What we have mapped so far */
+		elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
 
-	/* Map the last of the bss segment */
-	if (last_bss > elf_bss) {
+		/* Map the last of the bss segment */
 		down_write(&current->mm->mmap_sem);
 		error = do_brk(elf_bss, last_bss - elf_bss);
 		up_write(&current->mm->mmap_sem);
@@ -1518,11 +1518,11 @@ static int fill_note_info(struct elfhdr
 	info->thread = NULL;
 
 	psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
-	fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
-
 	if (psinfo == NULL)
 		return 0;
 
+	fill_note(&info->psinfo, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
+
 	/*
 	 * Figure out how many notes we're going to need for each thread.
 	 */
diff -druNp linux-libre-2.6.30-gnu1/fs/binfmt_flat.c linux-libre-2.6.30.10-gnu1/fs/binfmt_flat.c
--- linux-libre-2.6.30-gnu1/fs/binfmt_flat.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/binfmt_flat.c	2009-12-04 01:00:07.000000000 -0500
@@ -828,15 +828,22 @@ static int load_flat_shared_library(int
 	if (IS_ERR(bprm.file))
 		return res;
 
+	bprm.cred = prepare_exec_creds();
+	res = -ENOMEM;
+	if (!bprm.cred)
+		goto out;
+
 	res = prepare_binprm(&bprm);
 
 	if (res <= (unsigned long)-4096)
 		res = load_flat_file(&bprm, libs, id, NULL);
-	if (bprm.file) {
-		allow_write_access(bprm.file);
-		fput(bprm.file);
-		bprm.file = NULL;
-	}
+
+	abort_creds(bprm.cred);
+
+out:
+	allow_write_access(bprm.file);
+	fput(bprm.file);
+
 	return(res);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/fs/bio.c linux-libre-2.6.30.10-gnu1/fs/bio.c
--- linux-libre-2.6.30-gnu1/fs/bio.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/bio.c	2009-12-04 01:00:07.000000000 -0500
@@ -706,14 +706,13 @@ static struct bio_map_data *bio_alloc_ma
 }
 
 static int __bio_copy_iov(struct bio *bio, struct bio_vec *iovecs,
-			  struct sg_iovec *iov, int iov_count, int uncopy,
-			  int do_free_page)
+			  struct sg_iovec *iov, int iov_count,
+			  int to_user, int from_user, int do_free_page)
 {
 	int ret = 0, i;
 	struct bio_vec *bvec;
 	int iov_idx = 0;
 	unsigned int iov_off = 0;
-	int read = bio_data_dir(bio) == READ;
 
 	__bio_for_each_segment(bvec, bio, i, 0) {
 		char *bv_addr = page_address(bvec->bv_page);
@@ -728,13 +727,14 @@ static int __bio_copy_iov(struct bio *bi
 			iov_addr = iov[iov_idx].iov_base + iov_off;
 
 			if (!ret) {
-				if (!read && !uncopy)
-					ret = copy_from_user(bv_addr, iov_addr,
-							     bytes);
-				if (read && uncopy)
+				if (to_user)
 					ret = copy_to_user(iov_addr, bv_addr,
 							   bytes);
 
+				if (from_user)
+					ret = copy_from_user(bv_addr, iov_addr,
+							     bytes);
+
 				if (ret)
 					ret = -EFAULT;
 			}
@@ -771,7 +771,8 @@ int bio_uncopy_user(struct bio *bio)
 
 	if (!bio_flagged(bio, BIO_NULL_MAPPED))
 		ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
-				     bmd->nr_sgvecs, 1, bmd->is_our_pages);
+				     bmd->nr_sgvecs, bio_data_dir(bio) == READ,
+				     0, bmd->is_our_pages);
 	bio_free_map_data(bmd);
 	bio_put(bio);
 	return ret;
@@ -876,8 +877,9 @@ struct bio *bio_copy_user_iov(struct req
 	/*
 	 * success
 	 */
-	if (!write_to_vm && (!map_data || !map_data->null_mapped)) {
-		ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 0);
+	if ((!write_to_vm && (!map_data || !map_data->null_mapped)) ||
+	    (map_data && map_data->from_user)) {
+		ret = __bio_copy_iov(bio, bio->bi_io_vec, iov, iov_count, 0, 1, 0);
 		if (ret)
 			goto cleanup;
 	}
diff -druNp linux-libre-2.6.30-gnu1/fs/buffer.c linux-libre-2.6.30.10-gnu1/fs/buffer.c
--- linux-libre-2.6.30-gnu1/fs/buffer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/buffer.c	2009-12-04 01:00:07.000000000 -0500
@@ -1165,8 +1165,11 @@ void mark_buffer_dirty(struct buffer_hea
 
 	if (!test_set_buffer_dirty(bh)) {
 		struct page *page = bh->b_page;
-		if (!TestSetPageDirty(page))
-			__set_page_dirty(page, page_mapping(page), 0);
+		if (!TestSetPageDirty(page)) {
+			struct address_space *mapping = page_mapping(page);
+			if (mapping)
+				__set_page_dirty(page, mapping, 0);
+		}
 	}
 }
 
diff -druNp linux-libre-2.6.30-gnu1/fs/cifs/cifs_dfs_ref.c linux-libre-2.6.30.10-gnu1/fs/cifs/cifs_dfs_ref.c
--- linux-libre-2.6.30-gnu1/fs/cifs/cifs_dfs_ref.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/cifs/cifs_dfs_ref.c	2009-12-04 01:00:07.000000000 -0500
@@ -55,7 +55,7 @@ void cifs_dfs_release_automount_timer(vo
  * i.e. strips from UNC trailing path that is not part of share
  * name and fixup missing '\' in the begining of DFS node refferal
  * if neccessary.
- * Returns pointer to share name on success or NULL on error.
+ * Returns pointer to share name on success or ERR_PTR on error.
  * Caller is responsible for freeing returned string.
  */
 static char *cifs_get_share_name(const char *node_name)
@@ -68,7 +68,7 @@ static char *cifs_get_share_name(const c
 	UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
 			 GFP_KERNEL);
 	if (!UNC)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	/* get share name and server name */
 	if (node_name[1] != '\\') {
@@ -87,7 +87,7 @@ static char *cifs_get_share_name(const c
 		cERROR(1, ("%s: no server name end in node name: %s",
 			__func__, node_name));
 		kfree(UNC);
-		return NULL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	/* find sharename end */
@@ -133,6 +133,12 @@ char *cifs_compose_mount_options(const c
 		return ERR_PTR(-EINVAL);
 
 	*devname = cifs_get_share_name(ref->node_name);
+	if (IS_ERR(*devname)) {
+		rc = PTR_ERR(*devname);
+		*devname = NULL;
+		goto compose_mount_options_err;
+	}
+
 	rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
 	if (rc != 0) {
 		cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
diff -druNp linux-libre-2.6.30-gnu1/fs/cifs/cifsglob.h linux-libre-2.6.30.10-gnu1/fs/cifs/cifsglob.h
--- linux-libre-2.6.30-gnu1/fs/cifs/cifsglob.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/cifs/cifsglob.h	2009-12-04 01:00:07.000000000 -0500
@@ -544,9 +544,9 @@ require use of the stronger protocol */
 #define   CIFSSEC_MUST_LANMAN	0x10010
 #define   CIFSSEC_MUST_PLNTXT	0x20020
 #ifdef CONFIG_CIFS_UPCALL
-#define   CIFSSEC_MASK          0xAF0AF /* allows weak security but also krb5 */
+#define   CIFSSEC_MASK          0xBF0BF /* allows weak security but also krb5 */
 #else
-#define   CIFSSEC_MASK          0xA70A7 /* current flags supported if weak */
+#define   CIFSSEC_MASK          0xB70B7 /* current flags supported if weak */
 #endif /* UPCALL */
 #else /* do not allow weak pw hash */
 #ifdef CONFIG_CIFS_UPCALL
diff -druNp linux-libre-2.6.30-gnu1/fs/cifs/connect.c linux-libre-2.6.30.10-gnu1/fs/cifs/connect.c
--- linux-libre-2.6.30-gnu1/fs/cifs/connect.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/cifs/connect.c	2009-12-04 01:00:07.000000000 -0500
@@ -2563,11 +2563,20 @@ remote_path_check:
 
 			if (mount_data != mount_data_global)
 				kfree(mount_data);
+
 			mount_data = cifs_compose_mount_options(
 					cifs_sb->mountdata, full_path + 1,
 					referrals, &fake_devname);
-			kfree(fake_devname);
+
 			free_dfs_info_array(referrals, num_referrals);
+			kfree(fake_devname);
+			kfree(full_path);
+
+			if (IS_ERR(mount_data)) {
+				rc = PTR_ERR(mount_data);
+				mount_data = NULL;
+				goto mount_fail_check;
+			}
 
 			if (tcon)
 				cifs_put_tcon(tcon);
@@ -2575,8 +2584,6 @@ remote_path_check:
 				cifs_put_smb_ses(pSesInfo);
 
 			cleanup_volume_info(&volume_info);
-			FreeXid(xid);
-			kfree(full_path);
 			referral_walks_count++;
 			goto try_mount_again;
 		}
@@ -2745,6 +2752,7 @@ CIFSTCon(unsigned int xid, struct cifsSe
 		strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
 
 		/* mostly informational -- no need to fail on error here */
+		kfree(tcon->nativeFileSystem);
 		tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
 						      bytes_left, is_unicode,
 						      nls_codepage);
diff -druNp linux-libre-2.6.30-gnu1/fs/cifs/dir.c linux-libre-2.6.30.10-gnu1/fs/cifs/dir.c
--- linux-libre-2.6.30-gnu1/fs/cifs/dir.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/cifs/dir.c	2009-12-04 01:00:07.000000000 -0500
@@ -641,6 +641,15 @@ cifs_lookup(struct inode *parent_dir_ino
 			}
 	}
 
+	/*
+	 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
+	 * the VFS handle the create.
+	 */
+	if (nd->flags & LOOKUP_EXCL) {
+		d_instantiate(direntry, NULL);
+		return 0;
+	}
+
 	/* can not grab the rename sem here since it would
 	deadlock in the cases (beginning of sys_rename itself)
 	in which we already have the sb rename sem */
diff -druNp linux-libre-2.6.30-gnu1/fs/cifs/file.c linux-libre-2.6.30.10-gnu1/fs/cifs/file.c
--- linux-libre-2.6.30-gnu1/fs/cifs/file.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/cifs/file.c	2009-12-04 01:00:07.000000000 -0500
@@ -491,9 +491,9 @@ static int cifs_reopen_file(struct file
 		return -EBADF;
 
 	xid = GetXid();
-	mutex_unlock(&pCifsFile->fh_mutex);
+	mutex_lock(&pCifsFile->fh_mutex);
 	if (!pCifsFile->invalidHandle) {
-		mutex_lock(&pCifsFile->fh_mutex);
+		mutex_unlock(&pCifsFile->fh_mutex);
 		FreeXid(xid);
 		return 0;
 	}
@@ -524,7 +524,7 @@ static int cifs_reopen_file(struct file
 	if (full_path == NULL) {
 		rc = -ENOMEM;
 reopen_error_exit:
-		mutex_lock(&pCifsFile->fh_mutex);
+		mutex_unlock(&pCifsFile->fh_mutex);
 		FreeXid(xid);
 		return rc;
 	}
@@ -566,14 +566,14 @@ reopen_error_exit:
 			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
 				CIFS_MOUNT_MAP_SPECIAL_CHR);
 	if (rc) {
-		mutex_lock(&pCifsFile->fh_mutex);
+		mutex_unlock(&pCifsFile->fh_mutex);
 		cFYI(1, ("cifs_open returned 0x%x", rc));
 		cFYI(1, ("oplock: %d", oplock));
 	} else {
 reopen_success:
 		pCifsFile->netfid = netfid;
 		pCifsFile->invalidHandle = false;
-		mutex_lock(&pCifsFile->fh_mutex);
+		mutex_unlock(&pCifsFile->fh_mutex);
 		pCifsInode = CIFS_I(inode);
 		if (pCifsInode) {
 			if (can_flush) {
diff -druNp linux-libre-2.6.30-gnu1/fs/compat_ioctl.c linux-libre-2.6.30.10-gnu1/fs/compat_ioctl.c
--- linux-libre-2.6.30-gnu1/fs/compat_ioctl.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/compat_ioctl.c	2009-12-04 01:00:07.000000000 -0500
@@ -1915,6 +1915,7 @@ COMPATIBLE_IOCTL(FIONCLEX)
 COMPATIBLE_IOCTL(FIOASYNC)
 COMPATIBLE_IOCTL(FIONBIO)
 COMPATIBLE_IOCTL(FIONREAD)  /* This is also TIOCINQ */
+COMPATIBLE_IOCTL(FS_IOC_FIEMAP)
 /* 0x00 */
 COMPATIBLE_IOCTL(FIBMAP)
 COMPATIBLE_IOCTL(FIGETBSZ)
diff -druNp linux-libre-2.6.30-gnu1/fs/ecryptfs/keystore.c linux-libre-2.6.30.10-gnu1/fs/ecryptfs/keystore.c
--- linux-libre-2.6.30-gnu1/fs/ecryptfs/keystore.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/ecryptfs/keystore.c	2009-12-04 01:00:07.000000000 -0500
@@ -1303,6 +1303,13 @@ parse_tag_3_packet(struct ecryptfs_crypt
 	}
 	(*new_auth_tok)->session_key.encrypted_key_size =
 		(body_size - (ECRYPTFS_SALT_SIZE + 5));
+	if ((*new_auth_tok)->session_key.encrypted_key_size
+	    > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
+		printk(KERN_WARNING "Tag 3 packet contains key larger "
+		       "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n");
+		rc = -EINVAL;
+		goto out_free;
+	}
 	if (unlikely(data[(*packet_size)++] != 0x04)) {
 		printk(KERN_WARNING "Unknown version number [%d]\n",
 		       data[(*packet_size) - 1]);
@@ -1449,6 +1456,12 @@ parse_tag_11_packet(unsigned char *data,
 		rc = -EINVAL;
 		goto out;
 	}
+	if (unlikely((*tag_11_contents_size) > max_contents_bytes)) {
+		printk(KERN_ERR "Literal data section in tag 11 packet exceeds "
+		       "expected size\n");
+		rc = -EINVAL;
+		goto out;
+	}
 	if (data[(*packet_size)++] != 0x62) {
 		printk(KERN_WARNING "Unrecognizable packet\n");
 		rc = -EINVAL;
diff -druNp linux-libre-2.6.30-gnu1/fs/eventpoll.c linux-libre-2.6.30.10-gnu1/fs/eventpoll.c
--- linux-libre-2.6.30-gnu1/fs/eventpoll.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/eventpoll.c	2009-12-04 01:00:07.000000000 -0500
@@ -98,7 +98,7 @@ struct epoll_filefd {
 struct nested_call_node {
 	struct list_head llink;
 	void *cookie;
-	int cpu;
+	void *ctx;
 };
 
 /*
@@ -317,17 +317,17 @@ static void ep_nested_calls_init(struct
  * @nproc: Nested call core function pointer.
  * @priv: Opaque data to be passed to the @nproc callback.
  * @cookie: Cookie to be used to identify this nested call.
+ * @ctx: This instance context.
  *
  * Returns: Returns the code returned by the @nproc callback, or -1 if
  *          the maximum recursion limit has been exceeded.
  */
 static int ep_call_nested(struct nested_calls *ncalls, int max_nests,
 			  int (*nproc)(void *, void *, int), void *priv,
-			  void *cookie)
+			  void *cookie, void *ctx)
 {
 	int error, call_nests = 0;
 	unsigned long flags;
-	int this_cpu = get_cpu();
 	struct list_head *lsthead = &ncalls->tasks_call_list;
 	struct nested_call_node *tncur;
 	struct nested_call_node tnode;
@@ -340,7 +340,7 @@ static int ep_call_nested(struct nested_
 	 * very much limited.
 	 */
 	list_for_each_entry(tncur, lsthead, llink) {
-		if (tncur->cpu == this_cpu &&
+		if (tncur->ctx == ctx &&
 		    (tncur->cookie == cookie || ++call_nests > max_nests)) {
 			/*
 			 * Ops ... loop detected or maximum nest level reached.
@@ -352,7 +352,7 @@ static int ep_call_nested(struct nested_
 	}
 
 	/* Add the current task and cookie to the list */
-	tnode.cpu = this_cpu;
+	tnode.ctx = ctx;
 	tnode.cookie = cookie;
 	list_add(&tnode.llink, lsthead);
 
@@ -364,10 +364,9 @@ static int ep_call_nested(struct nested_
 	/* Remove the current task from the list */
 	spin_lock_irqsave(&ncalls->lock, flags);
 	list_del(&tnode.llink);
- out_unlock:
+out_unlock:
 	spin_unlock_irqrestore(&ncalls->lock, flags);
 
-	put_cpu();
 	return error;
 }
 
@@ -408,8 +407,12 @@ static int ep_poll_wakeup_proc(void *pri
  */
 static void ep_poll_safewake(wait_queue_head_t *wq)
 {
+	int this_cpu = get_cpu();
+
 	ep_call_nested(&poll_safewake_ncalls, EP_MAX_NESTS,
-		       ep_poll_wakeup_proc, NULL, wq);
+		       ep_poll_wakeup_proc, NULL, wq, (void *) (long) this_cpu);
+
+	put_cpu();
 }
 
 /*
@@ -663,7 +666,7 @@ static unsigned int ep_eventpoll_poll(st
 	 * could re-enter here.
 	 */
 	pollflags = ep_call_nested(&poll_readywalk_ncalls, EP_MAX_NESTS,
-				   ep_poll_readyevents_proc, ep, ep);
+				   ep_poll_readyevents_proc, ep, ep, current);
 
 	return pollflags != -1 ? pollflags : 0;
 }
diff -druNp linux-libre-2.6.30-gnu1/fs/exec.c linux-libre-2.6.30.10-gnu1/fs/exec.c
--- linux-libre-2.6.30-gnu1/fs/exec.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/exec.c	2009-12-04 01:00:07.000000000 -0500
@@ -677,8 +677,8 @@ exit:
 }
 EXPORT_SYMBOL(open_exec);
 
-int kernel_read(struct file *file, unsigned long offset,
-	char *addr, unsigned long count)
+int kernel_read(struct file *file, loff_t offset,
+		char *addr, unsigned long count)
 {
 	mm_segment_t old_fs;
 	loff_t pos = offset;
diff -druNp linux-libre-2.6.30-gnu1/fs/fs-writeback.c linux-libre-2.6.30.10-gnu1/fs/fs-writeback.c
--- linux-libre-2.6.30-gnu1/fs/fs-writeback.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/fs-writeback.c	2009-12-04 01:00:07.000000000 -0500
@@ -289,7 +289,6 @@ __sync_single_inode(struct inode *inode,
 	int ret;
 
 	BUG_ON(inode->i_state & I_SYNC);
-	WARN_ON(inode->i_state & I_NEW);
 
 	/* Set I_SYNC, reset I_DIRTY */
 	dirty = inode->i_state & I_DIRTY;
@@ -314,7 +313,6 @@ __sync_single_inode(struct inode *inode,
 	}
 
 	spin_lock(&inode_lock);
-	WARN_ON(inode->i_state & I_NEW);
 	inode->i_state &= ~I_SYNC;
 	if (!(inode->i_state & I_FREEING)) {
 		if (!(inode->i_state & I_DIRTY) &&
diff -druNp linux-libre-2.6.30-gnu1/fs/fuse/dev.c linux-libre-2.6.30.10-gnu1/fs/fuse/dev.c
--- linux-libre-2.6.30-gnu1/fs/fuse/dev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/fuse/dev.c	2009-12-04 01:00:07.000000000 -0500
@@ -904,7 +904,7 @@ static ssize_t fuse_dev_write(struct kio
 			       unsigned long nr_segs, loff_t pos)
 {
 	int err;
-	unsigned nbytes = iov_length(iov, nr_segs);
+	size_t nbytes = iov_length(iov, nr_segs);
 	struct fuse_req *req;
 	struct fuse_out_header oh;
 	struct fuse_copy_state cs;
diff -druNp linux-libre-2.6.30-gnu1/fs/fuse/file.c linux-libre-2.6.30.10-gnu1/fs/fuse/file.c
--- linux-libre-2.6.30-gnu1/fs/fuse/file.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/fuse/file.c	2009-12-04 01:00:07.000000000 -0500
@@ -1867,7 +1867,7 @@ static unsigned fuse_file_poll(struct fi
 
 	req = fuse_get_req(fc);
 	if (IS_ERR(req))
-		return PTR_ERR(req);
+		return POLLERR;
 
 	req->in.h.opcode = FUSE_POLL;
 	req->in.h.nodeid = get_node_id(inode);
diff -druNp linux-libre-2.6.30-gnu1/fs/hugetlbfs/inode.c linux-libre-2.6.30.10-gnu1/fs/hugetlbfs/inode.c
--- linux-libre-2.6.30-gnu1/fs/hugetlbfs/inode.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/hugetlbfs/inode.c	2009-12-04 01:00:07.000000000 -0500
@@ -934,26 +934,28 @@ static int can_do_hugetlb_shm(void)
 	return capable(CAP_IPC_LOCK) || in_group_p(sysctl_hugetlb_shm_group);
 }
 
-struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag)
+struct file *hugetlb_file_setup(const char *name, size_t size, int acctflag,
+						struct user_struct **user)
 {
 	int error = -ENOMEM;
-	int unlock_shm = 0;
 	struct file *file;
 	struct inode *inode;
 	struct dentry *dentry, *root;
 	struct qstr quick_string;
-	struct user_struct *user = current_user();
 
+	*user = NULL;
 	if (!hugetlbfs_vfsmount)
 		return ERR_PTR(-ENOENT);
 
 	if (!can_do_hugetlb_shm()) {
-		if (user_shm_lock(size, user)) {
-			unlock_shm = 1;
+		*user = current_user();
+		if (user_shm_lock(size, *user)) {
 			WARN_ONCE(1,
 			  "Using mlock ulimits for SHM_HUGETLB deprecated\n");
-		} else
+		} else {
+			*user = NULL;
 			return ERR_PTR(-EPERM);
+		}
 	}
 
 	root = hugetlbfs_vfsmount->mnt_root;
@@ -994,8 +996,10 @@ out_inode:
 out_dentry:
 	dput(dentry);
 out_shm_unlock:
-	if (unlock_shm)
-		user_shm_unlock(size, user);
+	if (*user) {
+		user_shm_unlock(size, *user);
+		*user = NULL;
+	}
 	return ERR_PTR(error);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/fs/inode.c linux-libre-2.6.30.10-gnu1/fs/inode.c
--- linux-libre-2.6.30-gnu1/fs/inode.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/inode.c	2009-12-04 01:00:07.000000000 -0500
@@ -118,12 +118,11 @@ static void wake_up_inode(struct inode *
  * These are initializations that need to be done on every inode
  * allocation as the fields are not initialised by slab allocation.
  */
-struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
+int inode_init_always(struct super_block *sb, struct inode *inode)
 {
 	static const struct address_space_operations empty_aops;
 	static struct inode_operations empty_iops;
 	static const struct file_operations empty_fops;
-
 	struct address_space *const mapping = &inode->i_data;
 
 	inode->i_sb = sb;
@@ -150,7 +149,7 @@ struct inode *inode_init_always(struct s
 	inode->dirtied_when = 0;
 
 	if (security_inode_alloc(inode))
-		goto out_free_inode;
+		goto out;
 
 	/* allocate and initialize an i_integrity */
 	if (ima_inode_alloc(inode))
@@ -189,16 +188,12 @@ struct inode *inode_init_always(struct s
 	inode->i_private = NULL;
 	inode->i_mapping = mapping;
 
-	return inode;
+	return 0;
 
 out_free_security:
 	security_inode_free(inode);
-out_free_inode:
-	if (inode->i_sb->s_op->destroy_inode)
-		inode->i_sb->s_op->destroy_inode(inode);
-	else
-		kmem_cache_free(inode_cachep, (inode));
-	return NULL;
+out:
+	return -ENOMEM;
 }
 EXPORT_SYMBOL(inode_init_always);
 
@@ -211,23 +206,36 @@ static struct inode *alloc_inode(struct
 	else
 		inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL);
 
-	if (inode)
-		return inode_init_always(sb, inode);
-	return NULL;
+	if (!inode)
+		return NULL;
+
+	if (unlikely(inode_init_always(sb, inode))) {
+		if (inode->i_sb->s_op->destroy_inode)
+			inode->i_sb->s_op->destroy_inode(inode);
+		else
+			kmem_cache_free(inode_cachep, inode);
+		return NULL;
+	}
+
+	return inode;
 }
 
-void destroy_inode(struct inode *inode)
+void __destroy_inode(struct inode *inode)
 {
 	BUG_ON(inode_has_buffers(inode));
 	ima_inode_free(inode);
 	security_inode_free(inode);
+}
+EXPORT_SYMBOL(__destroy_inode);
+
+void destroy_inode(struct inode *inode)
+{
+	__destroy_inode(inode);
 	if (inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
 	else
 		kmem_cache_free(inode_cachep, (inode));
 }
-EXPORT_SYMBOL(destroy_inode);
-
 
 /*
  * These are initializations that only need to be done
@@ -664,13 +672,15 @@ void unlock_new_inode(struct inode *inod
 	}
 #endif
 	/*
-	 * This is special!  We do not need the spinlock
-	 * when clearing I_LOCK, because we're guaranteed
-	 * that nobody else tries to do anything about the
-	 * state of the inode when it is locked, as we
-	 * just created it (so there can be no old holders
-	 * that haven't tested I_LOCK).
+	 * This is special!  We do not need the spinlock when clearing I_LOCK,
+	 * because we're guaranteed that nobody else tries to do anything about
+	 * the state of the inode when it is locked, as we just created it (so
+	 * there can be no old holders that haven't tested I_LOCK).
+	 * However we must emit the memory barrier so that other CPUs reliably
+	 * see the clearing of I_LOCK after the other inode initialisation has
+	 * completed.
 	 */
+	smp_mb();
 	WARN_ON((inode->i_state & (I_LOCK|I_NEW)) != (I_LOCK|I_NEW));
 	inode->i_state &= ~(I_LOCK|I_NEW);
 	wake_up_inode(inode);
diff -druNp linux-libre-2.6.30-gnu1/fs/jffs2/wbuf.c linux-libre-2.6.30.10-gnu1/fs/jffs2/wbuf.c
--- linux-libre-2.6.30-gnu1/fs/jffs2/wbuf.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/jffs2/wbuf.c	2009-12-04 01:00:07.000000000 -0500
@@ -1268,10 +1268,20 @@ int jffs2_nor_wbuf_flash_setup(struct jf
 	if (!c->wbuf)
 		return -ENOMEM;
 
+#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
+	c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
+	if (!c->wbuf_verify) {
+		kfree(c->wbuf);
+		return -ENOMEM;
+	}
+#endif
 	return 0;
 }
 
 void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
+#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
+	kfree(c->wbuf_verify);
+#endif
 	kfree(c->wbuf);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/fs/jfs/jfs_extent.c linux-libre-2.6.30.10-gnu1/fs/jfs/jfs_extent.c
--- linux-libre-2.6.30-gnu1/fs/jfs/jfs_extent.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/jfs/jfs_extent.c	2009-12-04 01:00:07.000000000 -0500
@@ -391,6 +391,7 @@ int extHint(struct inode *ip, s64 offset
 		}
 		XADaddress(xp, xaddr);
 		XADlength(xp, xlen);
+		XADoffset(xp, prev);
 		/*
 		 * only preserve the abnr flag within the xad flags
 		 * of the returned hint.
diff -druNp linux-libre-2.6.30-gnu1/fs/Kconfig linux-libre-2.6.30.10-gnu1/fs/Kconfig
--- linux-libre-2.6.30-gnu1/fs/Kconfig	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/Kconfig	2009-12-04 01:00:07.000000000 -0500
@@ -39,6 +39,13 @@ config FS_POSIX_ACL
 	bool
 	default n
 
+source "fs/xfs/Kconfig"
+source "fs/gfs2/Kconfig"
+source "fs/ocfs2/Kconfig"
+source "fs/btrfs/Kconfig"
+
+endif # BLOCK
+
 config FILE_LOCKING
 	bool "Enable POSIX file locking API" if EMBEDDED
 	default y
@@ -47,13 +54,6 @@ config FILE_LOCKING
           for filesystems like NFS and for the flock() system
           call. Disabling this option saves about 11k.
 
-source "fs/xfs/Kconfig"
-source "fs/gfs2/Kconfig"
-source "fs/ocfs2/Kconfig"
-source "fs/btrfs/Kconfig"
-
-endif # BLOCK
-
 source "fs/notify/Kconfig"
 
 source "fs/quota/Kconfig"
diff -druNp linux-libre-2.6.30-gnu1/fs/nfs/direct.c linux-libre-2.6.30.10-gnu1/fs/nfs/direct.c
--- linux-libre-2.6.30-gnu1/fs/nfs/direct.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nfs/direct.c	2009-12-04 01:00:07.000000000 -0500
@@ -255,7 +255,7 @@ static void nfs_direct_read_release(void
 
 	if (put_dreq(dreq))
 		nfs_direct_complete(dreq);
-	nfs_readdata_release(calldata);
+	nfs_readdata_free(data);
 }
 
 static const struct rpc_call_ops nfs_read_direct_ops = {
@@ -311,14 +311,14 @@ static ssize_t nfs_direct_read_schedule_
 					data->npages, 1, 0, data->pagevec, NULL);
 		up_read(&current->mm->mmap_sem);
 		if (result < 0) {
-			nfs_readdata_release(data);
+			nfs_readdata_free(data);
 			break;
 		}
 		if ((unsigned)result < data->npages) {
 			bytes = result * PAGE_SIZE;
 			if (bytes <= pgbase) {
 				nfs_direct_release_pages(data->pagevec, result);
-				nfs_readdata_release(data);
+				nfs_readdata_free(data);
 				break;
 			}
 			bytes -= pgbase;
@@ -331,7 +331,7 @@ static ssize_t nfs_direct_read_schedule_
 		data->inode = inode;
 		data->cred = msg.rpc_cred;
 		data->args.fh = NFS_FH(inode);
-		data->args.context = get_nfs_open_context(ctx);
+		data->args.context = ctx;
 		data->args.offset = pos;
 		data->args.pgbase = pgbase;
 		data->args.pages = data->pagevec;
@@ -438,7 +438,7 @@ static void nfs_direct_free_writedata(st
 		struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages);
 		list_del(&data->pages);
 		nfs_direct_release_pages(data->pagevec, data->npages);
-		nfs_writedata_release(data);
+		nfs_writedata_free(data);
 	}
 }
 
@@ -531,7 +531,7 @@ static void nfs_direct_commit_release(vo
 
 	dprintk("NFS: %5u commit returned %d\n", data->task.tk_pid, status);
 	nfs_direct_write_complete(dreq, data->inode);
-	nfs_commitdata_release(calldata);
+	nfs_commit_free(data);
 }
 
 static const struct rpc_call_ops nfs_commit_direct_ops = {
@@ -564,7 +564,7 @@ static void nfs_direct_commit_schedule(s
 	data->args.fh = NFS_FH(data->inode);
 	data->args.offset = 0;
 	data->args.count = 0;
-	data->args.context = get_nfs_open_context(dreq->ctx);
+	data->args.context = dreq->ctx;
 	data->res.count = 0;
 	data->res.fattr = &data->fattr;
 	data->res.verf = &data->verf;
@@ -725,14 +725,14 @@ static ssize_t nfs_direct_write_schedule
 					data->npages, 0, 0, data->pagevec, NULL);
 		up_read(&current->mm->mmap_sem);
 		if (result < 0) {
-			nfs_writedata_release(data);
+			nfs_writedata_free(data);
 			break;
 		}
 		if ((unsigned)result < data->npages) {
 			bytes = result * PAGE_SIZE;
 			if (bytes <= pgbase) {
 				nfs_direct_release_pages(data->pagevec, result);
-				nfs_writedata_release(data);
+				nfs_writedata_free(data);
 				break;
 			}
 			bytes -= pgbase;
@@ -747,7 +747,7 @@ static ssize_t nfs_direct_write_schedule
 		data->inode = inode;
 		data->cred = msg.rpc_cred;
 		data->args.fh = NFS_FH(inode);
-		data->args.context = get_nfs_open_context(ctx);
+		data->args.context = ctx;
 		data->args.offset = pos;
 		data->args.pgbase = pgbase;
 		data->args.pages = data->pagevec;
diff -druNp linux-libre-2.6.30-gnu1/fs/nfs/read.c linux-libre-2.6.30.10-gnu1/fs/nfs/read.c
--- linux-libre-2.6.30-gnu1/fs/nfs/read.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nfs/read.c	2009-12-04 01:00:07.000000000 -0500
@@ -59,17 +59,15 @@ struct nfs_read_data *nfs_readdata_alloc
 	return p;
 }
 
-static void nfs_readdata_free(struct nfs_read_data *p)
+void nfs_readdata_free(struct nfs_read_data *p)
 {
 	if (p && (p->pagevec != &p->page_array[0]))
 		kfree(p->pagevec);
 	mempool_free(p, nfs_rdata_mempool);
 }
 
-void nfs_readdata_release(void *data)
+static void nfs_readdata_release(struct nfs_read_data *rdata)
 {
-	struct nfs_read_data *rdata = data;
-
 	put_nfs_open_context(rdata->args.context);
 	nfs_readdata_free(rdata);
 }
diff -druNp linux-libre-2.6.30-gnu1/fs/nfs/write.c linux-libre-2.6.30.10-gnu1/fs/nfs/write.c
--- linux-libre-2.6.30-gnu1/fs/nfs/write.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nfs/write.c	2009-12-04 01:00:07.000000000 -0500
@@ -84,17 +84,15 @@ struct nfs_write_data *nfs_writedata_all
 	return p;
 }
 
-static void nfs_writedata_free(struct nfs_write_data *p)
+void nfs_writedata_free(struct nfs_write_data *p)
 {
 	if (p && (p->pagevec != &p->page_array[0]))
 		kfree(p->pagevec);
 	mempool_free(p, nfs_wdata_mempool);
 }
 
-void nfs_writedata_release(void *data)
+static void nfs_writedata_release(struct nfs_write_data *wdata)
 {
-	struct nfs_write_data *wdata = data;
-
 	put_nfs_open_context(wdata->args.context);
 	nfs_writedata_free(wdata);
 }
diff -druNp linux-libre-2.6.30-gnu1/fs/nfsd/vfs.c linux-libre-2.6.30.10-gnu1/fs/nfsd/vfs.c
--- linux-libre-2.6.30-gnu1/fs/nfsd/vfs.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nfsd/vfs.c	2009-12-04 01:00:07.000000000 -0500
@@ -677,7 +677,6 @@ __be32
 nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
 			int access, struct file **filp)
 {
-	const struct cred *cred = current_cred();
 	struct dentry	*dentry;
 	struct inode	*inode;
 	int		flags = O_RDONLY|O_LARGEFILE;
@@ -732,7 +731,7 @@ nfsd_open(struct svc_rqst *rqstp, struct
 		vfs_dq_init(inode);
 	}
 	*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
-			    flags, cred);
+			    flags, current_cred());
 	if (IS_ERR(*filp))
 		host_err = PTR_ERR(*filp);
 out_nfserr:
diff -druNp linux-libre-2.6.30-gnu1/fs/nilfs2/btnode.c linux-libre-2.6.30.10-gnu1/fs/nilfs2/btnode.c
--- linux-libre-2.6.30-gnu1/fs/nilfs2/btnode.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nilfs2/btnode.c	2009-12-04 01:00:07.000000000 -0500
@@ -36,6 +36,7 @@
 
 void nilfs_btnode_cache_init_once(struct address_space *btnc)
 {
+	memset(btnc, 0, sizeof(*btnc));
 	INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC);
 	spin_lock_init(&btnc->tree_lock);
 	INIT_LIST_HEAD(&btnc->private_list);
@@ -206,6 +207,7 @@ int nilfs_btnode_prepare_change_key(stru
 		 * We cannot call radix_tree_preload for the kernels older
 		 * than 2.6.23, because it is not exported for modules.
 		 */
+retry:
 		err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
 		if (err)
 			goto failed_unlock;
@@ -216,7 +218,6 @@ int nilfs_btnode_prepare_change_key(stru
 				       (unsigned long long)oldkey,
 				       (unsigned long long)newkey);
 
-retry:
 		spin_lock_irq(&btnc->tree_lock);
 		err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
 		spin_unlock_irq(&btnc->tree_lock);
diff -druNp linux-libre-2.6.30-gnu1/fs/nilfs2/cpfile.c linux-libre-2.6.30.10-gnu1/fs/nilfs2/cpfile.c
--- linux-libre-2.6.30-gnu1/fs/nilfs2/cpfile.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nilfs2/cpfile.c	2009-12-04 01:00:07.000000000 -0500
@@ -311,7 +311,7 @@ int nilfs_cpfile_delete_checkpoints(stru
 		ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh);
 		if (ret < 0) {
 			if (ret != -ENOENT)
-				goto out_header;
+				break;
 			/* skip hole */
 			ret = 0;
 			continue;
@@ -344,7 +344,7 @@ int nilfs_cpfile_delete_checkpoints(stru
 					continue;
 				printk(KERN_ERR "%s: cannot delete block\n",
 				       __func__);
-				goto out_header;
+				break;
 			}
 		}
 
@@ -362,7 +362,6 @@ int nilfs_cpfile_delete_checkpoints(stru
 		kunmap_atomic(kaddr, KM_USER0);
 	}
 
- out_header:
 	brelse(header_bh);
 
  out_sem:
diff -druNp linux-libre-2.6.30-gnu1/fs/nilfs2/dat.c linux-libre-2.6.30.10-gnu1/fs/nilfs2/dat.c
--- linux-libre-2.6.30-gnu1/fs/nilfs2/dat.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nilfs2/dat.c	2009-12-04 01:00:07.000000000 -0500
@@ -149,15 +149,6 @@ void nilfs_dat_commit_start(struct inode
 	entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr,
 					     req->pr_entry_bh, kaddr);
 	entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat));
-	if (entry->de_blocknr != cpu_to_le64(0) ||
-	    entry->de_end != cpu_to_le64(NILFS_CNO_MAX)) {
-		printk(KERN_CRIT
-		       "%s: vbn = %llu, start = %llu, end = %llu, pbn = %llu\n",
-		       __func__, (unsigned long long)req->pr_entry_nr,
-		       (unsigned long long)le64_to_cpu(entry->de_start),
-		       (unsigned long long)le64_to_cpu(entry->de_end),
-		       (unsigned long long)le64_to_cpu(entry->de_blocknr));
-	}
 	entry->de_blocknr = cpu_to_le64(blocknr);
 	kunmap_atomic(kaddr, KM_USER0);
 
diff -druNp linux-libre-2.6.30-gnu1/fs/nilfs2/segment.c linux-libre-2.6.30.10-gnu1/fs/nilfs2/segment.c
--- linux-libre-2.6.30-gnu1/fs/nilfs2/segment.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/nilfs2/segment.c	2009-12-04 01:00:07.000000000 -0500
@@ -1846,26 +1846,13 @@ static int nilfs_segctor_write(struct ni
 		err = nilfs_segbuf_write(segbuf, &wi);
 
 		res = nilfs_segbuf_wait(segbuf, &wi);
-		err = unlikely(err) ? : res;
-		if (unlikely(err))
+		err = err ? : res;
+		if (err)
 			return err;
 	}
 	return 0;
 }
 
-static int nilfs_page_has_uncleared_buffer(struct page *page)
-{
-	struct buffer_head *head, *bh;
-
-	head = bh = page_buffers(page);
-	do {
-		if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers))
-			return 1;
-		bh = bh->b_this_page;
-	} while (bh != head);
-	return 0;
-}
-
 static void __nilfs_end_page_io(struct page *page, int err)
 {
 	if (!err) {
@@ -1889,13 +1876,26 @@ static void nilfs_end_page_io(struct pag
 	if (!page)
 		return;
 
-	if (buffer_nilfs_node(page_buffers(page)) &&
-	    nilfs_page_has_uncleared_buffer(page))
-		/* For b-tree node pages, this function may be called twice
-		   or more because they might be split in a segment.
-		   This check assures that cleanup has been done for all
-		   buffers in a split btnode page. */
+	if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) {
+		/*
+		 * For b-tree node pages, this function may be called twice
+		 * or more because they might be split in a segment.
+		 */
+		if (PageDirty(page)) {
+			/*
+			 * For pages holding split b-tree node buffers, dirty
+			 * flag on the buffers may be cleared discretely.
+			 * In that case, the page is once redirtied for
+			 * remaining buffers, and it must be cancelled if
+			 * all the buffers get cleaned later.
+			 */
+			lock_page(page);
+			if (nilfs_page_buffers_clean(page))
+				__nilfs_clear_page_dirty(page);
+			unlock_page(page);
+		}
 		return;
+	}
 
 	__nilfs_end_page_io(page, err);
 }
@@ -1957,7 +1957,7 @@ static void nilfs_segctor_abort_write(st
 			}
 			if (bh->b_page != fs_page) {
 				nilfs_end_page_io(fs_page, err);
-				if (unlikely(fs_page == failed_page))
+				if (fs_page && fs_page == failed_page)
 					goto done;
 				fs_page = bh->b_page;
 			}
diff -druNp linux-libre-2.6.30-gnu1/fs/ocfs2/aops.c linux-libre-2.6.30.10-gnu1/fs/ocfs2/aops.c
--- linux-libre-2.6.30-gnu1/fs/ocfs2/aops.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/ocfs2/aops.c	2009-12-04 01:00:07.000000000 -0500
@@ -894,18 +894,17 @@ struct ocfs2_write_cluster_desc {
 	 */
 	unsigned	c_new;
 	unsigned	c_unwritten;
+	unsigned	c_needs_zero;
 };
 
-static inline int ocfs2_should_zero_cluster(struct ocfs2_write_cluster_desc *d)
-{
-	return d->c_new || d->c_unwritten;
-}
-
 struct ocfs2_write_ctxt {
 	/* Logical cluster position / len of write */
 	u32				w_cpos;
 	u32				w_clen;
 
+	/* First cluster allocated in a nonsparse extend */
+	u32				w_first_new_cpos;
+
 	struct ocfs2_write_cluster_desc	w_desc[OCFS2_MAX_CLUSTERS_PER_PAGE];
 
 	/*
@@ -983,6 +982,7 @@ static int ocfs2_alloc_write_ctxt(struct
 		return -ENOMEM;
 
 	wc->w_cpos = pos >> osb->s_clustersize_bits;
+	wc->w_first_new_cpos = UINT_MAX;
 	cend = (pos + len - 1) >> osb->s_clustersize_bits;
 	wc->w_clen = cend - wc->w_cpos + 1;
 	get_bh(di_bh);
@@ -1217,20 +1217,18 @@ out:
  */
 static int ocfs2_write_cluster(struct address_space *mapping,
 			       u32 phys, unsigned int unwritten,
+			       unsigned int should_zero,
 			       struct ocfs2_alloc_context *data_ac,
 			       struct ocfs2_alloc_context *meta_ac,
 			       struct ocfs2_write_ctxt *wc, u32 cpos,
 			       loff_t user_pos, unsigned user_len)
 {
-	int ret, i, new, should_zero = 0;
+	int ret, i, new;
 	u64 v_blkno, p_blkno;
 	struct inode *inode = mapping->host;
 	struct ocfs2_extent_tree et;
 
 	new = phys == 0 ? 1 : 0;
-	if (new || unwritten)
-		should_zero = 1;
-
 	if (new) {
 		u32 tmp_pos;
 
@@ -1341,7 +1339,9 @@ static int ocfs2_write_cluster_by_desc(s
 			local_len = osb->s_clustersize - cluster_off;
 
 		ret = ocfs2_write_cluster(mapping, desc->c_phys,
-					  desc->c_unwritten, data_ac, meta_ac,
+					  desc->c_unwritten,
+					  desc->c_needs_zero,
+					  data_ac, meta_ac,
 					  wc, desc->c_cpos, pos, local_len);
 		if (ret) {
 			mlog_errno(ret);
@@ -1391,14 +1391,14 @@ static void ocfs2_set_target_boundaries(
 		 * newly allocated cluster.
 		 */
 		desc = &wc->w_desc[0];
-		if (ocfs2_should_zero_cluster(desc))
+		if (desc->c_needs_zero)
 			ocfs2_figure_cluster_boundaries(osb,
 							desc->c_cpos,
 							&wc->w_target_from,
 							NULL);
 
 		desc = &wc->w_desc[wc->w_clen - 1];
-		if (ocfs2_should_zero_cluster(desc))
+		if (desc->c_needs_zero)
 			ocfs2_figure_cluster_boundaries(osb,
 							desc->c_cpos,
 							NULL,
@@ -1466,13 +1466,28 @@ static int ocfs2_populate_write_desc(str
 			phys++;
 		}
 
+		/*
+		 * If w_first_new_cpos is < UINT_MAX, we have a non-sparse
+		 * file that got extended.  w_first_new_cpos tells us
+		 * where the newly allocated clusters are so we can
+		 * zero them.
+		 */
+		if (desc->c_cpos >= wc->w_first_new_cpos) {
+			BUG_ON(phys == 0);
+			desc->c_needs_zero = 1;
+		}
+
 		desc->c_phys = phys;
 		if (phys == 0) {
 			desc->c_new = 1;
+			desc->c_needs_zero = 1;
 			*clusters_to_alloc = *clusters_to_alloc + 1;
 		}
-		if (ext_flags & OCFS2_EXT_UNWRITTEN)
+
+		if (ext_flags & OCFS2_EXT_UNWRITTEN) {
 			desc->c_unwritten = 1;
+			desc->c_needs_zero = 1;
+		}
 
 		num_clusters--;
 	}
@@ -1632,10 +1647,13 @@ static int ocfs2_expand_nonsparse_inode(
 	if (newsize <= i_size_read(inode))
 		return 0;
 
-	ret = ocfs2_extend_no_holes(inode, newsize, newsize - len);
+	ret = ocfs2_extend_no_holes(inode, newsize, pos);
 	if (ret)
 		mlog_errno(ret);
 
+	wc->w_first_new_cpos =
+		ocfs2_clusters_for_bytes(inode->i_sb, i_size_read(inode));
+
 	return ret;
 }
 
@@ -1644,7 +1662,7 @@ int ocfs2_write_begin_nolock(struct addr
 			     struct page **pagep, void **fsdata,
 			     struct buffer_head *di_bh, struct page *mmap_page)
 {
-	int ret, credits = OCFS2_INODE_UPDATE_CREDITS;
+	int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS;
 	unsigned int clusters_to_alloc, extents_to_split;
 	struct ocfs2_write_ctxt *wc;
 	struct inode *inode = mapping->host;
@@ -1722,8 +1740,19 @@ int ocfs2_write_begin_nolock(struct addr
 
 	}
 
-	ocfs2_set_target_boundaries(osb, wc, pos, len,
-				    clusters_to_alloc + extents_to_split);
+	/*
+	 * We have to zero sparse allocated clusters, unwritten extent clusters,
+	 * and non-sparse clusters we just extended.  For non-sparse writes,
+	 * we know zeros will only be needed in the first and/or last cluster.
+	 */
+	if (clusters_to_alloc || extents_to_split ||
+	    (wc->w_clen && (wc->w_desc[0].c_needs_zero ||
+			    wc->w_desc[wc->w_clen - 1].c_needs_zero)))
+		cluster_of_pages = 1;
+	else
+		cluster_of_pages = 0;
+
+	ocfs2_set_target_boundaries(osb, wc, pos, len, cluster_of_pages);
 
 	handle = ocfs2_start_trans(osb, credits);
 	if (IS_ERR(handle)) {
@@ -1756,8 +1785,7 @@ int ocfs2_write_begin_nolock(struct addr
 	 * extent.
 	 */
 	ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
-					 clusters_to_alloc + extents_to_split,
-					 mmap_page);
+					 cluster_of_pages, mmap_page);
 	if (ret) {
 		mlog_errno(ret);
 		goto out_quota;
diff -druNp linux-libre-2.6.30-gnu1/fs/ocfs2/super.c linux-libre-2.6.30.10-gnu1/fs/ocfs2/super.c
--- linux-libre-2.6.30-gnu1/fs/ocfs2/super.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/ocfs2/super.c	2009-12-04 01:00:07.000000000 -0500
@@ -232,20 +232,24 @@ static int ocfs2_osb_dump(struct ocfs2_s
 			"%10s => Opts: 0x%lX  AtimeQuanta: %u\n", "Mount",
 			osb->s_mount_opt, osb->s_atime_quantum);
 
-	out += snprintf(buf + out, len - out,
-			"%10s => Stack: %s  Name: %*s  Version: %d.%d\n",
-			"Cluster",
-			(*osb->osb_cluster_stack == '\0' ?
-			 "o2cb" : osb->osb_cluster_stack),
-			cconn->cc_namelen, cconn->cc_name,
-			cconn->cc_version.pv_major, cconn->cc_version.pv_minor);
+	if (cconn) {
+		out += snprintf(buf + out, len - out,
+				"%10s => Stack: %s  Name: %*s  "
+				"Version: %d.%d\n", "Cluster",
+				(*osb->osb_cluster_stack == '\0' ?
+				 "o2cb" : osb->osb_cluster_stack),
+				cconn->cc_namelen, cconn->cc_name,
+				cconn->cc_version.pv_major,
+				cconn->cc_version.pv_minor);
+	}
 
 	spin_lock(&osb->dc_task_lock);
 	out += snprintf(buf + out, len - out,
 			"%10s => Pid: %d  Count: %lu  WakeSeq: %lu  "
 			"WorkSeq: %lu\n", "DownCnvt",
-			task_pid_nr(osb->dc_task), osb->blocked_lock_count,
-			osb->dc_wake_sequence, osb->dc_work_sequence);
+			(osb->dc_task ?  task_pid_nr(osb->dc_task) : -1),
+			osb->blocked_lock_count, osb->dc_wake_sequence,
+			osb->dc_work_sequence);
 	spin_unlock(&osb->dc_task_lock);
 
 	spin_lock(&osb->osb_lock);
@@ -265,14 +269,15 @@ static int ocfs2_osb_dump(struct ocfs2_s
 
 	out += snprintf(buf + out, len - out,
 			"%10s => Pid: %d  Interval: %lu  Needs: %d\n", "Commit",
-			task_pid_nr(osb->commit_task), osb->osb_commit_interval,
+			(osb->commit_task ? task_pid_nr(osb->commit_task) : -1),
+			osb->osb_commit_interval,
 			atomic_read(&osb->needs_checkpoint));
 
 	out += snprintf(buf + out, len - out,
-			"%10s => State: %d  NumTxns: %d  TxnId: %lu\n",
+			"%10s => State: %d  TxnId: %lu  NumTxns: %d\n",
 			"Journal", osb->journal->j_state,
-			atomic_read(&osb->journal->j_num_trans),
-			osb->journal->j_trans_id);
+			osb->journal->j_trans_id,
+			atomic_read(&osb->journal->j_num_trans));
 
 	out += snprintf(buf + out, len - out,
 			"%10s => GlobalAllocs: %d  LocalAllocs: %d  "
@@ -300,7 +305,6 @@ static int ocfs2_osb_dump(struct ocfs2_s
 
 	out += snprintf(buf + out, len - out, "%10s => %3s  %10s\n",
 			"Slots", "Num", "RecoGen");
-
 	for (i = 0; i < osb->max_slots; ++i) {
 		out += snprintf(buf + out, len - out,
 				"%10s  %c %3d  %10d\n",
diff -druNp linux-libre-2.6.30-gnu1/fs/partitions/check.c linux-libre-2.6.30.10-gnu1/fs/partitions/check.c
--- linux-libre-2.6.30-gnu1/fs/partitions/check.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/partitions/check.c	2009-12-04 01:00:07.000000000 -0500
@@ -426,7 +426,7 @@ struct hd_struct *add_partition(struct g
 	rcu_assign_pointer(ptbl->part[partno], p);
 
 	/* suppress uevent if the disk supresses it */
-	if (!dev_get_uevent_suppress(pdev))
+	if (!dev_get_uevent_suppress(ddev))
 		kobject_uevent(&pdev->kobj, KOBJ_ADD);
 
 	return p;
diff -druNp linux-libre-2.6.30-gnu1/fs/proc/base.c linux-libre-2.6.30.10-gnu1/fs/proc/base.c
--- linux-libre-2.6.30-gnu1/fs/proc/base.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/proc/base.c	2009-12-04 01:00:07.000000000 -0500
@@ -234,23 +234,20 @@ static int check_mem_permission(struct t
 
 struct mm_struct *mm_for_maps(struct task_struct *task)
 {
-	struct mm_struct *mm = get_task_mm(task);
-	if (!mm)
+	struct mm_struct *mm;
+
+	if (mutex_lock_killable(&task->cred_exec_mutex))
 		return NULL;
-	down_read(&mm->mmap_sem);
-	task_lock(task);
-	if (task->mm != mm)
-		goto out;
-	if (task->mm != current->mm &&
-	    __ptrace_may_access(task, PTRACE_MODE_READ) < 0)
-		goto out;
-	task_unlock(task);
+
+	mm = get_task_mm(task);
+	if (mm && mm != current->mm &&
+			!ptrace_may_access(task, PTRACE_MODE_READ)) {
+		mmput(mm);
+		mm = NULL;
+	}
+	mutex_unlock(&task->cred_exec_mutex);
+
 	return mm;
-out:
-	task_unlock(task);
-	up_read(&mm->mmap_sem);
-	mmput(mm);
-	return NULL;
 }
 
 static int proc_pid_cmdline(struct task_struct *task, char * buffer)
diff -druNp linux-libre-2.6.30-gnu1/fs/proc/kcore.c linux-libre-2.6.30.10-gnu1/fs/proc/kcore.c
--- linux-libre-2.6.30-gnu1/fs/proc/kcore.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/proc/kcore.c	2009-12-04 01:00:07.000000000 -0500
@@ -361,7 +361,13 @@ read_kcore(struct file *file, char __use
 				/* don't dump ioremap'd stuff! (TA) */
 				if (m->flags & VM_IOREMAP)
 					continue;
-				memcpy(elf_buf + (vmstart - start),
+				/*
+				 * we may access memory holes, then use
+				 * ex_table. checking return value just for
+				 * avoid warnings.
+				 */
+				vmsize = __copy_from_user_inatomic(
+					elf_buf + (vmstart - start),
 					(char *)vmstart, vmsize);
 			}
 			read_unlock(&vmlist_lock);
diff -druNp linux-libre-2.6.30-gnu1/fs/proc/task_mmu.c linux-libre-2.6.30.10-gnu1/fs/proc/task_mmu.c
--- linux-libre-2.6.30-gnu1/fs/proc/task_mmu.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/proc/task_mmu.c	2009-12-04 01:00:07.000000000 -0500
@@ -119,6 +119,7 @@ static void *m_start(struct seq_file *m,
 	mm = mm_for_maps(priv->task);
 	if (!mm)
 		return NULL;
+	down_read(&mm->mmap_sem);
 
 	tail_vma = get_gate_vma(priv->task);
 	priv->tail_vma = tail_vma;
diff -druNp linux-libre-2.6.30-gnu1/fs/proc/task_nommu.c linux-libre-2.6.30.10-gnu1/fs/proc/task_nommu.c
--- linux-libre-2.6.30-gnu1/fs/proc/task_nommu.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/proc/task_nommu.c	2009-12-04 01:00:07.000000000 -0500
@@ -189,6 +189,7 @@ static void *m_start(struct seq_file *m,
 		priv->task = NULL;
 		return NULL;
 	}
+	down_read(&mm->mmap_sem);
 
 	/* start from the Nth VMA */
 	for (p = rb_first(&mm->mm_rb); p; p = rb_next(p))
diff -druNp linux-libre-2.6.30-gnu1/fs/proc/uptime.c linux-libre-2.6.30.10-gnu1/fs/proc/uptime.c
--- linux-libre-2.6.30-gnu1/fs/proc/uptime.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/proc/uptime.c	2009-12-04 01:00:07.000000000 -0500
@@ -4,13 +4,18 @@
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 #include <linux/time.h>
+#include <linux/kernel_stat.h>
 #include <asm/cputime.h>
 
 static int uptime_proc_show(struct seq_file *m, void *v)
 {
 	struct timespec uptime;
 	struct timespec idle;
-	cputime_t idletime = cputime_add(init_task.utime, init_task.stime);
+	int i;
+	cputime_t idletime = cputime_zero;
+
+	for_each_possible_cpu(i)
+		idletime = cputime64_add(idletime, kstat_cpu(i).cpustat.idle);
 
 	do_posix_clock_monotonic_gettime(&uptime);
 	monotonic_to_bootbased(&uptime);
diff -druNp linux-libre-2.6.30-gnu1/fs/ramfs/inode.c linux-libre-2.6.30.10-gnu1/fs/ramfs/inode.c
--- linux-libre-2.6.30-gnu1/fs/ramfs/inode.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/ramfs/inode.c	2009-12-04 01:00:07.000000000 -0500
@@ -202,9 +202,12 @@ static int ramfs_parse_options(char *dat
 				return -EINVAL;
 			opts->mode = option & S_IALLUGO;
 			break;
-		default:
-			printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
-			return -EINVAL;
+		/*
+		 * We might like to report bad mount options here;
+		 * but traditionally ramfs has ignored all mount options,
+		 * and as it is used as a !CONFIG_SHMEM simple substitute
+		 * for tmpfs, better continue to ignore other mount options.
+		 */
 		}
 	}
 
diff -druNp linux-libre-2.6.30-gnu1/fs/select.c linux-libre-2.6.30.10-gnu1/fs/select.c
--- linux-libre-2.6.30-gnu1/fs/select.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/select.c	2009-12-04 01:00:07.000000000 -0500
@@ -110,6 +110,7 @@ void poll_initwait(struct poll_wqueues *
 {
 	init_poll_funcptr(&pwq->pt, __pollwait);
 	pwq->polling_task = current;
+	pwq->triggered = 0;
 	pwq->error = 0;
 	pwq->table = NULL;
 	pwq->inline_index = 0;
diff -druNp linux-libre-2.6.30-gnu1/fs/sysfs/dir.c linux-libre-2.6.30.10-gnu1/fs/sysfs/dir.c
--- linux-libre-2.6.30-gnu1/fs/sysfs/dir.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/sysfs/dir.c	2009-12-04 01:00:07.000000000 -0500
@@ -939,8 +939,10 @@ again:
 	/* Remove from old parent's list and insert into new parent's list. */
 	sysfs_unlink_sibling(sd);
 	sysfs_get(new_parent_sd);
+	drop_nlink(old_parent->d_inode);
 	sysfs_put(sd->s_parent);
 	sd->s_parent = new_parent_sd;
+	inc_nlink(new_parent->d_inode);
 	sysfs_link_sibling(sd);
 
  out_unlock:
diff -druNp linux-libre-2.6.30-gnu1/fs/udf/lowlevel.c linux-libre-2.6.30.10-gnu1/fs/udf/lowlevel.c
--- linux-libre-2.6.30-gnu1/fs/udf/lowlevel.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/udf/lowlevel.c	2009-12-04 01:00:07.000000000 -0500
@@ -56,7 +56,12 @@ unsigned long udf_get_last_block(struct
 	struct block_device *bdev = sb->s_bdev;
 	unsigned long lblock = 0;
 
-	if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock))
+	/*
+	 * ioctl failed or returned obviously bogus value?
+	 * Try using the device size...
+	 */
+	if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) ||
+	    lblock == 0)
 		lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
 
 	if (lblock)
diff -druNp linux-libre-2.6.30-gnu1/fs/xfs/xfs_bmap.c linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_bmap.c
--- linux-libre-2.6.30-gnu1/fs/xfs/xfs_bmap.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_bmap.c	2009-12-04 01:00:07.000000000 -0500
@@ -6085,6 +6085,7 @@ xfs_getbmap(
 			break;
 	}
 
+	kmem_free(out);
 	return error;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/fs/xfs/xfs_iget.c linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_iget.c
--- linux-libre-2.6.30-gnu1/fs/xfs/xfs_iget.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_iget.c	2009-12-04 01:00:07.000000000 -0500
@@ -63,6 +63,10 @@ xfs_inode_alloc(
 	ip = kmem_zone_alloc(xfs_inode_zone, KM_SLEEP);
 	if (!ip)
 		return NULL;
+	if (inode_init_always(mp->m_super, VFS_I(ip))) {
+		kmem_zone_free(xfs_inode_zone, ip);
+		return NULL;
+	}
 
 	ASSERT(atomic_read(&ip->i_iocount) == 0);
 	ASSERT(atomic_read(&ip->i_pincount) == 0);
@@ -104,17 +108,6 @@ xfs_inode_alloc(
 #ifdef XFS_DIR2_TRACE
 	ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
 #endif
-	/*
-	* Now initialise the VFS inode. We do this after the xfs_inode
-	* initialisation as internal failures will result in ->destroy_inode
-	* being called and that will pass down through the reclaim path and
-	* free the XFS inode. This path requires the XFS inode to already be
-	* initialised. Hence if this call fails, the xfs_inode has already
-	* been freed and we should not reference it at all in the error
-	* handling.
-	*/
-	if (!inode_init_always(mp->m_super, VFS_I(ip)))
-		return NULL;
 
 	/* prevent anyone from using this yet */
 	VFS_I(ip)->i_state = I_NEW|I_LOCK;
@@ -122,6 +115,71 @@ xfs_inode_alloc(
 	return ip;
 }
 
+STATIC void
+xfs_inode_free(
+	struct xfs_inode	*ip)
+{
+	switch (ip->i_d.di_mode & S_IFMT) {
+	case S_IFREG:
+	case S_IFDIR:
+	case S_IFLNK:
+		xfs_idestroy_fork(ip, XFS_DATA_FORK);
+		break;
+	}
+
+	if (ip->i_afp)
+		xfs_idestroy_fork(ip, XFS_ATTR_FORK);
+
+#ifdef XFS_INODE_TRACE
+	ktrace_free(ip->i_trace);
+#endif
+#ifdef XFS_BMAP_TRACE
+	ktrace_free(ip->i_xtrace);
+#endif
+#ifdef XFS_BTREE_TRACE
+	ktrace_free(ip->i_btrace);
+#endif
+#ifdef XFS_RW_TRACE
+	ktrace_free(ip->i_rwtrace);
+#endif
+#ifdef XFS_ILOCK_TRACE
+	ktrace_free(ip->i_lock_trace);
+#endif
+#ifdef XFS_DIR2_TRACE
+	ktrace_free(ip->i_dir_trace);
+#endif
+
+	if (ip->i_itemp) {
+		/*
+		 * Only if we are shutting down the fs will we see an
+		 * inode still in the AIL. If it is there, we should remove
+		 * it to prevent a use-after-free from occurring.
+		 */
+		xfs_log_item_t	*lip = &ip->i_itemp->ili_item;
+		struct xfs_ail	*ailp = lip->li_ailp;
+
+		ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
+				       XFS_FORCED_SHUTDOWN(ip->i_mount));
+		if (lip->li_flags & XFS_LI_IN_AIL) {
+			spin_lock(&ailp->xa_lock);
+			if (lip->li_flags & XFS_LI_IN_AIL)
+				xfs_trans_ail_delete(ailp, lip);
+			else
+				spin_unlock(&ailp->xa_lock);
+		}
+		xfs_inode_item_destroy(ip);
+		ip->i_itemp = NULL;
+	}
+
+	/* asserts to verify all state is correct here */
+	ASSERT(atomic_read(&ip->i_iocount) == 0);
+	ASSERT(atomic_read(&ip->i_pincount) == 0);
+	ASSERT(!spin_is_locked(&ip->i_flags_lock));
+	ASSERT(completion_done(&ip->i_flush));
+
+	kmem_zone_free(xfs_inode_zone, ip);
+}
+
 /*
  * Check the validity of the inode we just found it the cache
  */
@@ -166,7 +224,7 @@ xfs_iget_cache_hit(
 		 * errors cleanly, then tag it so it can be set up correctly
 		 * later.
 		 */
-		if (!inode_init_always(mp->m_super, VFS_I(ip))) {
+		if (inode_init_always(mp->m_super, VFS_I(ip))) {
 			error = ENOMEM;
 			goto out_error;
 		}
@@ -298,7 +356,8 @@ out_preload_end:
 	if (lock_flags)
 		xfs_iunlock(ip, lock_flags);
 out_destroy:
-	xfs_destroy_inode(ip);
+	__destroy_inode(VFS_I(ip));
+	xfs_inode_free(ip);
 	return error;
 }
 
@@ -506,62 +565,7 @@ xfs_ireclaim(
 	XFS_QM_DQDETACH(ip->i_mount, ip);
 	xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
 
-	switch (ip->i_d.di_mode & S_IFMT) {
-	case S_IFREG:
-	case S_IFDIR:
-	case S_IFLNK:
-		xfs_idestroy_fork(ip, XFS_DATA_FORK);
-		break;
-	}
-
-	if (ip->i_afp)
-		xfs_idestroy_fork(ip, XFS_ATTR_FORK);
-
-#ifdef XFS_INODE_TRACE
-	ktrace_free(ip->i_trace);
-#endif
-#ifdef XFS_BMAP_TRACE
-	ktrace_free(ip->i_xtrace);
-#endif
-#ifdef XFS_BTREE_TRACE
-	ktrace_free(ip->i_btrace);
-#endif
-#ifdef XFS_RW_TRACE
-	ktrace_free(ip->i_rwtrace);
-#endif
-#ifdef XFS_ILOCK_TRACE
-	ktrace_free(ip->i_lock_trace);
-#endif
-#ifdef XFS_DIR2_TRACE
-	ktrace_free(ip->i_dir_trace);
-#endif
-	if (ip->i_itemp) {
-		/*
-		 * Only if we are shutting down the fs will we see an
-		 * inode still in the AIL. If it is there, we should remove
-		 * it to prevent a use-after-free from occurring.
-		 */
-		xfs_log_item_t	*lip = &ip->i_itemp->ili_item;
-		struct xfs_ail	*ailp = lip->li_ailp;
-
-		ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) ||
-				       XFS_FORCED_SHUTDOWN(ip->i_mount));
-		if (lip->li_flags & XFS_LI_IN_AIL) {
-			spin_lock(&ailp->xa_lock);
-			if (lip->li_flags & XFS_LI_IN_AIL)
-				xfs_trans_ail_delete(ailp, lip);
-			else
-				spin_unlock(&ailp->xa_lock);
-		}
-		xfs_inode_item_destroy(ip);
-		ip->i_itemp = NULL;
-	}
-	/* asserts to verify all state is correct here */
-	ASSERT(atomic_read(&ip->i_iocount) == 0);
-	ASSERT(atomic_read(&ip->i_pincount) == 0);
-	ASSERT(!spin_is_locked(&ip->i_flags_lock));
-	ASSERT(completion_done(&ip->i_flush));
-	kmem_zone_free(xfs_inode_zone, ip);
+	xfs_inode_free(ip);
 }
 
 /*
diff -druNp linux-libre-2.6.30-gnu1/fs/xfs/xfs_inode.h linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_inode.h
--- linux-libre-2.6.30-gnu1/fs/xfs/xfs_inode.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_inode.h	2009-12-04 01:00:07.000000000 -0500
@@ -309,23 +309,6 @@ static inline struct inode *VFS_I(struct
 }
 
 /*
- * Get rid of a partially initialized inode.
- *
- * We have to go through destroy_inode to make sure allocations
- * from init_inode_always like the security data are undone.
- *
- * We mark the inode bad so that it takes the short cut in
- * the reclaim path instead of going through the flush path
- * which doesn't make sense for an inode that has never seen the
- * light of day.
- */
-static inline void xfs_destroy_inode(struct xfs_inode *ip)
-{
-	make_bad_inode(VFS_I(ip));
-	return destroy_inode(VFS_I(ip));
-}
-
-/*
  * i_flags helper functions
  */
 static inline void
diff -druNp linux-libre-2.6.30-gnu1/fs/xfs/xfs_log.c linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_log.c
--- linux-libre-2.6.30-gnu1/fs/xfs/xfs_log.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/fs/xfs/xfs_log.c	2009-12-04 01:00:07.000000000 -0500
@@ -3180,7 +3180,7 @@ try_again:
 STATIC void
 xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
 {
-	ASSERT(spin_is_locked(&log->l_icloglock));
+	assert_spin_locked(&log->l_icloglock);
 
 	if (iclog->ic_state == XLOG_STATE_ACTIVE) {
 		xlog_state_switch_iclogs(log, iclog, 0);
diff -druNp linux-libre-2.6.30-gnu1/include/acpi/processor.h linux-libre-2.6.30.10-gnu1/include/acpi/processor.h
--- linux-libre-2.6.30-gnu1/include/acpi/processor.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/acpi/processor.h	2009-12-04 01:00:07.000000000 -0500
@@ -174,7 +174,7 @@ struct acpi_processor_throttling {
 	cpumask_var_t shared_cpu_map;
 	int (*acpi_processor_get_throttling) (struct acpi_processor * pr);
 	int (*acpi_processor_set_throttling) (struct acpi_processor * pr,
-					      int state);
+					      int state, bool force);
 
 	u32 address;
 	u8 duty_offset;
@@ -320,7 +320,8 @@ static inline int acpi_processor_ppc_has
 /* in processor_throttling.c */
 int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
-extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state);
+extern int acpi_processor_set_throttling(struct acpi_processor *pr,
+					 int state, bool force);
 extern const struct file_operations acpi_processor_throttling_fops;
 extern void acpi_processor_throttling_init(void);
 /* in processor_idle.c */
diff -druNp linux-libre-2.6.30-gnu1/include/asm-generic/percpu.h linux-libre-2.6.30.10-gnu1/include/asm-generic/percpu.h
--- linux-libre-2.6.30-gnu1/include/asm-generic/percpu.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/asm-generic/percpu.h	2009-12-04 01:00:07.000000000 -0500
@@ -97,4 +97,8 @@ extern void setup_per_cpu_areas(void);
 #define PER_CPU_ATTRIBUTES
 #endif
 
+#ifndef PER_CPU_DEF_ATTRIBUTES
+#define PER_CPU_DEF_ATTRIBUTES
+#endif
+
 #endif /* _ASM_GENERIC_PERCPU_H_ */
diff -druNp linux-libre-2.6.30-gnu1/include/linux/bitmap.h linux-libre-2.6.30.10-gnu1/include/linux/bitmap.h
--- linux-libre-2.6.30-gnu1/include/linux/bitmap.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/bitmap.h	2009-12-04 01:00:07.000000000 -0500
@@ -94,13 +94,13 @@ extern void __bitmap_shift_right(unsigne
                         const unsigned long *src, int shift, int bits);
 extern void __bitmap_shift_left(unsigned long *dst,
                         const unsigned long *src, int shift, int bits);
-extern void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
+extern int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
 extern void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
 extern void __bitmap_xor(unsigned long *dst, const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
-extern void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
+extern int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
 extern int __bitmap_intersects(const unsigned long *bitmap1,
 			const unsigned long *bitmap2, int bits);
@@ -171,13 +171,12 @@ static inline void bitmap_copy(unsigned
 	}
 }
 
-static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
+static inline int bitmap_and(unsigned long *dst, const unsigned long *src1,
 			const unsigned long *src2, int nbits)
 {
 	if (small_const_nbits(nbits))
-		*dst = *src1 & *src2;
-	else
-		__bitmap_and(dst, src1, src2, nbits);
+		return (*dst = *src1 & *src2) != 0;
+	return __bitmap_and(dst, src1, src2, nbits);
 }
 
 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
@@ -198,13 +197,12 @@ static inline void bitmap_xor(unsigned l
 		__bitmap_xor(dst, src1, src2, nbits);
 }
 
-static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1,
+static inline int bitmap_andnot(unsigned long *dst, const unsigned long *src1,
 			const unsigned long *src2, int nbits)
 {
 	if (small_const_nbits(nbits))
-		*dst = *src1 & ~(*src2);
-	else
-		__bitmap_andnot(dst, src1, src2, nbits);
+		return (*dst = *src1 & ~(*src2)) != 0;
+	return __bitmap_andnot(dst, src1, src2, nbits);
 }
 
 static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
diff -druNp linux-libre-2.6.30-gnu1/include/linux/blkdev.h linux-libre-2.6.30.10-gnu1/include/linux/blkdev.h
--- linux-libre-2.6.30-gnu1/include/linux/blkdev.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/blkdev.h	2009-12-04 01:00:07.000000000 -0500
@@ -723,6 +723,7 @@ struct rq_map_data {
 	int nr_entries;
 	unsigned long offset;
 	int null_mapped;
+	int from_user;
 };
 
 struct req_iterator {
diff -druNp linux-libre-2.6.30-gnu1/include/linux/cpumask.h linux-libre-2.6.30.10-gnu1/include/linux/cpumask.h
--- linux-libre-2.6.30-gnu1/include/linux/cpumask.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/cpumask.h	2009-12-04 01:00:07.000000000 -0500
@@ -43,10 +43,10 @@
  * int cpu_isset(cpu, mask)		true iff bit 'cpu' set in mask
  * int cpu_test_and_set(cpu, mask)	test and set bit 'cpu' in mask
  *
- * void cpus_and(dst, src1, src2)	dst = src1 & src2  [intersection]
+ * int cpus_and(dst, src1, src2)	dst = src1 & src2  [intersection]
  * void cpus_or(dst, src1, src2)	dst = src1 | src2  [union]
  * void cpus_xor(dst, src1, src2)	dst = src1 ^ src2
- * void cpus_andnot(dst, src1, src2)	dst = src1 & ~src2
+ * int cpus_andnot(dst, src1, src2)	dst = src1 & ~src2
  * void cpus_complement(dst, src)	dst = ~src
  *
  * int cpus_equal(mask1, mask2)		Does mask1 == mask2?
@@ -179,10 +179,10 @@ static inline int __cpu_test_and_set(int
 }
 
 #define cpus_and(dst, src1, src2) __cpus_and(&(dst), &(src1), &(src2), NR_CPUS)
-static inline void __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
+static inline int __cpus_and(cpumask_t *dstp, const cpumask_t *src1p,
 					const cpumask_t *src2p, int nbits)
 {
-	bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
+	return bitmap_and(dstp->bits, src1p->bits, src2p->bits, nbits);
 }
 
 #define cpus_or(dst, src1, src2) __cpus_or(&(dst), &(src1), &(src2), NR_CPUS)
@@ -201,10 +201,10 @@ static inline void __cpus_xor(cpumask_t
 
 #define cpus_andnot(dst, src1, src2) \
 				__cpus_andnot(&(dst), &(src1), &(src2), NR_CPUS)
-static inline void __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
+static inline int __cpus_andnot(cpumask_t *dstp, const cpumask_t *src1p,
 					const cpumask_t *src2p, int nbits)
 {
-	bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
+	return bitmap_andnot(dstp->bits, src1p->bits, src2p->bits, nbits);
 }
 
 #define cpus_complement(dst, src) __cpus_complement(&(dst), &(src), NR_CPUS)
@@ -738,11 +738,11 @@ static inline void cpumask_clear(struct
  * @src1p: the first input
  * @src2p: the second input
  */
-static inline void cpumask_and(struct cpumask *dstp,
+static inline int cpumask_and(struct cpumask *dstp,
 			       const struct cpumask *src1p,
 			       const struct cpumask *src2p)
 {
-	bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p),
+	return bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p),
 				       cpumask_bits(src2p), nr_cpumask_bits);
 }
 
@@ -779,11 +779,11 @@ static inline void cpumask_xor(struct cp
  * @src1p: the first input
  * @src2p: the second input
  */
-static inline void cpumask_andnot(struct cpumask *dstp,
+static inline int cpumask_andnot(struct cpumask *dstp,
 				  const struct cpumask *src1p,
 				  const struct cpumask *src2p)
 {
-	bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p),
+	return bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p),
 					  cpumask_bits(src2p), nr_cpumask_bits);
 }
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/firmware-map.h linux-libre-2.6.30.10-gnu1/include/linux/firmware-map.h
--- linux-libre-2.6.30-gnu1/include/linux/firmware-map.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/firmware-map.h	2009-12-04 01:00:07.000000000 -0500
@@ -24,21 +24,17 @@
  */
 #ifdef CONFIG_FIRMWARE_MEMMAP
 
-int firmware_map_add(resource_size_t start, resource_size_t end,
-		     const char *type);
-int firmware_map_add_early(resource_size_t start, resource_size_t end,
-			   const char *type);
+int firmware_map_add(u64 start, u64 end, const char *type);
+int firmware_map_add_early(u64 start, u64 end, const char *type);
 
 #else /* CONFIG_FIRMWARE_MEMMAP */
 
-static inline int firmware_map_add(resource_size_t start, resource_size_t end,
-				   const char *type)
+static inline int firmware_map_add(u64 start, u64 end, const char *type)
 {
 	return 0;
 }
 
-static inline int firmware_map_add_early(resource_size_t start,
-					 resource_size_t end, const char *type)
+static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
 {
 	return 0;
 }
diff -druNp linux-libre-2.6.30-gnu1/include/linux/fs.h linux-libre-2.6.30.10-gnu1/include/linux/fs.h
--- linux-libre-2.6.30-gnu1/include/linux/fs.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/fs.h	2009-12-04 01:00:07.000000000 -0500
@@ -2121,7 +2121,7 @@ extern struct file *do_filp_open(int dfd
 		int open_flag, int mode, int acc_mode);
 extern int may_open(struct path *, int, int);
 
-extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
+extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern struct file * open_exec(const char *);
  
 /* fs/dcache.c -- generic fs support functions */
@@ -2135,7 +2135,7 @@ extern loff_t default_llseek(struct file
 
 extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin);
 
-extern struct inode * inode_init_always(struct super_block *, struct inode *);
+extern int inode_init_always(struct super_block *, struct inode *);
 extern void inode_init_once(struct inode *);
 extern void inode_add_to_lists(struct super_block *, struct inode *);
 extern void iput(struct inode *);
@@ -2162,6 +2162,7 @@ extern void __iget(struct inode * inode)
 extern void iget_failed(struct inode *);
 extern void clear_inode(struct inode *);
 extern void destroy_inode(struct inode *);
+extern void __destroy_inode(struct inode *);
 extern struct inode *new_inode(struct super_block *);
 extern int should_remove_suid(struct dentry *);
 extern int file_remove_suid(struct file *);
diff -druNp linux-libre-2.6.30-gnu1/include/linux/hugetlb.h linux-libre-2.6.30.10-gnu1/include/linux/hugetlb.h
--- linux-libre-2.6.30-gnu1/include/linux/hugetlb.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/hugetlb.h	2009-12-04 01:00:07.000000000 -0500
@@ -10,6 +10,7 @@
 #include <asm/tlbflush.h>
 
 struct ctl_table;
+struct user_struct;
 
 static inline int is_vm_hugetlb_page(struct vm_area_struct *vma)
 {
@@ -139,7 +140,8 @@ static inline struct hugetlbfs_sb_info *
 
 extern const struct file_operations hugetlbfs_file_operations;
 extern struct vm_operations_struct hugetlb_vm_ops;
-struct file *hugetlb_file_setup(const char *name, size_t, int);
+struct file *hugetlb_file_setup(const char *name, size_t size, int acct,
+						struct user_struct **user);
 int hugetlb_get_quota(struct address_space *mapping, long delta);
 void hugetlb_put_quota(struct address_space *mapping, long delta);
 
@@ -161,7 +163,7 @@ static inline void set_file_hugepages(st
 
 #define is_file_hugepages(file)			0
 #define set_file_hugepages(file)		BUG()
-#define hugetlb_file_setup(name,size,acctflag)	ERR_PTR(-ENOSYS)
+#define hugetlb_file_setup(name,size,acct,user)	ERR_PTR(-ENOSYS)
 
 #endif /* !CONFIG_HUGETLBFS */
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/ide.h linux-libre-2.6.30.10-gnu1/include/linux/ide.h
--- linux-libre-2.6.30-gnu1/include/linux/ide.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/ide.h	2009-12-04 01:00:07.000000000 -0500
@@ -1384,7 +1384,6 @@ int ide_in_drive_list(u16 *, const struc
 #ifdef CONFIG_BLK_DEV_IDEDMA
 int ide_dma_good_drive(ide_drive_t *);
 int __ide_dma_bad_drive(ide_drive_t *);
-int ide_id_dma_bug(ide_drive_t *);
 
 u8 ide_find_dma_mode(ide_drive_t *, u8);
 
@@ -1425,7 +1424,6 @@ void ide_dma_lost_irq(ide_drive_t *);
 ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int);
 
 #else
-static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
 static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
 static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; }
diff -druNp linux-libre-2.6.30-gnu1/include/linux/kvm_host.h linux-libre-2.6.30.10-gnu1/include/linux/kvm_host.h
--- linux-libre-2.6.30-gnu1/include/linux/kvm_host.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/kvm_host.h	2009-12-04 01:00:07.000000000 -0500
@@ -110,6 +110,7 @@ struct kvm_memory_slot {
 
 struct kvm_kernel_irq_routing_entry {
 	u32 gsi;
+	u32 type;
 	int (*set)(struct kvm_kernel_irq_routing_entry *e,
 		    struct kvm *kvm, int level);
 	union {
@@ -125,6 +126,7 @@ struct kvm_kernel_irq_routing_entry {
 struct kvm {
 	struct mutex lock; /* protects the vcpus array and APIC accesses */
 	spinlock_t mmu_lock;
+	spinlock_t requests_lock;
 	struct rw_semaphore slots_lock;
 	struct mm_struct *mm; /* userspace tied to this vm */
 	int nmemslots;
diff -druNp linux-libre-2.6.30-gnu1/include/linux/kvm_para.h linux-libre-2.6.30.10-gnu1/include/linux/kvm_para.h
--- linux-libre-2.6.30-gnu1/include/linux/kvm_para.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/kvm_para.h	2009-12-04 01:00:07.000000000 -0500
@@ -13,6 +13,7 @@
 #define KVM_ENOSYS		1000
 #define KVM_EFAULT		EFAULT
 #define KVM_E2BIG		E2BIG
+#define KVM_EPERM		EPERM
 
 #define KVM_HC_VAPIC_POLL_IRQ		1
 #define KVM_HC_MMU_OP			2
diff -druNp linux-libre-2.6.30-gnu1/include/linux/mlx4/qp.h linux-libre-2.6.30.10-gnu1/include/linux/mlx4/qp.h
--- linux-libre-2.6.30-gnu1/include/linux/mlx4/qp.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/mlx4/qp.h	2009-12-04 01:00:07.000000000 -0500
@@ -165,6 +165,7 @@ enum {
 	MLX4_WQE_CTRL_IP_CSUM		= 1 << 4,
 	MLX4_WQE_CTRL_TCP_UDP_CSUM	= 1 << 5,
 	MLX4_WQE_CTRL_INS_VLAN		= 1 << 6,
+	MLX4_WQE_CTRL_STRONG_ORDER	= 1 << 7,
 };
 
 struct mlx4_wqe_ctrl_seg {
diff -druNp linux-libre-2.6.30-gnu1/include/linux/mm.h linux-libre-2.6.30.10-gnu1/include/linux/mm.h
--- linux-libre-2.6.30-gnu1/include/linux/mm.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/mm.h	2009-12-04 01:00:07.000000000 -0500
@@ -580,12 +580,10 @@ static inline void set_page_links(struct
  */
 static inline unsigned long round_hint_to_min(unsigned long hint)
 {
-#ifdef CONFIG_SECURITY
 	hint &= PAGE_MASK;
 	if (((void *)hint != NULL) &&
 	    (hint < mmap_min_addr))
 		return PAGE_ALIGN(mmap_min_addr);
-#endif
 	return hint;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/netdevice.h linux-libre-2.6.30.10-gnu1/include/linux/netdevice.h
--- linux-libre-2.6.30-gnu1/include/linux/netdevice.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/netdevice.h	2009-12-04 01:00:07.000000000 -0500
@@ -1856,15 +1856,14 @@ static inline int net_gso_ok(int feature
 
 static inline int skb_gso_ok(struct sk_buff *skb, int features)
 {
-	return net_gso_ok(features, skb_shinfo(skb)->gso_type);
+	return net_gso_ok(features, skb_shinfo(skb)->gso_type) &&
+	       (!skb_shinfo(skb)->frag_list || (features & NETIF_F_FRAGLIST));
 }
 
 static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
 {
 	return skb_is_gso(skb) &&
 	       (!skb_gso_ok(skb, dev->features) ||
-	        (skb_shinfo(skb)->frag_list &&
-	         !(dev->features & NETIF_F_FRAGLIST)) ||
 		unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
 }
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/nfs_fs.h linux-libre-2.6.30.10-gnu1/include/linux/nfs_fs.h
--- linux-libre-2.6.30-gnu1/include/linux/nfs_fs.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/nfs_fs.h	2009-12-04 01:00:07.000000000 -0500
@@ -473,7 +473,6 @@ extern int  nfs_writepages(struct addres
 extern int  nfs_flush_incompatible(struct file *file, struct page *page);
 extern int  nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int);
 extern int nfs_writeback_done(struct rpc_task *, struct nfs_write_data *);
-extern void nfs_writedata_release(void *);
 
 /*
  * Try to write back everything synchronously (but check the
@@ -488,7 +487,6 @@ extern int nfs_wb_page_cancel(struct ino
 extern int  nfs_commit_inode(struct inode *, int);
 extern struct nfs_write_data *nfs_commitdata_alloc(void);
 extern void nfs_commit_free(struct nfs_write_data *wdata);
-extern void nfs_commitdata_release(void *wdata);
 #else
 static inline int
 nfs_commit_inode(struct inode *inode, int how)
@@ -507,6 +505,7 @@ nfs_have_writebacks(struct inode *inode)
  * Allocate nfs_write_data structures
  */
 extern struct nfs_write_data *nfs_writedata_alloc(unsigned int npages);
+extern void nfs_writedata_free(struct nfs_write_data *);
 
 /*
  * linux/fs/nfs/read.c
@@ -515,7 +514,6 @@ extern int  nfs_readpage(struct file *,
 extern int  nfs_readpages(struct file *, struct address_space *,
 		struct list_head *, unsigned);
 extern int  nfs_readpage_result(struct rpc_task *, struct nfs_read_data *);
-extern void nfs_readdata_release(void *data);
 extern int  nfs_readpage_async(struct nfs_open_context *, struct inode *,
 			       struct page *);
 
@@ -523,6 +521,7 @@ extern int  nfs_readpage_async(struct nf
  * Allocate nfs_read_data structures
  */
 extern struct nfs_read_data *nfs_readdata_alloc(unsigned int npages);
+extern void nfs_readdata_free(struct nfs_read_data *);
 
 /*
  * linux/fs/nfs3proc.c
diff -druNp linux-libre-2.6.30-gnu1/include/linux/percpu-defs.h linux-libre-2.6.30.10-gnu1/include/linux/percpu-defs.h
--- linux-libre-2.6.30-gnu1/include/linux/percpu-defs.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/percpu-defs.h	2009-12-04 01:00:07.000000000 -0500
@@ -24,7 +24,8 @@
 
 #define DEFINE_PER_CPU_SECTION(type, name, section)			\
 	__attribute__((__section__(PER_CPU_BASE_SECTION section)))	\
-	PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name
+	PER_CPU_ATTRIBUTES PER_CPU_DEF_ATTRIBUTES			\
+	__typeof__(type) per_cpu__##name
 
 /*
  * Variant on the per-CPU variable declaration/definition theme used for
diff -druNp linux-libre-2.6.30-gnu1/include/linux/personality.h linux-libre-2.6.30.10-gnu1/include/linux/personality.h
--- linux-libre-2.6.30-gnu1/include/linux/personality.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/personality.h	2009-12-04 01:00:07.000000000 -0500
@@ -40,7 +40,10 @@ enum {
  * Security-relevant compatibility flags that must be
  * cleared upon setuid or setgid exec:
  */
-#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC|ADDR_NO_RANDOMIZE)
+#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC  | \
+			    ADDR_NO_RANDOMIZE  | \
+			    ADDR_COMPAT_LAYOUT | \
+			    MMAP_PAGE_ZERO)
 
 /*
  * Personality types.
diff -druNp linux-libre-2.6.30-gnu1/include/linux/sched.h linux-libre-2.6.30.10-gnu1/include/linux/sched.h
--- linux-libre-2.6.30-gnu1/include/linux/sched.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/sched.h	2009-12-04 01:00:07.000000000 -0500
@@ -206,7 +206,7 @@ extern unsigned long long time_sync_thre
 			((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
 #define task_contributes_to_load(task)	\
 				((task->state & TASK_UNINTERRUPTIBLE) != 0 && \
-				 (task->flags & PF_FROZEN) == 0)
+				 (task->flags & PF_FREEZING) == 0)
 
 #define __set_task_state(tsk, state_value)		\
 	do { (tsk)->state = (state_value); } while (0)
@@ -1630,6 +1630,7 @@ extern cputime_t task_gtime(struct task_
 #define PF_MEMALLOC	0x00000800	/* Allocating memory */
 #define PF_FLUSHER	0x00001000	/* responsible for disk writeback */
 #define PF_USED_MATH	0x00002000	/* if unset the fpu must be initialized before use */
+#define PF_FREEZING	0x00004000	/* freeze in progress. do not account to load */
 #define PF_NOFREEZE	0x00008000	/* this thread should not be frozen */
 #define PF_FROZEN	0x00010000	/* frozen for system suspend */
 #define PF_FSTRANS	0x00020000	/* inside a filesystem transaction */
diff -druNp linux-libre-2.6.30-gnu1/include/linux/security.h linux-libre-2.6.30.10-gnu1/include/linux/security.h
--- linux-libre-2.6.30-gnu1/include/linux/security.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/security.h	2009-12-04 01:00:07.000000000 -0500
@@ -2197,6 +2197,8 @@ static inline int security_file_mmap(str
 				     unsigned long addr,
 				     unsigned long addr_only)
 {
+	if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
+		return -EACCES;
 	return 0;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/serial.h linux-libre-2.6.30.10-gnu1/include/linux/serial.h
--- linux-libre-2.6.30-gnu1/include/linux/serial.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/serial.h	2009-12-04 01:00:07.000000000 -0500
@@ -96,54 +96,76 @@ struct serial_uart_config {
 
 /*
  * Definitions for async_struct (and serial_struct) flags field
+ *
+ * Define ASYNCB_* for convenient use with {test,set,clear}_bit.
  */
-#define ASYNC_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
-				   on the callout port */
-#define ASYNC_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
-#define ASYNC_SAK	0x0004	/* Secure Attention Key (Orange book) */
-#define ASYNC_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
-
-#define ASYNC_SPD_MASK	0x1030
-#define ASYNC_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
-
-#define ASYNC_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
-#define ASYNC_SPD_CUST	0x0030  /* Use user-specified divisor */
-
-#define ASYNC_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
-#define ASYNC_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
-#define ASYNC_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
-#define ASYNC_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
-#define ASYNC_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
-
-#define ASYNC_HARDPPS_CD	0x0800	/* Call hardpps when CD goes high  */
-
-#define ASYNC_SPD_SHI	0x1000	/* Use 230400 instead of 38400 bps */
-#define ASYNC_SPD_WARP	0x1010	/* Use 460800 instead of 38400 bps */
-
-#define ASYNC_LOW_LATENCY 0x2000 /* Request low latency behaviour */
-
-#define ASYNC_BUGGY_UART  0x4000 /* This is a buggy UART, skip some safety
-				  * checks.  Note: can be dangerous! */
+#define ASYNCB_HUP_NOTIFY	 0 /* Notify getty on hangups and closes
+				    * on the callout port */
+#define ASYNCB_FOURPORT		 1 /* Set OU1, OUT2 per AST Fourport settings */
+#define ASYNCB_SAK		 2 /* Secure Attention Key (Orange book) */
+#define ASYNCB_SPLIT_TERMIOS	 3 /* Separate termios for dialin/callout */
+#define ASYNCB_SPD_HI		 4 /* Use 56000 instead of 38400 bps */
+#define ASYNCB_SPD_VHI		 5 /* Use 115200 instead of 38400 bps */
+#define ASYNCB_SKIP_TEST	 6 /* Skip UART test during autoconfiguration */
+#define ASYNCB_AUTO_IRQ		 7 /* Do automatic IRQ during
+				    * autoconfiguration */
+#define ASYNCB_SESSION_LOCKOUT	 8 /* Lock out cua opens based on session */
+#define ASYNCB_PGRP_LOCKOUT	 9 /* Lock out cua opens based on pgrp */
+#define ASYNCB_CALLOUT_NOHUP	10 /* Don't do hangups for cua device */
+#define ASYNCB_HARDPPS_CD	11 /* Call hardpps when CD goes high  */
+#define ASYNCB_SPD_SHI		12 /* Use 230400 instead of 38400 bps */
+#define ASYNCB_LOW_LATENCY	13 /* Request low latency behaviour */
+#define ASYNCB_BUGGY_UART	14 /* This is a buggy UART, skip some safety
+				    * checks.  Note: can be dangerous! */
+#define ASYNCB_AUTOPROBE	15 /* Port was autoprobed by PCI or PNP code */
+#define ASYNCB_LAST_USER	15
 
-#define ASYNC_AUTOPROBE	 0x8000 /* Port was autoprobed by PCI or PNP code */
+/* Internal flags used only by kernel */
+#define ASYNCB_INITIALIZED	31 /* Serial port was initialized */
+#define ASYNCB_NORMAL_ACTIVE	29 /* Normal device is active */
+#define ASYNCB_BOOT_AUTOCONF	28 /* Autoconfigure port on bootup */
+#define ASYNCB_CLOSING		27 /* Serial port is closing */
+#define ASYNCB_CTS_FLOW		26 /* Do CTS flow control */
+#define ASYNCB_CHECK_CD		25 /* i.e., CLOCAL */
+#define ASYNCB_SHARE_IRQ	24 /* for multifunction cards, no longer used */
+#define ASYNCB_CONS_FLOW	23 /* flow control for console  */
+#define ASYNCB_BOOT_ONLYMCA	22 /* Probe only if MCA bus */
+#define ASYNCB_FIRST_KERNEL	22
 
-#define ASYNC_FLAGS	0x7FFF	/* Possible legal async flags */
-#define ASYNC_USR_MASK	0x3430	/* Legal flags that non-privileged
-				 * users can set or reset */
+#define ASYNC_HUP_NOTIFY	(1U << ASYNCB_HUP_NOTIFY)
+#define ASYNC_FOURPORT		(1U << ASYNCB_FOURPORT)
+#define ASYNC_SAK		(1U << ASYNCB_SAK)
+#define ASYNC_SPLIT_TERMIOS	(1U << ASYNCB_SPLIT_TERMIOS)
+#define ASYNC_SPD_HI		(1U << ASYNCB_SPD_HI)
+#define ASYNC_SPD_VHI		(1U << ASYNCB_SPD_VHI)
+#define ASYNC_SKIP_TEST		(1U << ASYNCB_SKIP_TEST)
+#define ASYNC_AUTO_IRQ		(1U << ASYNCB_AUTO_IRQ)
+#define ASYNC_SESSION_LOCKOUT	(1U << ASYNCB_SESSION_LOCKOUT)
+#define ASYNC_PGRP_LOCKOUT	(1U << ASYNCB_PGRP_LOCKOUT)
+#define ASYNC_CALLOUT_NOHUP	(1U << ASYNCB_CALLOUT_NOHUP)
+#define ASYNC_HARDPPS_CD	(1U << ASYNCB_HARDPPS_CD)
+#define ASYNC_SPD_SHI		(1U << ASYNCB_SPD_SHI)
+#define ASYNC_LOW_LATENCY	(1U << ASYNCB_LOW_LATENCY)
+#define ASYNC_BUGGY_UART	(1U << ASYNCB_BUGGY_UART)
+#define ASYNC_AUTOPROBE		(1U << ASYNCB_AUTOPROBE)
 
-/* Internal flags used only by kernel/chr_drv/serial.c */
-#define ASYNC_INITIALIZED	0x80000000 /* Serial port was initialized */
-#define ASYNC_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
-#define ASYNC_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
-#define ASYNC_CLOSING		0x08000000 /* Serial port is closing */
-#define ASYNC_CTS_FLOW		0x04000000 /* Do CTS flow control */
-#define ASYNC_CHECK_CD		0x02000000 /* i.e., CLOCAL */
-#define ASYNC_SHARE_IRQ		0x01000000 /* for multifunction cards
-					     --- no longer used */
-#define ASYNC_CONS_FLOW		0x00800000 /* flow control for console  */
+#define ASYNC_FLAGS		((1U << ASYNCB_LAST_USER) - 1)
+#define ASYNC_USR_MASK		(ASYNC_SPD_HI|ASYNC_SPD_VHI| \
+		ASYNC_CALLOUT_NOHUP|ASYNC_SPD_SHI|ASYNC_LOW_LATENCY)
+#define ASYNC_SPD_CUST		(ASYNC_SPD_HI|ASYNC_SPD_VHI)
+#define ASYNC_SPD_WARP		(ASYNC_SPD_HI|ASYNC_SPD_SHI)
+#define ASYNC_SPD_MASK		(ASYNC_SPD_HI|ASYNC_SPD_VHI|ASYNC_SPD_SHI)
 
-#define ASYNC_BOOT_ONLYMCA	0x00400000 /* Probe only if MCA bus */
-#define ASYNC_INTERNAL_FLAGS	0xFFC00000 /* Internal flags */
+#define ASYNC_INITIALIZED	(1U << ASYNCB_INITIALIZED)
+#define ASYNC_NORMAL_ACTIVE	(1U << ASYNCB_NORMAL_ACTIVE)
+#define ASYNC_BOOT_AUTOCONF	(1U << ASYNCB_BOOT_AUTOCONF)
+#define ASYNC_CLOSING		(1U << ASYNCB_CLOSING)
+#define ASYNC_CTS_FLOW		(1U << ASYNCB_CTS_FLOW)
+#define ASYNC_CHECK_CD		(1U << ASYNCB_CHECK_CD)
+#define ASYNC_SHARE_IRQ		(1U << ASYNCB_SHARE_IRQ)
+#define ASYNC_CONS_FLOW		(1U << ASYNCB_CONS_FLOW)
+#define ASYNC_BOOT_ONLYMCA	(1U << ASYNCB_BOOT_ONLYMCA)
+#define ASYNC_INTERNAL_FLAGS	(~((1U << ASYNCB_FIRST_KERNEL) - 1))
 
 /*
  * Multiport serial configuration structure --- external structure
diff -druNp linux-libre-2.6.30-gnu1/include/linux/usb/serial.h linux-libre-2.6.30.10-gnu1/include/linux/usb/serial.h
--- linux-libre-2.6.30-gnu1/include/linux/usb/serial.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/usb/serial.h	2009-12-04 01:00:07.000000000 -0500
@@ -181,8 +181,10 @@ static inline void usb_set_serial_data(s
  *	This will be called when the struct usb_serial structure is fully set
  *	set up.  Do any local initialization of the device, or any private
  *	memory structure allocation at this point in time.
- * @shutdown: pointer to the driver's shutdown function.  This will be
- *	called when the device is removed from the system.
+ * @disconnect: pointer to the driver's disconnect function.  This will be
+ *	called when the device is unplugged or unbound from the driver.
+ * @release: pointer to the driver's release function.  This will be called
+ *	when the usb_serial data structure is about to be destroyed.
  * @usb_driver: pointer to the struct usb_driver that controls this
  *	device.  This is necessary to allow dynamic ids to be added to
  *	the driver from sysfs.
@@ -212,7 +214,8 @@ struct usb_serial_driver {
 	int (*attach)(struct usb_serial *serial);
 	int (*calc_num_ports) (struct usb_serial *serial);
 
-	void (*shutdown)(struct usb_serial *serial);
+	void (*disconnect)(struct usb_serial *serial);
+	void (*release)(struct usb_serial *serial);
 
 	int (*port_probe)(struct usb_serial_port *port);
 	int (*port_remove)(struct usb_serial_port *port);
@@ -292,7 +295,8 @@ extern void usb_serial_generic_read_bulk
 extern void usb_serial_generic_write_bulk_callback(struct urb *urb);
 extern void usb_serial_generic_throttle(struct tty_struct *tty);
 extern void usb_serial_generic_unthrottle(struct tty_struct *tty);
-extern void usb_serial_generic_shutdown(struct usb_serial *serial);
+extern void usb_serial_generic_disconnect(struct usb_serial *serial);
+extern void usb_serial_generic_release(struct usb_serial *serial);
 extern int usb_serial_generic_register(int debug);
 extern void usb_serial_generic_deregister(void);
 
diff -druNp linux-libre-2.6.30-gnu1/include/linux/vmstat.h linux-libre-2.6.30.10-gnu1/include/linux/vmstat.h
--- linux-libre-2.6.30-gnu1/include/linux/vmstat.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/linux/vmstat.h	2009-12-04 01:00:07.000000000 -0500
@@ -36,6 +36,9 @@ enum vm_event_item { PGPGIN, PGPGOUT, PS
 		FOR_ALL_ZONES(PGSTEAL),
 		FOR_ALL_ZONES(PGSCAN_KSWAPD),
 		FOR_ALL_ZONES(PGSCAN_DIRECT),
+#ifdef CONFIG_NUMA
+		PGSCAN_ZONE_RECLAIM_FAILED,
+#endif
 		PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL,
 		PAGEOUTRUN, ALLOCSTALL, PGROTATED,
 #ifdef CONFIG_HUGETLB_PAGE
diff -druNp linux-libre-2.6.30-gnu1/include/net/netfilter/nf_conntrack.h linux-libre-2.6.30.10-gnu1/include/net/netfilter/nf_conntrack.h
--- linux-libre-2.6.30-gnu1/include/net/netfilter/nf_conntrack.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/net/netfilter/nf_conntrack.h	2009-12-04 01:00:07.000000000 -0500
@@ -255,8 +255,8 @@ static inline bool nf_ct_kill(struct nf_
 /* Update TCP window tracking data when NAT mangles the packet */
 extern void nf_conntrack_tcp_update(const struct sk_buff *skb,
 				    unsigned int dataoff,
-				    struct nf_conn *ct,
-				    int dir);
+				    struct nf_conn *ct, int dir,
+				    s16 offset);
 
 /* Fake conntrack entry for untracked connections */
 extern struct nf_conn nf_conntrack_untracked;
diff -druNp linux-libre-2.6.30-gnu1/include/net/sctp/sctp.h linux-libre-2.6.30.10-gnu1/include/net/sctp/sctp.h
--- linux-libre-2.6.30-gnu1/include/net/sctp/sctp.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/net/sctp/sctp.h	2009-12-04 01:00:07.000000000 -0500
@@ -448,6 +448,7 @@ static inline void sctp_skb_set_owner_r(
 {
 	struct sctp_ulpevent *event = sctp_skb2event(skb);
 
+	skb_orphan(skb);
 	skb->sk = sk;
 	skb->destructor = sctp_sock_rfree;
 	atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
diff -druNp linux-libre-2.6.30-gnu1/include/net/sock.h linux-libre-2.6.30.10-gnu1/include/net/sock.h
--- linux-libre-2.6.30-gnu1/include/net/sock.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/net/sock.h	2009-12-04 01:00:07.000000000 -0500
@@ -103,15 +103,15 @@ struct net;
 
 /**
  *	struct sock_common - minimal network layer representation of sockets
+ *	@skc_node: main hash linkage for various protocol lookup tables
+ *	@skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol
+ *	@skc_refcnt: reference count
+ *	@skc_hash: hash value used with various protocol lookup tables
  *	@skc_family: network address family
  *	@skc_state: Connection state
  *	@skc_reuse: %SO_REUSEADDR setting
  *	@skc_bound_dev_if: bound device index if != 0
- *	@skc_node: main hash linkage for various protocol lookup tables
- *	@skc_nulls_node: main hash linkage for UDP/UDP-Lite protocol
  *	@skc_bind_node: bind hash linkage for various protocol lookup tables
- *	@skc_refcnt: reference count
- *	@skc_hash: hash value used with various protocol lookup tables
  *	@skc_prot: protocol handlers inside a network family
  *	@skc_net: reference to the network namespace of this socket
  *
@@ -119,17 +119,21 @@ struct net;
  *	for struct sock and struct inet_timewait_sock.
  */
 struct sock_common {
-	unsigned short		skc_family;
-	volatile unsigned char	skc_state;
-	unsigned char		skc_reuse;
-	int			skc_bound_dev_if;
+	/*
+	 * first fields are not copied in sock_copy()
+	 */
 	union {
 		struct hlist_node	skc_node;
 		struct hlist_nulls_node skc_nulls_node;
 	};
-	struct hlist_node	skc_bind_node;
 	atomic_t		skc_refcnt;
+
 	unsigned int		skc_hash;
+	unsigned short		skc_family;
+	volatile unsigned char	skc_state;
+	unsigned char		skc_reuse;
+	int			skc_bound_dev_if;
+	struct hlist_node	skc_bind_node;
 	struct proto		*skc_prot;
 #ifdef CONFIG_NET_NS
 	struct net	 	*skc_net;
@@ -207,15 +211,17 @@ struct sock {
 	 * don't add nothing before this first member (__sk_common) --acme
 	 */
 	struct sock_common	__sk_common;
+#define sk_node			__sk_common.skc_node
+#define sk_nulls_node		__sk_common.skc_nulls_node
+#define sk_refcnt		__sk_common.skc_refcnt
+
+#define sk_copy_start		__sk_common.skc_hash
+#define sk_hash			__sk_common.skc_hash
 #define sk_family		__sk_common.skc_family
 #define sk_state		__sk_common.skc_state
 #define sk_reuse		__sk_common.skc_reuse
 #define sk_bound_dev_if		__sk_common.skc_bound_dev_if
-#define sk_node			__sk_common.skc_node
-#define sk_nulls_node		__sk_common.skc_nulls_node
 #define sk_bind_node		__sk_common.skc_bind_node
-#define sk_refcnt		__sk_common.skc_refcnt
-#define sk_hash			__sk_common.skc_hash
 #define sk_prot			__sk_common.skc_prot
 #define sk_net			__sk_common.skc_net
 	unsigned char		sk_shutdown : 2,
@@ -1217,6 +1223,7 @@ static inline int skb_copy_to_page(struc
 
 static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
 {
+	skb_orphan(skb);
 	sock_hold(sk);
 	skb->sk = sk;
 	skb->destructor = sock_wfree;
@@ -1225,6 +1232,7 @@ static inline void skb_set_owner_w(struc
 
 static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
 {
+	skb_orphan(skb);
 	skb->sk = sk;
 	skb->destructor = sock_rfree;
 	atomic_add(skb->truesize, &sk->sk_rmem_alloc);
diff -druNp linux-libre-2.6.30-gnu1/include/net/x25.h linux-libre-2.6.30.10-gnu1/include/net/x25.h
--- linux-libre-2.6.30-gnu1/include/net/x25.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/net/x25.h	2009-12-04 01:00:07.000000000 -0500
@@ -187,7 +187,7 @@ extern int  x25_addr_ntoa(unsigned char
 extern int  x25_addr_aton(unsigned char *, struct x25_address *,
 			  struct x25_address *);
 extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
-extern void x25_destroy_socket(struct sock *);
+extern void x25_destroy_socket_from_timer(struct sock *);
 extern int  x25_rx_call_request(struct sk_buff *, struct x25_neigh *, unsigned int);
 extern void x25_kill_by_neigh(struct x25_neigh *);
 
diff -druNp linux-libre-2.6.30-gnu1/include/pcmcia/ss.h linux-libre-2.6.30.10-gnu1/include/pcmcia/ss.h
--- linux-libre-2.6.30-gnu1/include/pcmcia/ss.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/include/pcmcia/ss.h	2009-12-04 01:00:07.000000000 -0500
@@ -279,7 +279,7 @@ extern struct pccard_resource_ops pccard
 extern struct pccard_resource_ops pccard_nonstatic_ops;
 
 /* socket drivers are expected to use these callbacks in their .drv struct */
-extern int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state);
+extern int pcmcia_socket_dev_suspend(struct device *dev);
 extern int pcmcia_socket_dev_resume(struct device *dev);
 
 /* socket drivers use this callback in their IRQ handler */
diff -druNp linux-libre-2.6.30-gnu1/init/main.c linux-libre-2.6.30.10-gnu1/init/main.c
--- linux-libre-2.6.30-gnu1/init/main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/init/main.c	2009-12-04 01:00:07.000000000 -0500
@@ -702,13 +702,14 @@ asmlinkage void __init start_kernel(void
 int initcall_debug;
 core_param(initcall_debug, initcall_debug, bool, 0644);
 
+static char msgbuf[64];
+static struct boot_trace_call call;
+static struct boot_trace_ret ret;
+
 int do_one_initcall(initcall_t fn)
 {
 	int count = preempt_count();
 	ktime_t calltime, delta, rettime;
-	char msgbuf[64];
-	struct boot_trace_call call;
-	struct boot_trace_ret ret;
 
 	if (initcall_debug) {
 		call.caller = task_pid_nr(current);
diff -druNp linux-libre-2.6.30-gnu1/ipc/shm.c linux-libre-2.6.30.10-gnu1/ipc/shm.c
--- linux-libre-2.6.30-gnu1/ipc/shm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/ipc/shm.c	2009-12-04 01:00:07.000000000 -0500
@@ -174,7 +174,7 @@ static void shm_destroy(struct ipc_names
 	shm_unlock(shp);
 	if (!is_file_hugepages(shp->shm_file))
 		shmem_lock(shp->shm_file, 0, shp->mlock_user);
-	else
+	else if (shp->mlock_user)
 		user_shm_unlock(shp->shm_file->f_path.dentry->d_inode->i_size,
 						shp->mlock_user);
 	fput (shp->shm_file);
@@ -369,8 +369,8 @@ static int newseg(struct ipc_namespace *
 		/* hugetlb_file_setup applies strict accounting */
 		if (shmflg & SHM_NORESERVE)
 			acctflag = VM_NORESERVE;
-		file = hugetlb_file_setup(name, size, acctflag);
-		shp->mlock_user = current_user();
+		file = hugetlb_file_setup(name, size, acctflag,
+							&shp->mlock_user);
 	} else {
 		/*
 		 * Do not allow no accounting for OVERCOMMIT_NEVER, even
@@ -411,6 +411,8 @@ static int newseg(struct ipc_namespace *
 	return error;
 
 no_id:
+	if (is_file_hugepages(file) && shp->mlock_user)
+		user_shm_unlock(size, shp->mlock_user);
 	fput(file);
 no_file:
 	security_shm_free(shp);
diff -druNp linux-libre-2.6.30-gnu1/kernel/acct.c linux-libre-2.6.30.10-gnu1/kernel/acct.c
--- linux-libre-2.6.30-gnu1/kernel/acct.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/acct.c	2009-12-04 01:00:07.000000000 -0500
@@ -215,6 +215,7 @@ static void acct_file_reopen(struct bsd_
 static int acct_on(char *name)
 {
 	struct file *file;
+	struct vfsmount *mnt;
 	int error;
 	struct pid_namespace *ns;
 	struct bsd_acct_struct *acct = NULL;
@@ -256,11 +257,12 @@ static int acct_on(char *name)
 		acct = NULL;
 	}
 
-	mnt_pin(file->f_path.mnt);
+	mnt = file->f_path.mnt;
+	mnt_pin(mnt);
 	acct_file_reopen(ns->bacct, file, ns);
 	spin_unlock(&acct_lock);
 
-	mntput(file->f_path.mnt); /* it's pinned, now give up active reference */
+	mntput(mnt); /* it's pinned, now give up active reference */
 	kfree(acct);
 
 	return 0;
diff -druNp linux-libre-2.6.30-gnu1/kernel/fork.c linux-libre-2.6.30.10-gnu1/kernel/fork.c
--- linux-libre-2.6.30-gnu1/kernel/fork.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/fork.c	2009-12-04 01:00:07.000000000 -0500
@@ -568,18 +568,18 @@ void mm_release(struct task_struct *tsk,
 	 * the value intact in a core dump, and to save the unnecessary
 	 * trouble otherwise.  Userland only wants this done for a sys_exit.
 	 */
-	if (tsk->clear_child_tid
-	    && !(tsk->flags & PF_SIGNALED)
-	    && atomic_read(&mm->mm_users) > 1) {
-		u32 __user * tidptr = tsk->clear_child_tid;
+	if (tsk->clear_child_tid) {
+		if (!(tsk->flags & PF_SIGNALED) &&
+		    atomic_read(&mm->mm_users) > 1) {
+			/*
+			 * We don't check the error code - if userspace has
+			 * not set up a proper pointer then tough luck.
+			 */
+			put_user(0, tsk->clear_child_tid);
+			sys_futex(tsk->clear_child_tid, FUTEX_WAKE,
+					1, NULL, NULL, 0);
+		}
 		tsk->clear_child_tid = NULL;
-
-		/*
-		 * We don't check the error code - if userspace has
-		 * not set up a proper pointer then tough luck.
-		 */
-		put_user(0, tidptr);
-		sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
 	}
 }
 
@@ -816,11 +816,8 @@ static int copy_signal(unsigned long clo
 {
 	struct signal_struct *sig;
 
-	if (clone_flags & CLONE_THREAD) {
-		atomic_inc(&current->signal->count);
-		atomic_inc(&current->signal->live);
+	if (clone_flags & CLONE_THREAD)
 		return 0;
-	}
 
 	sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
 	tsk->signal = sig;
@@ -878,16 +875,6 @@ void __cleanup_signal(struct signal_stru
 	kmem_cache_free(signal_cachep, sig);
 }
 
-static void cleanup_signal(struct task_struct *tsk)
-{
-	struct signal_struct *sig = tsk->signal;
-
-	atomic_dec(&sig->live);
-
-	if (atomic_dec_and_test(&sig->count))
-		__cleanup_signal(sig);
-}
-
 static void copy_flags(unsigned long clone_flags, struct task_struct *p)
 {
 	unsigned long new_flags = p->flags;
@@ -1237,6 +1224,8 @@ static struct task_struct *copy_process(
 	}
 
 	if (clone_flags & CLONE_THREAD) {
+		atomic_inc(&current->signal->count);
+		atomic_inc(&current->signal->live);
 		p->group_leader = current->group_leader;
 		list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
 	}
@@ -1281,7 +1270,8 @@ bad_fork_cleanup_mm:
 	if (p->mm)
 		mmput(p->mm);
 bad_fork_cleanup_signal:
-	cleanup_signal(p);
+	if (!(clone_flags & CLONE_THREAD))
+		__cleanup_signal(p->signal);
 bad_fork_cleanup_sighand:
 	__cleanup_sighand(p->sighand);
 bad_fork_cleanup_fs:
diff -druNp linux-libre-2.6.30-gnu1/kernel/freezer.c linux-libre-2.6.30.10-gnu1/kernel/freezer.c
--- linux-libre-2.6.30-gnu1/kernel/freezer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/freezer.c	2009-12-04 01:00:07.000000000 -0500
@@ -44,12 +44,19 @@ void refrigerator(void)
 	recalc_sigpending(); /* We sent fake signal, clean it up */
 	spin_unlock_irq(&current->sighand->siglock);
 
+	/* prevent accounting of that task to load */
+	current->flags |= PF_FREEZING;
+
 	for (;;) {
 		set_current_state(TASK_UNINTERRUPTIBLE);
 		if (!frozen(current))
 			break;
 		schedule();
 	}
+
+	/* Remove the accounting blocker */
+	current->flags &= ~PF_FREEZING;
+
 	pr_debug("%s left refrigerator\n", current->comm);
 	__set_current_state(save);
 }
diff -druNp linux-libre-2.6.30-gnu1/kernel/futex.c linux-libre-2.6.30.10-gnu1/kernel/futex.c
--- linux-libre-2.6.30-gnu1/kernel/futex.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/futex.c	2009-12-04 01:00:07.000000000 -0500
@@ -241,6 +241,7 @@ again:
 	if (err < 0)
 		return err;
 
+	page = compound_head(page);
 	lock_page(page);
 	if (!page->mapping) {
 		unlock_page(page);
@@ -278,6 +279,25 @@ void put_futex_key(int fshared, union fu
 	drop_futex_key_refs(key);
 }
 
+/*
+ * fault_in_user_writeable - fault in user address and verify RW access
+ * @uaddr:	pointer to faulting user space address
+ *
+ * Slow path to fixup the fault we just took in the atomic write
+ * access to @uaddr.
+ *
+ * We have no generic implementation of a non destructive write to the
+ * user address. We know that we faulted in the atomic pagefault
+ * disabled section so we can as well avoid the #PF overhead by
+ * calling get_user_pages() right away.
+ */
+static int fault_in_user_writeable(u32 __user *uaddr)
+{
+	int ret = get_user_pages(current, current->mm, (unsigned long)uaddr,
+				 1, 1, 0, NULL, NULL);
+	return ret < 0 ? ret : 0;
+}
+
 static u32 cmpxchg_futex_value_locked(u32 __user *uaddr, u32 uval, u32 newval)
 {
 	u32 curval;
@@ -739,7 +759,6 @@ retry:
 retry_private:
 	op_ret = futex_atomic_op_inuser(op, uaddr2);
 	if (unlikely(op_ret < 0)) {
-		u32 dummy;
 
 		double_unlock_hb(hb1, hb2);
 
@@ -757,7 +776,7 @@ retry_private:
 			goto out_put_keys;
 		}
 
-		ret = get_user(dummy, uaddr2);
+		ret = fault_in_user_writeable(uaddr2);
 		if (ret)
 			goto out_put_keys;
 
@@ -1097,7 +1116,7 @@ retry:
 handle_fault:
 	spin_unlock(q->lock_ptr);
 
-	ret = get_user(uval, uaddr);
+	ret = fault_in_user_writeable(uaddr);
 
 	spin_lock(q->lock_ptr);
 
@@ -1552,16 +1571,9 @@ out:
 	return ret;
 
 uaddr_faulted:
-	/*
-	 * We have to r/w  *(int __user *)uaddr, and we have to modify it
-	 * atomically.  Therefore, if we continue to fault after get_user()
-	 * below, we need to handle the fault ourselves, while still holding
-	 * the mmap_sem.  This can occur if the uaddr is under contention as
-	 * we have to drop the mmap_sem in order to call get_user().
-	 */
 	queue_unlock(&q, hb);
 
-	ret = get_user(uval, uaddr);
+	ret = fault_in_user_writeable(uaddr);
 	if (ret)
 		goto out_put_key;
 
@@ -1657,17 +1669,10 @@ out:
 	return ret;
 
 pi_faulted:
-	/*
-	 * We have to r/w  *(int __user *)uaddr, and we have to modify it
-	 * atomically.  Therefore, if we continue to fault after get_user()
-	 * below, we need to handle the fault ourselves, while still holding
-	 * the mmap_sem.  This can occur if the uaddr is under contention as
-	 * we have to drop the mmap_sem in order to call get_user().
-	 */
 	spin_unlock(&hb->lock);
 	put_futex_key(fshared, &key);
 
-	ret = get_user(uval, uaddr);
+	ret = fault_in_user_writeable(uaddr);
 	if (!ret)
 		goto retry;
 
diff -druNp linux-libre-2.6.30-gnu1/kernel/kthread.c linux-libre-2.6.30.10-gnu1/kernel/kthread.c
--- linux-libre-2.6.30-gnu1/kernel/kthread.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/kthread.c	2009-12-04 01:00:07.000000000 -0500
@@ -216,12 +216,12 @@ int kthread_stop(struct task_struct *k)
 	/* Now set kthread_should_stop() to true, and wake it up. */
 	kthread_stop_info.k = k;
 	wake_up_process(k);
-	put_task_struct(k);
 
 	/* Once it dies, reset stop ptr, gather result and we're done. */
 	wait_for_completion(&kthread_stop_info.done);
 	kthread_stop_info.k = NULL;
 	ret = kthread_stop_info.err;
+	put_task_struct(k);
 	mutex_unlock(&kthread_stop_lock);
 
 	trace_sched_kthread_stop_ret(ret);
diff -druNp linux-libre-2.6.30-gnu1/kernel/posix-timers.c linux-libre-2.6.30.10-gnu1/kernel/posix-timers.c
--- linux-libre-2.6.30-gnu1/kernel/posix-timers.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/posix-timers.c	2009-12-04 01:00:07.000000000 -0500
@@ -202,6 +202,12 @@ static int no_timer_create(struct k_itim
 	return -EOPNOTSUPP;
 }
 
+static int no_nsleep(const clockid_t which_clock, int flags,
+		     struct timespec *tsave, struct timespec __user *rmtp)
+{
+	return -EOPNOTSUPP;
+}
+
 /*
  * Return nonzero if we know a priori this clockid_t value is bogus.
  */
@@ -254,6 +260,7 @@ static __init int init_posix_timers(void
 		.clock_get = posix_get_monotonic_raw,
 		.clock_set = do_posix_clock_nosettime,
 		.timer_create = no_timer_create,
+		.nsleep = no_nsleep,
 	};
 
 	register_posix_clock(CLOCK_REALTIME, &clock_realtime);
diff -druNp linux-libre-2.6.30-gnu1/kernel/resource.c linux-libre-2.6.30.10-gnu1/kernel/resource.c
--- linux-libre-2.6.30-gnu1/kernel/resource.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/resource.c	2009-12-04 01:00:07.000000000 -0500
@@ -787,7 +787,7 @@ static int __init reserve_setup(char *st
 	static struct resource reserve[MAXRESERVE];
 
 	for (;;) {
-		int io_start, io_num;
+		unsigned int io_start, io_num;
 		int x = reserved;
 
 		if (get_option (&str, &io_start) != 2)
diff -druNp linux-libre-2.6.30-gnu1/kernel/sched.c linux-libre-2.6.30.10-gnu1/kernel/sched.c
--- linux-libre-2.6.30-gnu1/kernel/sched.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/sched.c	2009-12-04 01:00:07.000000000 -0500
@@ -497,6 +497,7 @@ struct rt_rq {
 #endif
 #ifdef CONFIG_SMP
 	unsigned long rt_nr_migratory;
+	unsigned long rt_nr_total;
 	int overloaded;
 	struct plist_head pushable_tasks;
 #endif
diff -druNp linux-libre-2.6.30-gnu1/kernel/sched_rt.c linux-libre-2.6.30.10-gnu1/kernel/sched_rt.c
--- linux-libre-2.6.30-gnu1/kernel/sched_rt.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/sched_rt.c	2009-12-04 01:00:07.000000000 -0500
@@ -10,6 +10,8 @@ static inline struct task_struct *rt_tas
 
 #ifdef CONFIG_RT_GROUP_SCHED
 
+#define rt_entity_is_task(rt_se) (!(rt_se)->my_q)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return rt_rq->rq;
@@ -22,6 +24,8 @@ static inline struct rt_rq *rt_rq_of_se(
 
 #else /* CONFIG_RT_GROUP_SCHED */
 
+#define rt_entity_is_task(rt_se) (1)
+
 static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq)
 {
 	return container_of(rt_rq, struct rq, rt);
@@ -73,7 +77,7 @@ static inline void rt_clear_overload(str
 
 static void update_rt_migration(struct rt_rq *rt_rq)
 {
-	if (rt_rq->rt_nr_migratory && (rt_rq->rt_nr_running > 1)) {
+	if (rt_rq->rt_nr_migratory && rt_rq->rt_nr_total > 1) {
 		if (!rt_rq->overloaded) {
 			rt_set_overload(rq_of_rt_rq(rt_rq));
 			rt_rq->overloaded = 1;
@@ -86,6 +90,12 @@ static void update_rt_migration(struct r
 
 static void inc_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total++;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory++;
 
@@ -94,6 +104,12 @@ static void inc_rt_migration(struct sche
 
 static void dec_rt_migration(struct sched_rt_entity *rt_se, struct rt_rq *rt_rq)
 {
+	if (!rt_entity_is_task(rt_se))
+		return;
+
+	rt_rq = &rq_of_rt_rq(rt_rq)->rt;
+
+	rt_rq->rt_nr_total--;
 	if (rt_se->nr_cpus_allowed > 1)
 		rt_rq->rt_nr_migratory--;
 
diff -druNp linux-libre-2.6.30-gnu1/kernel/signal.c linux-libre-2.6.30.10-gnu1/kernel/signal.c
--- linux-libre-2.6.30-gnu1/kernel/signal.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/signal.c	2009-12-04 01:00:07.000000000 -0500
@@ -2414,11 +2414,9 @@ do_sigaltstack (const stack_t __user *us
 	stack_t oss;
 	int error;
 
-	if (uoss) {
-		oss.ss_sp = (void __user *) current->sas_ss_sp;
-		oss.ss_size = current->sas_ss_size;
-		oss.ss_flags = sas_ss_flags(sp);
-	}
+	oss.ss_sp = (void __user *) current->sas_ss_sp;
+	oss.ss_size = current->sas_ss_size;
+	oss.ss_flags = sas_ss_flags(sp);
 
 	if (uss) {
 		void __user *ss_sp;
@@ -2461,13 +2459,16 @@ do_sigaltstack (const stack_t __user *us
 		current->sas_ss_size = ss_size;
 	}
 
+	error = 0;
 	if (uoss) {
 		error = -EFAULT;
-		if (copy_to_user(uoss, &oss, sizeof(oss)))
+		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
 			goto out;
+		error = __put_user(oss.ss_sp, &uoss->ss_sp) |
+			__put_user(oss.ss_size, &uoss->ss_size) |
+			__put_user(oss.ss_flags, &uoss->ss_flags);
 	}
 
-	error = 0;
 out:
 	return error;
 }
diff -druNp linux-libre-2.6.30-gnu1/kernel/smp.c linux-libre-2.6.30.10-gnu1/kernel/smp.c
--- linux-libre-2.6.30-gnu1/kernel/smp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/smp.c	2009-12-04 01:00:07.000000000 -0500
@@ -57,7 +57,7 @@ hotplug_cfd(struct notifier_block *nfb,
 			return NOTIFY_BAD;
 		break;
 
-#ifdef CONFIG_CPU_HOTPLUG
+#ifdef CONFIG_HOTPLUG_CPU
 	case CPU_UP_CANCELED:
 	case CPU_UP_CANCELED_FROZEN:
 
diff -druNp linux-libre-2.6.30-gnu1/kernel/sysctl.c linux-libre-2.6.30.10-gnu1/kernel/sysctl.c
--- linux-libre-2.6.30-gnu1/kernel/sysctl.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/sysctl.c	2009-12-04 01:00:07.000000000 -0500
@@ -1225,7 +1225,6 @@ static struct ctl_table vm_table[] = {
 		.strategy	= &sysctl_jiffies,
 	},
 #endif
-#ifdef CONFIG_SECURITY
 	{
 		.ctl_name	= CTL_UNNUMBERED,
 		.procname	= "mmap_min_addr",
@@ -1234,7 +1233,6 @@ static struct ctl_table vm_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_doulongvec_minmax,
 	},
-#endif
 #ifdef CONFIG_NUMA
 	{
 		.ctl_name	= CTL_UNNUMBERED,
diff -druNp linux-libre-2.6.30-gnu1/kernel/trace/ring_buffer.c linux-libre-2.6.30.10-gnu1/kernel/trace/ring_buffer.c
--- linux-libre-2.6.30-gnu1/kernel/trace/ring_buffer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/trace/ring_buffer.c	2009-12-04 01:00:07.000000000 -0500
@@ -695,6 +695,7 @@ ring_buffer_free(struct ring_buffer *buf
 
 	put_online_cpus();
 
+	kfree(buffer->buffers);
 	free_cpumask_var(buffer->cpumask);
 
 	kfree(buffer);
@@ -2101,7 +2102,6 @@ rb_buffer_peek(struct ring_buffer *buffe
 		 * the box. Return the padding, and we will release
 		 * the current locks, and try again.
 		 */
-		rb_advance_reader(cpu_buffer);
 		return event;
 
 	case RINGBUF_TYPE_TIME_EXTEND:
@@ -2218,6 +2218,8 @@ ring_buffer_peek(struct ring_buffer *buf
  again:
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 	event = rb_buffer_peek(buffer, cpu, ts);
+	if (event && event->type == RINGBUF_TYPE_PADDING)
+		rb_advance_reader(cpu_buffer);
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
 	if (event && event->type == RINGBUF_TYPE_PADDING) {
@@ -2282,12 +2284,9 @@ ring_buffer_consume(struct ring_buffer *
 	spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
 
 	event = rb_buffer_peek(buffer, cpu, ts);
-	if (!event)
-		goto out_unlock;
-
-	rb_advance_reader(cpu_buffer);
+	if (event)
+		rb_advance_reader(cpu_buffer);
 
- out_unlock:
 	spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
 
  out:
diff -druNp linux-libre-2.6.30-gnu1/kernel/trace/trace.c linux-libre-2.6.30.10-gnu1/kernel/trace/trace.c
--- linux-libre-2.6.30-gnu1/kernel/trace/trace.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/trace/trace.c	2009-12-04 01:00:07.000000000 -0500
@@ -2993,7 +2993,8 @@ tracing_fill_pipe_page(size_t rem, struc
 			break;
 		}
 
-		trace_consume(iter);
+		if (ret != TRACE_TYPE_NO_CONSUME)
+			trace_consume(iter);
 		rem -= count;
 		if (!find_next_entry_inc(iter))	{
 			rem = 0;
@@ -4122,8 +4123,11 @@ static void __ftrace_dump(bool disable_t
 		iter.pos = -1;
 
 		if (find_next_entry_inc(&iter) != NULL) {
-			print_trace_line(&iter);
-			trace_consume(&iter);
+			int ret;
+
+			ret = print_trace_line(&iter);
+			if (ret != TRACE_TYPE_NO_CONSUME)
+				trace_consume(&iter);
 		}
 
 		trace_printk_seq(&iter.seq);
diff -druNp linux-libre-2.6.30-gnu1/kernel/trace/trace_functions.c linux-libre-2.6.30.10-gnu1/kernel/trace/trace_functions.c
--- linux-libre-2.6.30-gnu1/kernel/trace/trace_functions.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/trace/trace_functions.c	2009-12-04 01:00:07.000000000 -0500
@@ -193,9 +193,11 @@ static void tracing_start_function_trace
 static void tracing_stop_function_trace(void)
 {
 	ftrace_function_enabled = 0;
-	/* OK if they are not registered */
-	unregister_ftrace_function(&trace_stack_ops);
-	unregister_ftrace_function(&trace_ops);
+
+	if (func_flags.val & TRACE_FUNC_OPT_STACK)
+		unregister_ftrace_function(&trace_stack_ops);
+	else
+		unregister_ftrace_function(&trace_ops);
 }
 
 static int func_set_flag(u32 old_flags, u32 bit, int set)
@@ -362,7 +364,7 @@ ftrace_trace_onoff_callback(char *glob,
  out_reg:
 	ret = register_ftrace_function_probe(glob, ops, count);
 
-	return ret;
+	return ret < 0 ? ret : 0;
 }
 
 static struct ftrace_func_command ftrace_traceon_cmd = {
diff -druNp linux-libre-2.6.30-gnu1/kernel/trace/trace_functions_graph.c linux-libre-2.6.30.10-gnu1/kernel/trace/trace_functions_graph.c
--- linux-libre-2.6.30-gnu1/kernel/trace/trace_functions_graph.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/kernel/trace/trace_functions_graph.c	2009-12-04 01:00:07.000000000 -0500
@@ -798,9 +798,16 @@ print_graph_function(struct trace_iterat
 
 	switch (entry->type) {
 	case TRACE_GRAPH_ENT: {
-		struct ftrace_graph_ent_entry *field;
+		/*
+		 * print_graph_entry() may consume the current event,
+		 * thus @field may become invalid, so we need to save it.
+		 * sizeof(struct ftrace_graph_ent_entry) is very small,
+		 * it can be safely saved at the stack.
+		 */
+		struct ftrace_graph_ent_entry *field, saved;
 		trace_assign_type(field, entry);
-		return print_graph_entry(field, s, iter);
+		saved = *field;
+		return print_graph_entry(&saved, s, iter);
 	}
 	case TRACE_GRAPH_RET: {
 		struct ftrace_graph_ret_entry *field;
diff -druNp linux-libre-2.6.30-gnu1/lib/bitmap.c linux-libre-2.6.30.10-gnu1/lib/bitmap.c
--- linux-libre-2.6.30-gnu1/lib/bitmap.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/lib/bitmap.c	2009-12-04 01:00:07.000000000 -0500
@@ -179,14 +179,16 @@ void __bitmap_shift_left(unsigned long *
 }
 EXPORT_SYMBOL(__bitmap_shift_left);
 
-void __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
+int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
 				const unsigned long *bitmap2, int bits)
 {
 	int k;
 	int nr = BITS_TO_LONGS(bits);
+	unsigned long result = 0;
 
 	for (k = 0; k < nr; k++)
-		dst[k] = bitmap1[k] & bitmap2[k];
+		result |= (dst[k] = bitmap1[k] & bitmap2[k]);
+	return result != 0;
 }
 EXPORT_SYMBOL(__bitmap_and);
 
@@ -212,14 +214,16 @@ void __bitmap_xor(unsigned long *dst, co
 }
 EXPORT_SYMBOL(__bitmap_xor);
 
-void __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
+int __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1,
 				const unsigned long *bitmap2, int bits)
 {
 	int k;
 	int nr = BITS_TO_LONGS(bits);
+	unsigned long result = 0;
 
 	for (k = 0; k < nr; k++)
-		dst[k] = bitmap1[k] & ~bitmap2[k];
+		result |= (dst[k] = bitmap1[k] & ~bitmap2[k]);
+	return result != 0;
 }
 EXPORT_SYMBOL(__bitmap_andnot);
 
diff -druNp linux-libre-2.6.30-gnu1/lib/dma-debug.c linux-libre-2.6.30.10-gnu1/lib/dma-debug.c
--- linux-libre-2.6.30-gnu1/lib/dma-debug.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/lib/dma-debug.c	2009-12-04 01:00:07.000000000 -0500
@@ -185,15 +185,50 @@ static void put_hash_bucket(struct hash_
 static struct dma_debug_entry *hash_bucket_find(struct hash_bucket *bucket,
 						struct dma_debug_entry *ref)
 {
-	struct dma_debug_entry *entry;
+	struct dma_debug_entry *entry, *ret = NULL;
+	int matches = 0, match_lvl, last_lvl = 0;
 
 	list_for_each_entry(entry, &bucket->list, list) {
-		if ((entry->dev_addr == ref->dev_addr) &&
-		    (entry->dev == ref->dev))
+		if ((entry->dev_addr != ref->dev_addr) ||
+		    (entry->dev != ref->dev))
+			continue;
+
+		/*
+		 * Some drivers map the same physical address multiple
+		 * times. Without a hardware IOMMU this results in the
+		 * same device addresses being put into the dma-debug
+		 * hash multiple times too. This can result in false
+		 * positives being reported. Therfore we implement a
+		 * best-fit algorithm here which returns the entry from
+		 * the hash which fits best to the reference value
+		 * instead of the first-fit.
+		 */
+		matches += 1;
+		match_lvl = 0;
+		entry->size      == ref->size      ? ++match_lvl : match_lvl;
+		entry->type      == ref->type      ? ++match_lvl : match_lvl;
+		entry->direction == ref->direction ? ++match_lvl : match_lvl;
+
+		if (match_lvl == 3) {
+			/* perfect-fit - return the result */
 			return entry;
+		} else if (match_lvl > last_lvl) {
+			/*
+			 * We found an entry that fits better then the
+			 * previous one
+			 */
+			last_lvl = match_lvl;
+			ret      = entry;
+		}
 	}
 
-	return NULL;
+	/*
+	 * If we have multiple matches but no perfect-fit, just return
+	 * NULL.
+	 */
+	ret = (matches == 1) ? ret : NULL;
+
+	return ret;
 }
 
 /*
@@ -564,7 +599,7 @@ static inline bool overlap(void *addr, u
 
 	return ((addr >= start && addr < end) ||
 		(addr2 >= start && addr2 < end) ||
-		((addr < start) && (addr2 >= end)));
+		((addr < start) && (addr2 > end)));
 }
 
 static void check_for_illegal_area(struct device *dev, void *addr, u64 size)
diff -druNp linux-libre-2.6.30-gnu1/lib/genalloc.c linux-libre-2.6.30.10-gnu1/lib/genalloc.c
--- linux-libre-2.6.30-gnu1/lib/genalloc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/lib/genalloc.c	2009-12-04 01:00:07.000000000 -0500
@@ -85,7 +85,6 @@ void gen_pool_destroy(struct gen_pool *p
 	int bit, end_bit;
 
 
-	write_lock(&pool->lock);
 	list_for_each_safe(_chunk, _next_chunk, &pool->chunks) {
 		chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk);
 		list_del(&chunk->next_chunk);
diff -druNp linux-libre-2.6.30-gnu1/lib/Kconfig.debug linux-libre-2.6.30.10-gnu1/lib/Kconfig.debug
--- linux-libre-2.6.30-gnu1/lib/Kconfig.debug	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/lib/Kconfig.debug	2009-12-04 01:00:07.000000000 -0500
@@ -440,7 +440,7 @@ config LOCKDEP
 	bool
 	depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
 	select STACKTRACE
-	select FRAME_POINTER if !X86 && !MIPS && !PPC && !ARM_UNWIND && !S390
+	select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390
 	select KALLSYMS
 	select KALLSYMS_ALL
 
diff -druNp linux-libre-2.6.30-gnu1/Makefile linux-libre-2.6.30.10-gnu1/Makefile
--- linux-libre-2.6.30-gnu1/Makefile	2013-05-03 16:43:13.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/Makefile	2013-05-03 17:21:49.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 30
-EXTRAVERSION =-gnu1
+EXTRAVERSION = .10-gnu1
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
@@ -351,7 +351,8 @@ KBUILD_CPPFLAGS := -D__KERNEL__
 
 KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
 		   -fno-strict-aliasing -fno-common \
-		   -Werror-implicit-function-declaration
+		   -Werror-implicit-function-declaration \
+		   -fno-delete-null-pointer-checks
 KBUILD_AFLAGS   := -D__ASSEMBLY__
 
 # Read KERNELRELEASE from include/config/kernel.release (if it exists)
@@ -573,7 +574,7 @@ KBUILD_CFLAGS += $(call cc-option,-Wdecl
 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
 
 # disable invalid "can't wrap" optimizations for signed / pointers
-KBUILD_CFLAGS	+= $(call cc-option,-fwrapv)
+KBUILD_CFLAGS	+= $(call cc-option,-fno-strict-overflow)
 
 # revert to pre-gcc-4.4 behaviour of .eh_frame
 KBUILD_CFLAGS	+= $(call cc-option,-fno-dwarf2-cfi-asm)
diff -druNp linux-libre-2.6.30-gnu1/mm/filemap.c linux-libre-2.6.30.10-gnu1/mm/filemap.c
--- linux-libre-2.6.30-gnu1/mm/filemap.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/filemap.c	2009-12-04 01:00:07.000000000 -0500
@@ -2249,6 +2249,7 @@ again:
 		pagefault_enable();
 		flush_dcache_page(page);
 
+		mark_page_accessed(page);
 		status = a_ops->write_end(file, mapping, pos, bytes, copied,
 						page, fsdata);
 		if (unlikely(status < 0))
diff -druNp linux-libre-2.6.30-gnu1/mm/hugetlb.c linux-libre-2.6.30.10-gnu1/mm/hugetlb.c
--- linux-libre-2.6.30-gnu1/mm/hugetlb.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/hugetlb.c	2009-12-04 01:00:07.000000000 -0500
@@ -1017,6 +1017,7 @@ int __weak alloc_bootmem_huge_page(struc
 				NODE_DATA(h->hugetlb_next_nid),
 				huge_page_size(h), huge_page_size(h), 0);
 
+		hstate_next_node(h);
 		if (addr) {
 			/*
 			 * Use the beginning of the huge page to store the
@@ -1026,7 +1027,6 @@ int __weak alloc_bootmem_huge_page(struc
 			m = addr;
 			goto found;
 		}
-		hstate_next_node(h);
 		nr_nodes--;
 	}
 	return 0;
@@ -2341,7 +2341,7 @@ void hugetlb_unreserve_pages(struct inod
 	long chg = region_truncate(&inode->i_mapping->private_list, offset);
 
 	spin_lock(&inode->i_lock);
-	inode->i_blocks -= blocks_per_huge_page(h);
+	inode->i_blocks -= (blocks_per_huge_page(h) * freed);
 	spin_unlock(&inode->i_lock);
 
 	hugetlb_put_quota(inode->i_mapping, (chg - freed));
diff -druNp linux-libre-2.6.30-gnu1/mm/internal.h linux-libre-2.6.30.10-gnu1/mm/internal.h
--- linux-libre-2.6.30-gnu1/mm/internal.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/internal.h	2009-12-04 01:00:07.000000000 -0500
@@ -284,4 +284,8 @@ int __get_user_pages(struct task_struct
 		     unsigned long start, int len, int flags,
 		     struct page **pages, struct vm_area_struct **vmas);
 
+#define ZONE_RECLAIM_NOSCAN	-2
+#define ZONE_RECLAIM_FULL	-1
+#define ZONE_RECLAIM_SOME	0
+#define ZONE_RECLAIM_SUCCESS	1
 #endif
diff -druNp linux-libre-2.6.30-gnu1/mm/Kconfig linux-libre-2.6.30.10-gnu1/mm/Kconfig
--- linux-libre-2.6.30-gnu1/mm/Kconfig	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/Kconfig	2009-12-04 01:00:07.000000000 -0500
@@ -226,6 +226,25 @@ config HAVE_MLOCKED_PAGE_BIT
 config MMU_NOTIFIER
 	bool
 
+config DEFAULT_MMAP_MIN_ADDR
+        int "Low address space to protect from user allocation"
+        default 4096
+        help
+	  This is the portion of low virtual memory which should be protected
+	  from userspace allocation.  Keeping a user from writing to low pages
+	  can help reduce the impact of kernel NULL pointer bugs.
+
+	  For most ia64, ppc64 and x86 users with lots of address space
+	  a value of 65536 is reasonable and should cause no problems.
+	  On arm and other archs it should not be higher than 32768.
+	  Programs which use vm86 functionality would either need additional
+	  permissions from either the LSM or the capabilities module or have
+	  this protection disabled.
+
+	  This value can be changed after boot using the
+	  /proc/sys/vm/mmap_min_addr tunable.
+
+
 config NOMMU_INITIAL_TRIM_EXCESS
 	int "Turn on mmap() excess space trimming before booting"
 	depends on !MMU
diff -druNp linux-libre-2.6.30-gnu1/mm/memory.c linux-libre-2.6.30.10-gnu1/mm/memory.c
--- linux-libre-2.6.30-gnu1/mm/memory.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/memory.c	2009-12-04 01:00:07.000000000 -0500
@@ -2586,7 +2586,8 @@ static int do_anonymous_page(struct mm_s
 		goto oom_free_page;
 
 	entry = mk_pte(page, vma->vm_page_prot);
-	entry = maybe_mkwrite(pte_mkdirty(entry), vma);
+	if (vma->vm_flags & VM_WRITE)
+		entry = pte_mkwrite(pte_mkdirty(entry));
 
 	page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
 	if (!pte_none(*page_table))
diff -druNp linux-libre-2.6.30-gnu1/mm/mmap.c linux-libre-2.6.30.10-gnu1/mm/mmap.c
--- linux-libre-2.6.30-gnu1/mm/mmap.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/mmap.c	2009-12-04 01:00:07.000000000 -0500
@@ -87,6 +87,9 @@ int sysctl_overcommit_ratio = 50;	/* def
 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
 struct percpu_counter vm_committed_as;
 
+/* amount of vm to protect from userspace access */
+unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
+
 /*
  * Check that a process has enough memory to allocate a new virtual
  * mapping. 0 means there is enough memory for the allocation to
@@ -569,9 +572,9 @@ again:			remove_next = 1 + (end > next->
 
 	/*
 	 * When changing only vma->vm_end, we don't really need
-	 * anon_vma lock: but is that case worth optimizing out?
+	 * anon_vma lock.
 	 */
-	if (vma->anon_vma)
+	if (vma->anon_vma && (insert || importer || start != vma->vm_start))
 		anon_vma = vma->anon_vma;
 	if (anon_vma) {
 		spin_lock(&anon_vma->lock);
diff -druNp linux-libre-2.6.30-gnu1/mm/nommu.c linux-libre-2.6.30.10-gnu1/mm/nommu.c
--- linux-libre-2.6.30-gnu1/mm/nommu.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/nommu.c	2009-12-04 01:00:07.000000000 -0500
@@ -69,6 +69,9 @@ int sysctl_max_map_count = DEFAULT_MAX_M
 int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
 int heap_stack_gap = 0;
 
+/* amount of vm to protect from userspace access */
+unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
+
 atomic_long_t mmap_pages_allocated;
 
 EXPORT_SYMBOL(mem_map);
diff -druNp linux-libre-2.6.30-gnu1/mm/page_alloc.c linux-libre-2.6.30.10-gnu1/mm/page_alloc.c
--- linux-libre-2.6.30-gnu1/mm/page_alloc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/page_alloc.c	2009-12-04 01:00:07.000000000 -0500
@@ -858,7 +858,7 @@ static struct page *__rmqueue(struct zon
  */
 static int rmqueue_bulk(struct zone *zone, unsigned int order, 
 			unsigned long count, struct list_head *list,
-			int migratetype)
+			int migratetype, int cold)
 {
 	int i;
 	
@@ -877,7 +877,10 @@ static int rmqueue_bulk(struct zone *zon
 		 * merge IO requests if the physical pages are ordered
 		 * properly.
 		 */
-		list_add(&page->lru, list);
+		if (likely(cold == 0))
+			list_add(&page->lru, list);
+		else
+			list_add_tail(&page->lru, list);
 		set_page_private(page, migratetype);
 		list = &page->lru;
 	}
@@ -1077,7 +1080,8 @@ again:
 		local_irq_save(flags);
 		if (!pcp->count) {
 			pcp->count = rmqueue_bulk(zone, 0,
-					pcp->batch, &pcp->list, migratetype);
+					pcp->batch, &pcp->list,
+					migratetype, cold);
 			if (unlikely(!pcp->count))
 				goto failed;
 		}
@@ -1096,7 +1100,8 @@ again:
 		/* Allocate more to the pcp list if necessary */
 		if (unlikely(&page->lru == &pcp->list)) {
 			pcp->count += rmqueue_bulk(zone, 0,
-					pcp->batch, &pcp->list, migratetype);
+					pcp->batch, &pcp->list,
+					migratetype, cold);
 			page = list_entry(pcp->list.next, struct page, lru);
 		}
 
@@ -1420,20 +1425,38 @@ zonelist_scan:
 
 		if (!(alloc_flags & ALLOC_NO_WATERMARKS)) {
 			unsigned long mark;
+			int ret;
 			if (alloc_flags & ALLOC_WMARK_MIN)
 				mark = zone->pages_min;
 			else if (alloc_flags & ALLOC_WMARK_LOW)
 				mark = zone->pages_low;
 			else
 				mark = zone->pages_high;
-			if (!zone_watermark_ok(zone, order, mark,
-				    classzone_idx, alloc_flags)) {
-				if (!zone_reclaim_mode ||
-				    !zone_reclaim(zone, gfp_mask, order))
+
+			if (zone_watermark_ok(zone, order, mark,
+				    classzone_idx, alloc_flags))
+				goto try_this_zone;
+
+			if (zone_reclaim_mode == 0)
+				goto this_zone_full;
+
+			ret = zone_reclaim(zone, gfp_mask, order);
+			switch (ret) {
+			case ZONE_RECLAIM_NOSCAN:
+				/* did not scan */
+				goto try_next_zone;
+			case ZONE_RECLAIM_FULL:
+				/* scanned but unreclaimable */
+				goto this_zone_full;
+			default:
+				/* did we reclaim enough */
+				if (!zone_watermark_ok(zone, order, mark,
+						classzone_idx, alloc_flags))
 					goto this_zone_full;
 			}
 		}
 
+try_this_zone:
 		page = buffered_rmqueue(preferred_zone, zone, order, gfp_mask);
 		if (page)
 			break;
@@ -2319,7 +2342,6 @@ static void build_zonelists(pg_data_t *p
 	prev_node = local_node;
 	nodes_clear(used_mask);
 
-	memset(node_load, 0, sizeof(node_load));
 	memset(node_order, 0, sizeof(node_order));
 	j = 0;
 
@@ -2428,6 +2450,9 @@ static int __build_all_zonelists(void *d
 {
 	int nid;
 
+#ifdef CONFIG_NUMA
+	memset(node_load, 0, sizeof(node_load));
+#endif
 	for_each_online_node(nid) {
 		pg_data_t *pgdat = NODE_DATA(nid);
 
@@ -2812,7 +2837,7 @@ bad:
 		if (dzone == zone)
 			break;
 		kfree(zone_pcp(dzone, cpu));
-		zone_pcp(dzone, cpu) = NULL;
+		zone_pcp(dzone, cpu) = &boot_pageset[cpu];
 	}
 	return -ENOMEM;
 }
@@ -2827,7 +2852,7 @@ static inline void free_zone_pagesets(in
 		/* Free per_cpu_pageset if it is slab allocated */
 		if (pset != &boot_pageset[cpu])
 			kfree(pset);
-		zone_pcp(zone, cpu) = NULL;
+		zone_pcp(zone, cpu) = &boot_pageset[cpu];
 	}
 }
 
@@ -4501,7 +4526,7 @@ int percpu_pagelist_fraction_sysctl_hand
 	ret = proc_dointvec_minmax(table, write, file, buffer, length, ppos);
 	if (!write || (ret == -EINVAL))
 		return ret;
-	for_each_zone(zone) {
+	for_each_populated_zone(zone) {
 		for_each_online_cpu(cpu) {
 			unsigned long  high;
 			high = zone->present_pages / percpu_pagelist_fraction;
diff -druNp linux-libre-2.6.30-gnu1/mm/slab.c linux-libre-2.6.30.10-gnu1/mm/slab.c
--- linux-libre-2.6.30-gnu1/mm/slab.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/slab.c	2009-12-04 01:00:07.000000000 -0500
@@ -2592,7 +2592,7 @@ void kmem_cache_destroy(struct kmem_cach
 	}
 
 	if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU))
-		synchronize_rcu();
+		rcu_barrier();
 
 	__kmem_cache_destroy(cachep);
 	mutex_unlock(&cache_chain_mutex);
diff -druNp linux-libre-2.6.30-gnu1/mm/slob.c linux-libre-2.6.30.10-gnu1/mm/slob.c
--- linux-libre-2.6.30-gnu1/mm/slob.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/slob.c	2009-12-04 01:00:07.000000000 -0500
@@ -590,6 +590,8 @@ EXPORT_SYMBOL(kmem_cache_create);
 
 void kmem_cache_destroy(struct kmem_cache *c)
 {
+	if (c->flags & SLAB_DESTROY_BY_RCU)
+		rcu_barrier();
 	slob_free(c, sizeof(struct kmem_cache));
 }
 EXPORT_SYMBOL(kmem_cache_destroy);
diff -druNp linux-libre-2.6.30-gnu1/mm/slub.c linux-libre-2.6.30.10-gnu1/mm/slub.c
--- linux-libre-2.6.30-gnu1/mm/slub.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/slub.c	2009-12-04 01:00:07.000000000 -0500
@@ -2500,6 +2500,8 @@ void kmem_cache_destroy(struct kmem_cach
 				"still has objects.\n", s->name, __func__);
 			dump_stack();
 		}
+		if (s->flags & SLAB_DESTROY_BY_RCU)
+			rcu_barrier();
 		sysfs_slab_remove(s);
 	} else
 		up_write(&slub_lock);
diff -druNp linux-libre-2.6.30-gnu1/mm/vmscan.c linux-libre-2.6.30.10-gnu1/mm/vmscan.c
--- linux-libre-2.6.30-gnu1/mm/vmscan.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/vmscan.c	2009-12-04 01:00:07.000000000 -0500
@@ -2290,6 +2290,48 @@ int sysctl_min_unmapped_ratio = 1;
  */
 int sysctl_min_slab_ratio = 5;
 
+static inline unsigned long zone_unmapped_file_pages(struct zone *zone)
+{
+	unsigned long file_mapped = zone_page_state(zone, NR_FILE_MAPPED);
+	unsigned long file_lru = zone_page_state(zone, NR_INACTIVE_FILE) +
+		zone_page_state(zone, NR_ACTIVE_FILE);
+
+	/*
+	 * It's possible for there to be more file mapped pages than
+	 * accounted for by the pages on the file LRU lists because
+	 * tmpfs pages accounted for as ANON can also be FILE_MAPPED
+	 */
+	return (file_lru > file_mapped) ? (file_lru - file_mapped) : 0;
+}
+
+/* Work out how many page cache pages we can reclaim in this reclaim_mode */
+static long zone_pagecache_reclaimable(struct zone *zone)
+{
+	long nr_pagecache_reclaimable;
+	long delta = 0;
+
+	/*
+	 * If RECLAIM_SWAP is set, then all file pages are considered
+	 * potentially reclaimable. Otherwise, we have to worry about
+	 * pages like swapcache and zone_unmapped_file_pages() provides
+	 * a better estimate
+	 */
+	if (zone_reclaim_mode & RECLAIM_SWAP)
+		nr_pagecache_reclaimable = zone_page_state(zone, NR_FILE_PAGES);
+	else
+		nr_pagecache_reclaimable = zone_unmapped_file_pages(zone);
+
+	/* If we can't clean pages, remove dirty pages from consideration */
+	if (!(zone_reclaim_mode & RECLAIM_WRITE))
+		delta += zone_page_state(zone, NR_FILE_DIRTY);
+
+	/* Watch for any possible underflows due to delta */
+	if (unlikely(delta > nr_pagecache_reclaimable))
+		delta = nr_pagecache_reclaimable;
+
+	return nr_pagecache_reclaimable - delta;
+}
+
 /*
  * Try to free up some pages from this zone through reclaim.
  */
@@ -2324,9 +2366,7 @@ static int __zone_reclaim(struct zone *z
 	reclaim_state.reclaimed_slab = 0;
 	p->reclaim_state = &reclaim_state;
 
-	if (zone_page_state(zone, NR_FILE_PAGES) -
-		zone_page_state(zone, NR_FILE_MAPPED) >
-		zone->min_unmapped_pages) {
+	if (zone_pagecache_reclaimable(zone) > zone->min_unmapped_pages) {
 		/*
 		 * Free memory by calling shrink zone with increasing
 		 * priorities until we have enough memory freed.
@@ -2384,20 +2424,18 @@ int zone_reclaim(struct zone *zone, gfp_
 	 * if less than a specified percentage of the zone is used by
 	 * unmapped file backed pages.
 	 */
-	if (zone_page_state(zone, NR_FILE_PAGES) -
-	    zone_page_state(zone, NR_FILE_MAPPED) <= zone->min_unmapped_pages
-	    && zone_page_state(zone, NR_SLAB_RECLAIMABLE)
-			<= zone->min_slab_pages)
-		return 0;
+	if (zone_pagecache_reclaimable(zone) <= zone->min_unmapped_pages &&
+	    zone_page_state(zone, NR_SLAB_RECLAIMABLE) <= zone->min_slab_pages)
+		return ZONE_RECLAIM_FULL;
 
 	if (zone_is_all_unreclaimable(zone))
-		return 0;
+		return ZONE_RECLAIM_FULL;
 
 	/*
 	 * Do not scan if the allocation should not be delayed.
 	 */
 	if (!(gfp_mask & __GFP_WAIT) || (current->flags & PF_MEMALLOC))
-			return 0;
+		return ZONE_RECLAIM_NOSCAN;
 
 	/*
 	 * Only run zone reclaim on the local zone or on zones that do not
@@ -2407,13 +2445,17 @@ int zone_reclaim(struct zone *zone, gfp_
 	 */
 	node_id = zone_to_nid(zone);
 	if (node_state(node_id, N_CPU) && node_id != numa_node_id())
-		return 0;
+		return ZONE_RECLAIM_NOSCAN;
 
 	if (zone_test_and_set_flag(zone, ZONE_RECLAIM_LOCKED))
-		return 0;
+		return ZONE_RECLAIM_NOSCAN;
+
 	ret = __zone_reclaim(zone, gfp_mask, order);
 	zone_clear_flag(zone, ZONE_RECLAIM_LOCKED);
 
+	if (!ret)
+		count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED);
+
 	return ret;
 }
 #endif
diff -druNp linux-libre-2.6.30-gnu1/mm/vmstat.c linux-libre-2.6.30.10-gnu1/mm/vmstat.c
--- linux-libre-2.6.30-gnu1/mm/vmstat.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/mm/vmstat.c	2009-12-04 01:00:07.000000000 -0500
@@ -675,6 +675,9 @@ static const char * const vmstat_text[]
 	TEXTS_FOR_ZONES("pgscan_kswapd")
 	TEXTS_FOR_ZONES("pgscan_direct")
 
+#ifdef CONFIG_NUMA
+	"zone_reclaim_failed",
+#endif
 	"pginodesteal",
 	"slabs_scanned",
 	"kswapd_steal",
diff -druNp linux-libre-2.6.30-gnu1/net/appletalk/ddp.c linux-libre-2.6.30.10-gnu1/net/appletalk/ddp.c
--- linux-libre-2.6.30-gnu1/net/appletalk/ddp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/appletalk/ddp.c	2009-12-04 01:00:07.000000000 -0500
@@ -1242,6 +1242,7 @@ static int atalk_getname(struct socket *
 			return -ENOBUFS;
 
 	*uaddr_len = sizeof(struct sockaddr_at);
+	memset(&sat.sat_zero, 0, sizeof(sat.sat_zero));
 
 	if (peer) {
 		if (sk->sk_state != TCP_ESTABLISHED)
diff -druNp linux-libre-2.6.30-gnu1/net/ax25/af_ax25.c linux-libre-2.6.30.10-gnu1/net/ax25/af_ax25.c
--- linux-libre-2.6.30-gnu1/net/ax25/af_ax25.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ax25/af_ax25.c	2009-12-04 01:00:07.000000000 -0500
@@ -539,7 +539,7 @@ static int ax25_setsockopt(struct socket
 	if (level != SOL_AX25)
 		return -ENOPROTOOPT;
 
-	if (optlen < sizeof(int))
+	if (optlen < (int)sizeof(int))
 		return -EINVAL;
 
 	if (get_user(opt, (int __user *)optval))
diff -druNp linux-libre-2.6.30-gnu1/net/ax25/ax25_in.c linux-libre-2.6.30.10-gnu1/net/ax25/ax25_in.c
--- linux-libre-2.6.30-gnu1/net/ax25/ax25_in.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ax25/ax25_in.c	2009-12-04 01:00:07.000000000 -0500
@@ -437,8 +437,7 @@ free:
 int ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
 		  struct packet_type *ptype, struct net_device *orig_dev)
 {
-	skb->sk = NULL;		/* Initially we don't know who it's for */
-	skb->destructor = NULL;	/* Who initializes this, dammit?! */
+	skb_orphan(skb);
 
 	if (!net_eq(dev_net(dev), &init_net)) {
 		kfree_skb(skb);
diff -druNp linux-libre-2.6.30-gnu1/net/bridge/br_netfilter.c linux-libre-2.6.30.10-gnu1/net/bridge/br_netfilter.c
--- linux-libre-2.6.30-gnu1/net/bridge/br_netfilter.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/bridge/br_netfilter.c	2009-12-04 01:00:07.000000000 -0500
@@ -357,7 +357,7 @@ static int br_nf_pre_routing_finish(stru
 				},
 				.proto = 0,
 			};
-			struct in_device *in_dev = in_dev_get(dev);
+			struct in_device *in_dev = __in_dev_get_rcu(dev);
 
 			/* If err equals -EHOSTUNREACH the error is due to a
 			 * martian destination or due to the fact that
diff -druNp linux-libre-2.6.30-gnu1/net/bridge/netfilter/ebt_ulog.c linux-libre-2.6.30.10-gnu1/net/bridge/netfilter/ebt_ulog.c
--- linux-libre-2.6.30-gnu1/net/bridge/netfilter/ebt_ulog.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/bridge/netfilter/ebt_ulog.c	2009-12-04 01:00:07.000000000 -0500
@@ -266,7 +266,7 @@ static bool ebt_ulog_tg_check(const stru
 	if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
 		uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
 
-	return 0;
+	return true;
 }
 
 static struct xt_target ebt_ulog_tg_reg __read_mostly = {
diff -druNp linux-libre-2.6.30-gnu1/net/can/raw.c linux-libre-2.6.30.10-gnu1/net/can/raw.c
--- linux-libre-2.6.30-gnu1/net/can/raw.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/can/raw.c	2009-12-04 01:00:07.000000000 -0500
@@ -397,6 +397,7 @@ static int raw_getname(struct socket *so
 	if (peer)
 		return -EOPNOTSUPP;
 
+	memset(addr, 0, sizeof(*addr));
 	addr->can_family  = AF_CAN;
 	addr->can_ifindex = ro->ifindex;
 
diff -druNp linux-libre-2.6.30-gnu1/net/core/dev.c linux-libre-2.6.30.10-gnu1/net/core/dev.c
--- linux-libre-2.6.30-gnu1/net/core/dev.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/core/dev.c	2009-12-04 01:00:07.000000000 -0500
@@ -2284,8 +2284,6 @@ ncls:
 	if (!skb)
 		goto out;
 
-	skb_orphan(skb);
-
 	type = skb->protocol;
 	list_for_each_entry_rcu(ptype,
 			&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
@@ -2788,9 +2786,11 @@ static void net_rx_action(struct softirq
 		 * move the instance around on the list at-will.
 		 */
 		if (unlikely(work == weight)) {
-			if (unlikely(napi_disable_pending(n)))
-				__napi_complete(n);
-			else
+			if (unlikely(napi_disable_pending(n))) {
+				local_irq_enable();
+				napi_complete(n);
+				local_irq_disable();
+			} else
 				list_move_tail(&n->poll_list, list);
 		}
 
diff -druNp linux-libre-2.6.30-gnu1/net/core/net_namespace.c linux-libre-2.6.30.10-gnu1/net/core/net_namespace.c
--- linux-libre-2.6.30-gnu1/net/core/net_namespace.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/core/net_namespace.c	2009-12-04 01:00:07.000000000 -0500
@@ -498,7 +498,7 @@ int net_assign_generic(struct net *net,
 	 */
 
 	ng->len = id;
-	memcpy(&ng->ptr, &old_ng->ptr, old_ng->len);
+	memcpy(&ng->ptr, &old_ng->ptr, old_ng->len * sizeof(void*));
 
 	rcu_assign_pointer(net->gen, ng);
 	call_rcu(&old_ng->rcu, net_generic_release);
diff -druNp linux-libre-2.6.30-gnu1/net/core/sock.c linux-libre-2.6.30.10-gnu1/net/core/sock.c
--- linux-libre-2.6.30-gnu1/net/core/sock.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/core/sock.c	2009-12-04 01:00:07.000000000 -0500
@@ -915,13 +915,19 @@ static inline void sock_lock_init(struct
 			af_family_keys + sk->sk_family);
 }
 
+/*
+ * Copy all fields from osk to nsk but nsk->sk_refcnt must not change yet,
+ * even temporarly, because of RCU lookups. sk_node should also be left as is.
+ */
 static void sock_copy(struct sock *nsk, const struct sock *osk)
 {
 #ifdef CONFIG_SECURITY_NETWORK
 	void *sptr = nsk->sk_security;
 #endif
-
-	memcpy(nsk, osk, osk->sk_prot->obj_size);
+	BUILD_BUG_ON(offsetof(struct sock, sk_copy_start) !=
+		     sizeof(osk->sk_node) + sizeof(osk->sk_refcnt));
+	memcpy(&nsk->sk_copy_start, &osk->sk_copy_start,
+	       osk->sk_prot->obj_size - offsetof(struct sock, sk_copy_start));
 #ifdef CONFIG_SECURITY_NETWORK
 	nsk->sk_security = sptr;
 	security_sk_clone(osk, nsk);
@@ -935,8 +941,23 @@ static struct sock *sk_prot_alloc(struct
 	struct kmem_cache *slab;
 
 	slab = prot->slab;
-	if (slab != NULL)
-		sk = kmem_cache_alloc(slab, priority);
+	if (slab != NULL) {
+		sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
+		if (!sk)
+			return sk;
+		if (priority & __GFP_ZERO) {
+			/*
+			 * caches using SLAB_DESTROY_BY_RCU should let
+			 * sk_node.next un-modified. Special care is taken
+			 * when initializing object to zero.
+			 */
+			if (offsetof(struct sock, sk_node.next) != 0)
+				memset(sk, 0, offsetof(struct sock, sk_node.next));
+			memset(&sk->sk_node.pprev, 0,
+			       prot->obj_size - offsetof(struct sock,
+							 sk_node.pprev));
+		}
+	}
 	else
 		sk = kmalloc(prot->obj_size, priority);
 
@@ -1103,6 +1124,11 @@ struct sock *sk_clone(const struct sock
 
 		newsk->sk_err	   = 0;
 		newsk->sk_priority = 0;
+		/*
+		 * Before updating sk_refcnt, we must commit prior changes to memory
+		 * (Documentation/RCU/rculist_nulls.txt for details)
+		 */
+		smp_wmb();
 		atomic_set(&newsk->sk_refcnt, 2);
 
 		/*
@@ -1794,6 +1820,11 @@ void sock_init_data(struct socket *sock,
 
 	sk->sk_stamp = ktime_set(-1L, 0);
 
+	/*
+	 * Before updating sk_refcnt, we must commit prior changes to memory
+	 * (Documentation/RCU/rculist_nulls.txt for details)
+	 */
+	smp_wmb();
 	atomic_set(&sk->sk_refcnt, 1);
 	atomic_set(&sk->sk_drops, 0);
 }
diff -druNp linux-libre-2.6.30-gnu1/net/dccp/proto.c linux-libre-2.6.30.10-gnu1/net/dccp/proto.c
--- linux-libre-2.6.30-gnu1/net/dccp/proto.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/dccp/proto.c	2009-12-04 01:00:07.000000000 -0500
@@ -1159,6 +1159,7 @@ static void __exit dccp_fini(void)
 	kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
 	dccp_ackvec_exit();
 	dccp_sysctl_exit();
+	percpu_counter_destroy(&dccp_orphan_count);
 }
 
 module_init(dccp_init);
diff -druNp linux-libre-2.6.30-gnu1/net/dsa/mv88e6xxx.c linux-libre-2.6.30.10-gnu1/net/dsa/mv88e6xxx.c
--- linux-libre-2.6.30-gnu1/net/dsa/mv88e6xxx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/dsa/mv88e6xxx.c	2009-12-04 01:00:07.000000000 -0500
@@ -418,7 +418,7 @@ static int mv88e6xxx_stats_wait(struct d
 	int i;
 
 	for (i = 0; i < 10; i++) {
-		ret = REG_READ(REG_GLOBAL2, 0x1d);
+		ret = REG_READ(REG_GLOBAL, 0x1d);
 		if ((ret & 0x8000) == 0)
 			return 0;
 	}
diff -druNp linux-libre-2.6.30-gnu1/net/econet/af_econet.c linux-libre-2.6.30.10-gnu1/net/econet/af_econet.c
--- linux-libre-2.6.30-gnu1/net/econet/af_econet.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/econet/af_econet.c	2009-12-04 01:00:07.000000000 -0500
@@ -520,6 +520,7 @@ static int econet_getname(struct socket
 	if (peer)
 		return -EOPNOTSUPP;
 
+	memset(sec, 0, sizeof(*sec));
 	mutex_lock(&econet_mutex);
 
 	sk = sock->sk;
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/arp.c linux-libre-2.6.30.10-gnu1/net/ipv4/arp.c
--- linux-libre-2.6.30-gnu1/net/ipv4/arp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/arp.c	2009-12-04 01:00:07.000000000 -0500
@@ -801,11 +801,8 @@ static int arp_process(struct sk_buff *s
  *  cache.
  */
 
-	/*
-	 *  Special case: IPv4 duplicate address detection packet (RFC2131)
-	 *  and Gratuitous ARP/ARP Announce. (RFC3927, Section 2.4)
-	 */
-	if (sip == 0 || tip == sip) {
+	/* Special case: IPv4 duplicate address detection packet (RFC2131) */
+	if (sip == 0) {
 		if (arp->ar_op == htons(ARPOP_REQUEST) &&
 		    inet_addr_type(net, tip) == RTN_LOCAL &&
 		    !arp_ignore(in_dev, sip, tip))
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/ip_fragment.c linux-libre-2.6.30.10-gnu1/net/ipv4/ip_fragment.c
--- linux-libre-2.6.30-gnu1/net/ipv4/ip_fragment.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/ip_fragment.c	2009-12-04 01:00:07.000000000 -0500
@@ -563,7 +563,7 @@ out_oversize:
 		printk(KERN_INFO "Oversized IP packet from %pI4.\n",
 			&qp->saddr);
 out_fail:
-	IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
+	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
 	return err;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/ip_gre.c linux-libre-2.6.30.10-gnu1/net/ipv4/ip_gre.c
--- linux-libre-2.6.30-gnu1/net/ipv4/ip_gre.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/ip_gre.c	2009-12-04 01:00:07.000000000 -0500
@@ -952,7 +952,7 @@ static int ipgre_tunnel_bind_dev(struct
 			addend += 4;
 	}
 	dev->needed_headroom = addend + hlen;
-	mtu -= dev->hard_header_len - addend;
+	mtu -= dev->hard_header_len + addend;
 
 	if (mtu < 68)
 		mtu = 68;
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/ip_input.c linux-libre-2.6.30.10-gnu1/net/ipv4/ip_input.c
--- linux-libre-2.6.30-gnu1/net/ipv4/ip_input.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/ip_input.c	2009-12-04 01:00:07.000000000 -0500
@@ -437,6 +437,9 @@ int ip_rcv(struct sk_buff *skb, struct n
 	/* Remove any debris in the socket control block */
 	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
 
+	/* Must drop socket now because of tproxy. */
+	skb_orphan(skb);
+
 	return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL,
 		       ip_rcv_finish);
 
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/ip_output.c linux-libre-2.6.30.10-gnu1/net/ipv4/ip_output.c
--- linux-libre-2.6.30-gnu1/net/ipv4/ip_output.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/ip_output.c	2009-12-04 01:00:07.000000000 -0500
@@ -814,6 +814,8 @@ int ip_append_data(struct sock *sk,
 			inet->cork.addr = ipc->addr;
 		}
 		rt = *rtp;
+		if (unlikely(!rt))
+			return -EFAULT;
 		/*
 		 * We steal reference to this route, caller should not release it
 		 */
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/netfilter/nf_nat_core.c linux-libre-2.6.30.10-gnu1/net/ipv4/netfilter/nf_nat_core.c
--- linux-libre-2.6.30-gnu1/net/ipv4/netfilter/nf_nat_core.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/netfilter/nf_nat_core.c	2009-12-04 01:00:07.000000000 -0500
@@ -212,7 +212,7 @@ find_best_ips_proto(struct nf_conntrack_
 	maxip = ntohl(range->max_ip);
 	j = jhash_2words((__force u32)tuple->src.u3.ip,
 			 range->flags & IP_NAT_RANGE_PERSISTENT ?
-				(__force u32)tuple->dst.u3.ip : 0, 0);
+				0 : (__force u32)tuple->dst.u3.ip, 0);
 	j = ((u64)j * (maxip - minip + 1)) >> 32;
 	*var_ipp = htonl(minip + j);
 }
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/netfilter/nf_nat_helper.c linux-libre-2.6.30.10-gnu1/net/ipv4/netfilter/nf_nat_helper.c
--- linux-libre-2.6.30-gnu1/net/ipv4/netfilter/nf_nat_helper.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/netfilter/nf_nat_helper.c	2009-12-04 01:00:07.000000000 -0500
@@ -191,7 +191,8 @@ nf_nat_mangle_tcp_packet(struct sk_buff
 				    ct, ctinfo);
 		/* Tell TCP window tracking about seq change */
 		nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
-					ct, CTINFO2DIR(ctinfo));
+					ct, CTINFO2DIR(ctinfo),
+					(int)rep_len - (int)match_len);
 
 		nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
 	}
@@ -377,6 +378,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
 	struct tcphdr *tcph;
 	int dir;
 	__be32 newseq, newack;
+	s16 seqoff, ackoff;
 	struct nf_conn_nat *nat = nfct_nat(ct);
 	struct nf_nat_seq *this_way, *other_way;
 
@@ -390,15 +392,18 @@ nf_nat_seq_adjust(struct sk_buff *skb,
 
 	tcph = (void *)skb->data + ip_hdrlen(skb);
 	if (after(ntohl(tcph->seq), this_way->correction_pos))
-		newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
+		seqoff = this_way->offset_after;
 	else
-		newseq = htonl(ntohl(tcph->seq) + this_way->offset_before);
+		seqoff = this_way->offset_before;
 
 	if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
 		  other_way->correction_pos))
-		newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after);
+		ackoff = other_way->offset_after;
 	else
-		newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
+		ackoff = other_way->offset_before;
+
+	newseq = htonl(ntohl(tcph->seq) + seqoff);
+	newack = htonl(ntohl(tcph->ack_seq) - ackoff);
 
 	inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0);
 	inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0);
@@ -413,7 +418,7 @@ nf_nat_seq_adjust(struct sk_buff *skb,
 	if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo))
 		return 0;
 
-	nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir);
+	nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff);
 
 	return 1;
 }
diff -druNp linux-libre-2.6.30-gnu1/net/ipv4/route.c linux-libre-2.6.30.10-gnu1/net/ipv4/route.c
--- linux-libre-2.6.30-gnu1/net/ipv4/route.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv4/route.c	2009-12-04 01:00:07.000000000 -0500
@@ -1081,8 +1081,35 @@ restart:
 	now = jiffies;
 
 	if (!rt_caching(dev_net(rt->u.dst.dev))) {
-		rt_drop(rt);
-		return 0;
+		/*
+		 * If we're not caching, just tell the caller we
+		 * were successful and don't touch the route.  The
+		 * caller hold the sole reference to the cache entry, and
+		 * it will be released when the caller is done with it.
+		 * If we drop it here, the callers have no way to resolve routes
+		 * when we're not caching.  Instead, just point *rp at rt, so
+		 * the caller gets a single use out of the route
+		 * Note that we do rt_free on this new route entry, so that
+		 * once its refcount hits zero, we are still able to reap it
+		 * (Thanks Alexey)
+		 * Note also the rt_free uses call_rcu.  We don't actually
+		 * need rcu protection here, this is just our path to get
+		 * on the route gc list.
+		 */
+
+		if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) {
+			int err = arp_bind_neighbour(&rt->u.dst);
+			if (err) {
+				if (net_ratelimit())
+					printk(KERN_WARNING
+					    "Neighbour table failure & not caching routes.\n");
+				rt_drop(rt);
+				return err;
+			}
+		}
+
+		rt_free(rt);
+		goto skip_hashing;
 	}
 
 	rthp = &rt_hash_table[hash].chain;
@@ -1196,7 +1223,8 @@ restart:
 #if RT_CACHE_DEBUG >= 2
 	if (rt->u.dst.rt_next) {
 		struct rtable *trt;
-		printk(KERN_DEBUG "rt_cache @%02x: %pI4", hash, &rt->rt_dst);
+		printk(KERN_DEBUG "rt_cache @%02x: %pI4",
+		       hash, &rt->rt_dst);
 		for (trt = rt->u.dst.rt_next; trt; trt = trt->u.dst.rt_next)
 			printk(" . %pI4", &trt->rt_dst);
 		printk("\n");
@@ -1210,6 +1238,8 @@ restart:
 	rcu_assign_pointer(rt_hash_table[hash].chain, rt);
 
 	spin_unlock_bh(rt_hash_lock_addr(hash));
+
+skip_hashing:
 	*rp = rt;
 	return 0;
 }
diff -druNp linux-libre-2.6.30-gnu1/net/ipv6/af_inet6.c linux-libre-2.6.30.10-gnu1/net/ipv6/af_inet6.c
--- linux-libre-2.6.30-gnu1/net/ipv6/af_inet6.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv6/af_inet6.c	2009-12-04 01:00:07.000000000 -0500
@@ -294,8 +294,10 @@ int inet6_bind(struct socket *sock, stru
 		    v4addr != htonl(INADDR_ANY) &&
 		    chk_addr_ret != RTN_LOCAL &&
 		    chk_addr_ret != RTN_MULTICAST &&
-		    chk_addr_ret != RTN_BROADCAST)
+		    chk_addr_ret != RTN_BROADCAST) {
+			err = -EADDRNOTAVAIL;
 			goto out;
+		}
 	} else {
 		if (addr_type != IPV6_ADDR_ANY) {
 			struct net_device *dev = NULL;
diff -druNp linux-libre-2.6.30-gnu1/net/ipv6/ip6_input.c linux-libre-2.6.30.10-gnu1/net/ipv6/ip6_input.c
--- linux-libre-2.6.30-gnu1/net/ipv6/ip6_input.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/ipv6/ip6_input.c	2009-12-04 01:00:07.000000000 -0500
@@ -139,6 +139,9 @@ int ipv6_rcv(struct sk_buff *skb, struct
 
 	rcu_read_unlock();
 
+	/* Must drop socket now because of tproxy. */
+	skb_orphan(skb);
+
 	return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL,
 		       ip6_rcv_finish);
 err:
diff -druNp linux-libre-2.6.30-gnu1/net/irda/af_irda.c linux-libre-2.6.30.10-gnu1/net/irda/af_irda.c
--- linux-libre-2.6.30-gnu1/net/irda/af_irda.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/irda/af_irda.c	2009-12-04 01:00:07.000000000 -0500
@@ -714,6 +714,7 @@ static int irda_getname(struct socket *s
 	struct sock *sk = sock->sk;
 	struct irda_sock *self = irda_sk(sk);
 
+	memset(&saddr, 0, sizeof(saddr));
 	if (peer) {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -ENOTCONN;
@@ -913,9 +914,6 @@ static int irda_accept(struct socket *so
 	/* Clean up the original one to keep it in listen state */
 	irttp_listen(self->tsap);
 
-	/* Wow ! What is that ? Jean II */
-	skb->sk = NULL;
-	skb->destructor = NULL;
 	kfree_skb(skb);
 	sk->sk_ack_backlog--;
 
diff -druNp linux-libre-2.6.30-gnu1/net/irda/ircomm/ircomm_lmp.c linux-libre-2.6.30.10-gnu1/net/irda/ircomm/ircomm_lmp.c
--- linux-libre-2.6.30-gnu1/net/irda/ircomm/ircomm_lmp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/irda/ircomm/ircomm_lmp.c	2009-12-04 01:00:07.000000000 -0500
@@ -196,6 +196,7 @@ static int ircomm_lmp_data_request(struc
 	/* Don't forget to refcount it - see ircomm_tty_do_softint() */
 	skb_get(skb);
 
+	skb_orphan(skb);
 	skb->destructor = ircomm_lmp_flow_control;
 
 	if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) {
diff -druNp linux-libre-2.6.30-gnu1/net/llc/af_llc.c linux-libre-2.6.30.10-gnu1/net/llc/af_llc.c
--- linux-libre-2.6.30-gnu1/net/llc/af_llc.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/llc/af_llc.c	2009-12-04 01:00:07.000000000 -0500
@@ -914,6 +914,7 @@ static int llc_ui_getname(struct socket
 	struct llc_sock *llc = llc_sk(sk);
 	int rc = 0;
 
+	memset(&sllc, 0, sizeof(sllc));
 	lock_sock(sk);
 	if (sock_flag(sk, SOCK_ZAPPED))
 		goto out;
diff -druNp linux-libre-2.6.30-gnu1/net/mac80211/agg-tx.c linux-libre-2.6.30.10-gnu1/net/mac80211/agg-tx.c
--- linux-libre-2.6.30-gnu1/net/mac80211/agg-tx.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/mac80211/agg-tx.c	2009-12-04 01:00:07.000000000 -0500
@@ -376,6 +376,14 @@ static void ieee80211_agg_splice_packets
 		&local->hw, queue,
 		IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
 
+	if (!(sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK))
+		return;
+
+	if (WARN(!sta->ampdu_mlme.tid_tx[tid],
+		 "TID %d gone but expected when splicing aggregates from"
+		 "the pending queue\n", tid))
+		return;
+
 	if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
 		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
 		/* mark queue as pending, it is stopped already */
diff -druNp linux-libre-2.6.30-gnu1/net/mac80211/rc80211_minstrel.c linux-libre-2.6.30.10-gnu1/net/mac80211/rc80211_minstrel.c
--- linux-libre-2.6.30-gnu1/net/mac80211/rc80211_minstrel.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/mac80211/rc80211_minstrel.c	2009-12-04 01:00:07.000000000 -0500
@@ -216,7 +216,7 @@ minstrel_get_next_sample(struct minstrel
 	unsigned int sample_ndx;
 	sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
 	mi->sample_idx++;
-	if (mi->sample_idx > (mi->n_rates - 2)) {
+	if ((int) mi->sample_idx > (mi->n_rates - 2)) {
 		mi->sample_idx = 0;
 		mi->sample_column++;
 		if (mi->sample_column >= SAMPLE_COLUMNS)
diff -druNp linux-libre-2.6.30-gnu1/net/netfilter/nf_conntrack_core.c linux-libre-2.6.30.10-gnu1/net/netfilter/nf_conntrack_core.c
--- linux-libre-2.6.30-gnu1/net/netfilter/nf_conntrack_core.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netfilter/nf_conntrack_core.c	2009-12-04 01:00:07.000000000 -0500
@@ -295,7 +295,8 @@ begin:
 	h = __nf_conntrack_find(net, tuple);
 	if (h) {
 		ct = nf_ct_tuplehash_to_ctrack(h);
-		if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+		if (unlikely(nf_ct_is_dying(ct) ||
+			     !atomic_inc_not_zero(&ct->ct_general.use)))
 			h = NULL;
 		else {
 			if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple))) {
@@ -385,7 +386,6 @@ __nf_conntrack_confirm(struct sk_buff *s
 	/* Remove from unconfirmed list */
 	hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
 
-	__nf_conntrack_hash_insert(ct, hash, repl_hash);
 	/* Timer relative to confirmation time, not original
 	   setting time, otherwise we'd get timer wrap in
 	   weird delay cases. */
@@ -393,8 +393,16 @@ __nf_conntrack_confirm(struct sk_buff *s
 	add_timer(&ct->timeout);
 	atomic_inc(&ct->ct_general.use);
 	set_bit(IPS_CONFIRMED_BIT, &ct->status);
+
+	/* Since the lookup is lockless, hash insertion must be done after
+	 * starting the timer and setting the CONFIRMED bit. The RCU barriers
+	 * guarantee that no other CPU can find the conntrack before the above
+	 * stores are visible.
+	 */
+	__nf_conntrack_hash_insert(ct, hash, repl_hash);
 	NF_CT_STAT_INC(net, insert);
 	spin_unlock_bh(&nf_conntrack_lock);
+
 	help = nfct_help(ct);
 	if (help && help->helper)
 		nf_conntrack_event_cache(IPCT_HELPER, ct);
@@ -467,7 +475,8 @@ static noinline int early_drop(struct ne
 			cnt++;
 		}
 
-		if (ct && unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
+		if (ct && unlikely(nf_ct_is_dying(ct) ||
+				   !atomic_inc_not_zero(&ct->ct_general.use)))
 			ct = NULL;
 		if (ct || cnt >= NF_CT_EVICTION_RANGE)
 			break;
@@ -516,22 +525,37 @@ struct nf_conn *nf_conntrack_alloc(struc
 		}
 	}
 
-	ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp);
+	/*
+	 * Do not use kmem_cache_zalloc(), as this cache uses
+	 * SLAB_DESTROY_BY_RCU.
+	 */
+	ct = kmem_cache_alloc(nf_conntrack_cachep, gfp);
 	if (ct == NULL) {
 		pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
 		atomic_dec(&net->ct.count);
 		return ERR_PTR(-ENOMEM);
 	}
-
-	atomic_set(&ct->ct_general.use, 1);
+	/*
+	 * Let ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.next
+	 * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged.
+	 */
+	memset(&ct->tuplehash[IP_CT_DIR_MAX], 0,
+	       sizeof(*ct) - offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX]));
 	ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
+	ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
 	ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
+	ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL;
 	/* Don't set timer yet: wait for confirmation */
 	setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
 #ifdef CONFIG_NET_NS
 	ct->ct_net = net;
 #endif
 
+	/*
+	 * changes to lookup keys must be done before setting refcnt to 1
+	 */
+	smp_wmb();
+	atomic_set(&ct->ct_general.use, 1);
 	return ct;
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
diff -druNp linux-libre-2.6.30-gnu1/net/netfilter/nf_conntrack_proto_tcp.c linux-libre-2.6.30.10-gnu1/net/netfilter/nf_conntrack_proto_tcp.c
--- linux-libre-2.6.30-gnu1/net/netfilter/nf_conntrack_proto_tcp.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netfilter/nf_conntrack_proto_tcp.c	2009-12-04 01:00:07.000000000 -0500
@@ -706,8 +706,8 @@ static bool tcp_in_window(const struct n
 /* Caller must linearize skb at tcp header. */
 void nf_conntrack_tcp_update(const struct sk_buff *skb,
 			     unsigned int dataoff,
-			     struct nf_conn *ct,
-			     int dir)
+			     struct nf_conn *ct, int dir,
+			     s16 offset)
 {
 	const struct tcphdr *tcph = (const void *)skb->data + dataoff;
 	const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir];
@@ -720,7 +720,7 @@ void nf_conntrack_tcp_update(const struc
 	/*
 	 * We have to worry for the ack in the reply packet only...
 	 */
-	if (after(end, ct->proto.tcp.seen[dir].td_end))
+	if (ct->proto.tcp.seen[dir].td_end + offset == end)
 		ct->proto.tcp.seen[dir].td_end = end;
 	ct->proto.tcp.last_end = end;
 	write_unlock_bh(&tcp_lock);
diff -druNp linux-libre-2.6.30-gnu1/net/netfilter/nf_log.c linux-libre-2.6.30.10-gnu1/net/netfilter/nf_log.c
--- linux-libre-2.6.30-gnu1/net/netfilter/nf_log.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netfilter/nf_log.c	2009-12-04 01:00:07.000000000 -0500
@@ -47,7 +47,6 @@ int nf_log_register(u_int8_t pf, struct
 	mutex_lock(&nf_log_mutex);
 
 	if (pf == NFPROTO_UNSPEC) {
-		int i;
 		for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
 			list_add_tail(&(logger->list[i]), &(nf_loggers_l[i]));
 	} else {
@@ -216,7 +215,7 @@ static const struct file_operations nflo
 #endif /* PROC_FS */
 
 #ifdef CONFIG_SYSCTL
-struct ctl_path nf_log_sysctl_path[] = {
+static struct ctl_path nf_log_sysctl_path[] = {
 	{ .procname = "net", .ctl_name = CTL_NET, },
 	{ .procname = "netfilter", .ctl_name = NET_NETFILTER, },
 	{ .procname = "nf_log", .ctl_name = CTL_UNNUMBERED, },
@@ -228,19 +227,26 @@ static struct ctl_table nf_log_sysctl_ta
 static struct ctl_table_header *nf_log_dir_header;
 
 static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp,
-			 void *buffer, size_t *lenp, loff_t *ppos)
+			 void __user *buffer, size_t *lenp, loff_t *ppos)
 {
 	const struct nf_logger *logger;
+	char buf[NFLOGGER_NAME_LEN];
+	size_t size = *lenp;
 	int r = 0;
 	int tindex = (unsigned long)table->extra1;
 
 	if (write) {
-		if (!strcmp(buffer, "NONE")) {
+		if (size > sizeof(buf))
+			size = sizeof(buf);
+		if (copy_from_user(buf, buffer, size))
+			return -EFAULT;
+
+		if (!strcmp(buf, "NONE")) {
 			nf_log_unbind_pf(tindex);
 			return 0;
 		}
 		mutex_lock(&nf_log_mutex);
-		logger = __find_logger(tindex, buffer);
+		logger = __find_logger(tindex, buf);
 		if (logger == NULL) {
 			mutex_unlock(&nf_log_mutex);
 			return -ENOENT;
@@ -248,14 +254,14 @@ static int nf_log_proc_dostring(ctl_tabl
 		rcu_assign_pointer(nf_loggers[tindex], logger);
 		mutex_unlock(&nf_log_mutex);
 	} else {
-		rcu_read_lock();
-		logger = rcu_dereference(nf_loggers[tindex]);
+		mutex_lock(&nf_log_mutex);
+		logger = nf_loggers[tindex];
 		if (!logger)
 			table->data = "NONE";
 		else
 			table->data = logger->name;
 		r = proc_dostring(table, write, filp, buffer, lenp, ppos);
-		rcu_read_unlock();
+		mutex_unlock(&nf_log_mutex);
 	}
 
 	return r;
diff -druNp linux-libre-2.6.30-gnu1/net/netfilter/xt_quota.c linux-libre-2.6.30.10-gnu1/net/netfilter/xt_quota.c
--- linux-libre-2.6.30-gnu1/net/netfilter/xt_quota.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netfilter/xt_quota.c	2009-12-04 01:00:07.000000000 -0500
@@ -54,6 +54,7 @@ static bool quota_mt_check(const struct
 	if (q->master == NULL)
 		return -ENOMEM;
 
+	q->master->quota = q->quota;
 	return true;
 }
 
diff -druNp linux-libre-2.6.30-gnu1/net/netfilter/xt_rateest.c linux-libre-2.6.30.10-gnu1/net/netfilter/xt_rateest.c
--- linux-libre-2.6.30-gnu1/net/netfilter/xt_rateest.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netfilter/xt_rateest.c	2009-12-04 01:00:07.000000000 -0500
@@ -66,7 +66,7 @@ xt_rateest_mt(const struct sk_buff *skb,
 		if (info->flags & XT_RATEEST_MATCH_BPS)
 			ret &= bps1 == bps2;
 		if (info->flags & XT_RATEEST_MATCH_PPS)
-			ret &= pps2 == pps2;
+			ret &= pps1 == pps2;
 		break;
 	}
 
diff -druNp linux-libre-2.6.30-gnu1/net/netrom/af_netrom.c linux-libre-2.6.30.10-gnu1/net/netrom/af_netrom.c
--- linux-libre-2.6.30-gnu1/net/netrom/af_netrom.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/netrom/af_netrom.c	2009-12-04 01:00:07.000000000 -0500
@@ -848,6 +848,7 @@ static int nr_getname(struct socket *soc
 		sax->fsa_ax25.sax25_family = AF_NETROM;
 		sax->fsa_ax25.sax25_ndigis = 1;
 		sax->fsa_ax25.sax25_call   = nr->user_addr;
+		memset(sax->fsa_digipeater, 0, sizeof(sax->fsa_digipeater));
 		sax->fsa_digipeater[0]     = nr->dest_addr;
 		*uaddr_len = sizeof(struct full_sockaddr_ax25);
 	} else {
diff -druNp linux-libre-2.6.30-gnu1/net/packet/af_packet.c linux-libre-2.6.30.10-gnu1/net/packet/af_packet.c
--- linux-libre-2.6.30-gnu1/net/packet/af_packet.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/packet/af_packet.c	2009-12-04 01:00:07.000000000 -0500
@@ -1501,7 +1501,7 @@ packet_setsockopt(struct socket *sock, i
 static int packet_getsockopt(struct socket *sock, int level, int optname,
 			     char __user *optval, int __user *optlen)
 {
-	int len;
+	unsigned int len;
 	int val;
 	struct sock *sk = sock->sk;
 	struct packet_sock *po = pkt_sk(sk);
@@ -1514,7 +1514,7 @@ static int packet_getsockopt(struct sock
 	if (get_user(len, optlen))
 		return -EFAULT;
 
-	if (len < 0)
+	if ((int)len < 0)
 		return -EINVAL;
 
 	switch(optname)	{
diff -druNp linux-libre-2.6.30-gnu1/net/rose/af_rose.c linux-libre-2.6.30.10-gnu1/net/rose/af_rose.c
--- linux-libre-2.6.30-gnu1/net/rose/af_rose.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/rose/af_rose.c	2009-12-04 01:00:07.000000000 -0500
@@ -957,6 +957,7 @@ static int rose_getname(struct socket *s
 	struct rose_sock *rose = rose_sk(sk);
 	int n;
 
+	memset(srose, 0, sizeof(*srose));
 	if (peer != 0) {
 		if (sk->sk_state != TCP_ESTABLISHED)
 			return -ENOTCONN;
diff -druNp linux-libre-2.6.30-gnu1/net/socket.c linux-libre-2.6.30.10-gnu1/net/socket.c
--- linux-libre-2.6.30-gnu1/net/socket.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/socket.c	2009-12-04 01:00:07.000000000 -0500
@@ -736,7 +736,7 @@ static ssize_t sock_sendpage(struct file
 	if (more)
 		flags |= MSG_MORE;
 
-	return sock->ops->sendpage(sock, page, offset, size, flags);
+	return kernel_sendpage(sock, page, offset, size, flags);
 }
 
 static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
diff -druNp linux-libre-2.6.30-gnu1/net/sunrpc/clnt.c linux-libre-2.6.30.10-gnu1/net/sunrpc/clnt.c
--- linux-libre-2.6.30-gnu1/net/sunrpc/clnt.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/sunrpc/clnt.c	2009-12-04 01:00:07.000000000 -0500
@@ -876,6 +876,7 @@ static inline void
 rpc_task_force_reencode(struct rpc_task *task)
 {
 	task->tk_rqstp->rq_snd_buf.len = 0;
+	task->tk_rqstp->rq_bytes_sent = 0;
 }
 
 static inline void
diff -druNp linux-libre-2.6.30-gnu1/net/wireless/nl80211.c linux-libre-2.6.30.10-gnu1/net/wireless/nl80211.c
--- linux-libre-2.6.30-gnu1/net/wireless/nl80211.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/wireless/nl80211.c	2009-12-04 01:00:07.000000000 -0500
@@ -2385,18 +2385,24 @@ static int nl80211_set_reg(struct sk_buf
 			rem_reg_rules) {
 		num_rules++;
 		if (num_rules > NL80211_MAX_SUPP_REG_RULES)
-			goto bad_reg;
+			return -EINVAL;
 	}
 
-	if (!reg_is_valid_request(alpha2))
-		return -EINVAL;
+	mutex_lock(&cfg80211_mutex);
+
+	if (!reg_is_valid_request(alpha2)) {
+		r = -EINVAL;
+		goto bad_reg;
+	}
 
 	size_of_regd = sizeof(struct ieee80211_regdomain) +
 		(num_rules * sizeof(struct ieee80211_reg_rule));
 
 	rd = kzalloc(size_of_regd, GFP_KERNEL);
-	if (!rd)
-		return -ENOMEM;
+	if (!rd) {
+		r = -ENOMEM;
+		goto bad_reg;
+	}
 
 	rd->n_reg_rules = num_rules;
 	rd->alpha2[0] = alpha2[0];
@@ -2413,20 +2419,24 @@ static int nl80211_set_reg(struct sk_buf
 
 		rule_idx++;
 
-		if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
+		if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
+			r = -EINVAL;
 			goto bad_reg;
+		}
 	}
 
 	BUG_ON(rule_idx != num_rules);
 
-	mutex_lock(&cfg80211_mutex);
 	r = set_regdom(rd);
+
 	mutex_unlock(&cfg80211_mutex);
+
 	return r;
 
  bad_reg:
+	mutex_unlock(&cfg80211_mutex);
 	kfree(rd);
-	return -EINVAL;
+	return r;
 }
 
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
diff -druNp linux-libre-2.6.30-gnu1/net/wireless/reg.c linux-libre-2.6.30.10-gnu1/net/wireless/reg.c
--- linux-libre-2.6.30-gnu1/net/wireless/reg.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/wireless/reg.c	2009-12-04 01:00:07.000000000 -0500
@@ -389,6 +389,8 @@ static int call_crda(const char *alpha2)
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
 bool reg_is_valid_request(const char *alpha2)
 {
+	assert_cfg80211_lock();
+
 	if (!last_request)
 		return false;
 
@@ -2042,7 +2044,13 @@ static int __set_regdom(const struct iee
 	 * the country IE rd with what CRDA believes that country should have
 	 */
 
-	BUG_ON(!country_ie_regdomain);
+	/*
+	 * Userspace could have sent two replies with only
+	 * one kernel request. By the second reply we would have
+	 * already processed and consumed the country_ie_regdomain.
+	 */
+	if (!country_ie_regdomain)
+		return -EALREADY;
 	BUG_ON(rd == country_ie_regdomain);
 
 	/*
diff -druNp linux-libre-2.6.30-gnu1/net/wireless/scan.c linux-libre-2.6.30.10-gnu1/net/wireless/scan.c
--- linux-libre-2.6.30-gnu1/net/wireless/scan.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/wireless/scan.c	2009-12-04 01:00:07.000000000 -0500
@@ -97,7 +97,7 @@ void cfg80211_bss_expire(struct cfg80211
 		dev->bss_generation++;
 }
 
-static u8 *find_ie(u8 num, u8 *ies, size_t len)
+static u8 *find_ie(u8 num, u8 *ies, int len)
 {
 	while (len > 2 && ies[0] != num) {
 		len -= ies[1] + 2;
@@ -118,7 +118,7 @@ static int cmp_ies(u8 num, u8 *ies1, siz
 
 	if (!ie1 && !ie2)
 		return 0;
-	if (!ie1)
+	if (!ie1 || !ie2)
 		return -1;
 
 	r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
@@ -171,6 +171,8 @@ static bool is_mesh(struct cfg80211_bss
 	ie = find_ie(WLAN_EID_MESH_CONFIG,
 		     a->information_elements,
 		     a->len_information_elements);
+	if (!ie)
+		return false;
 	if (ie[1] != IEEE80211_MESH_CONFIG_LEN)
 		return false;
 
@@ -365,7 +367,6 @@ cfg80211_bss_update(struct cfg80211_regi
 	found = rb_find_bss(dev, res);
 
 	if (found) {
-		kref_get(&found->ref);
 		found->pub.beacon_interval = res->pub.beacon_interval;
 		found->pub.tsf = res->pub.tsf;
 		found->pub.signal = res->pub.signal;
diff -druNp linux-libre-2.6.30-gnu1/net/x25/af_x25.c linux-libre-2.6.30.10-gnu1/net/x25/af_x25.c
--- linux-libre-2.6.30-gnu1/net/x25/af_x25.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/x25/af_x25.c	2009-12-04 01:00:07.000000000 -0500
@@ -332,14 +332,14 @@ static unsigned int x25_new_lci(struct x
 /*
  *	Deferred destroy.
  */
-void x25_destroy_socket(struct sock *);
+static void __x25_destroy_socket(struct sock *);
 
 /*
  *	handler for deferred kills.
  */
 static void x25_destroy_timer(unsigned long data)
 {
-	x25_destroy_socket((struct sock *)data);
+	x25_destroy_socket_from_timer((struct sock *)data);
 }
 
 /*
@@ -349,12 +349,10 @@ static void x25_destroy_timer(unsigned l
  *	will touch it and we are (fairly 8-) ) safe.
  *	Not static as it's used by the timer
  */
-void x25_destroy_socket(struct sock *sk)
+static void __x25_destroy_socket(struct sock *sk)
 {
 	struct sk_buff *skb;
 
-	sock_hold(sk);
-	lock_sock(sk);
 	x25_stop_heartbeat(sk);
 	x25_stop_timer(sk);
 
@@ -385,7 +383,22 @@ void x25_destroy_socket(struct sock *sk)
 		/* drop last reference so sock_put will free */
 		__sock_put(sk);
 	}
+}
 
+void x25_destroy_socket_from_timer(struct sock *sk)
+{
+	sock_hold(sk);
+	bh_lock_sock(sk);
+	__x25_destroy_socket(sk);
+	bh_unlock_sock(sk);
+	sock_put(sk);
+}
+
+static void x25_destroy_socket(struct sock *sk)
+{
+	sock_hold(sk);
+	lock_sock(sk);
+	__x25_destroy_socket(sk);
 	release_sock(sk);
 	sock_put(sk);
 }
diff -druNp linux-libre-2.6.30-gnu1/net/x25/x25_timer.c linux-libre-2.6.30.10-gnu1/net/x25/x25_timer.c
--- linux-libre-2.6.30-gnu1/net/x25/x25_timer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/x25/x25_timer.c	2009-12-04 01:00:07.000000000 -0500
@@ -113,7 +113,7 @@ static void x25_heartbeat_expiry(unsigne
 			    (sk->sk_state == TCP_LISTEN &&
 			     sock_flag(sk, SOCK_DEAD))) {
 				bh_unlock_sock(sk);
-				x25_destroy_socket(sk);
+				x25_destroy_socket_from_timer(sk);
 				return;
 			}
 			break;
diff -druNp linux-libre-2.6.30-gnu1/net/xfrm/xfrm_algo.c linux-libre-2.6.30.10-gnu1/net/xfrm/xfrm_algo.c
--- linux-libre-2.6.30-gnu1/net/xfrm/xfrm_algo.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/net/xfrm/xfrm_algo.c	2009-12-04 01:00:07.000000000 -0500
@@ -292,8 +292,8 @@ static struct xfrm_algo_desc ealg_list[]
 	}
 },
 {
-	.name = "cbc(cast128)",
-	.compat = "cast128",
+	.name = "cbc(cast5)",
+	.compat = "cast5",
 
 	.uinfo = {
 		.encr = {
diff -druNp linux-libre-2.6.30-gnu1/scripts/kallsyms.c linux-libre-2.6.30.10-gnu1/scripts/kallsyms.c
--- linux-libre-2.6.30-gnu1/scripts/kallsyms.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/scripts/kallsyms.c	2009-12-04 01:00:07.000000000 -0500
@@ -539,7 +539,7 @@ static int prefix_underscores_count(cons
 {
 	const char *tail = str;
 
-	while (*tail != '_')
+	while (*tail == '_')
 		tail++;
 
 	return tail - str;
diff -druNp linux-libre-2.6.30-gnu1/security/integrity/ima/ima_audit.c linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_audit.c
--- linux-libre-2.6.30-gnu1/security/integrity/ima/ima_audit.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_audit.c	2009-12-04 01:00:07.000000000 -0500
@@ -50,7 +50,7 @@ void integrity_audit_msg(int audit_msgno
 
 	ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
 	audit_log_format(ab, "integrity: pid=%d uid=%u auid=%u ses=%u",
-			 current->pid, current->cred->uid,
+			 current->pid, current_cred()->uid,
 			 audit_get_loginuid(current),
 			 audit_get_sessionid(current));
 	audit_log_task_context(ab);
diff -druNp linux-libre-2.6.30-gnu1/security/integrity/ima/ima_crypto.c linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_crypto.c
--- linux-libre-2.6.30-gnu1/security/integrity/ima/ima_crypto.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_crypto.c	2009-12-04 01:00:07.000000000 -0500
@@ -45,9 +45,9 @@ int ima_calc_hash(struct file *file, cha
 {
 	struct hash_desc desc;
 	struct scatterlist sg[1];
-	loff_t i_size;
+	loff_t i_size, offset = 0;
 	char *rbuf;
-	int rc, offset = 0;
+	int rc;
 
 	rc = init_desc(&desc);
 	if (rc != 0)
@@ -67,6 +67,8 @@ int ima_calc_hash(struct file *file, cha
 			rc = rbuf_len;
 			break;
 		}
+		if (rbuf_len == 0)
+			break;
 		offset += rbuf_len;
 		sg_init_one(sg, rbuf, rbuf_len);
 
diff -druNp linux-libre-2.6.30-gnu1/security/integrity/ima/ima_main.c linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_main.c
--- linux-libre-2.6.30-gnu1/security/integrity/ima/ima_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/security/integrity/ima/ima_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -128,10 +128,6 @@ static int get_path_measurement(struct i
 {
 	int rc = 0;
 
-	if (IS_ERR(file)) {
-		pr_info("%s dentry_open failed\n", filename);
-		return rc;
-	}
 	iint->opencount++;
 	iint->readcount++;
 
@@ -196,7 +192,14 @@ int ima_path_check(struct path *path, in
 		struct dentry *dentry = dget(path->dentry);
 		struct vfsmount *mnt = mntget(path->mnt);
 
-		file = dentry_open(dentry, mnt, O_RDONLY, current->cred);
+		file = dentry_open(dentry, mnt, O_RDONLY | O_LARGEFILE,
+				   current_cred());
+		if (IS_ERR(file)) {
+			pr_info("%s dentry_open failed\n", dentry->d_name.name);
+			rc = PTR_ERR(file);
+			file = NULL;
+			goto out;
+		}
 		rc = get_path_measurement(iint, file, dentry->d_name.name);
 	}
 out:
diff -druNp linux-libre-2.6.30-gnu1/security/Kconfig linux-libre-2.6.30.10-gnu1/security/Kconfig
--- linux-libre-2.6.30-gnu1/security/Kconfig	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/security/Kconfig	2009-12-04 01:00:07.000000000 -0500
@@ -110,28 +110,8 @@ config SECURITY_ROOTPLUG
 
 	  See <http://www.linuxjournal.com/article.php?sid=6279> for
 	  more information about this module.
-	  
-	  If you are unsure how to answer this question, answer N.
-
-config SECURITY_DEFAULT_MMAP_MIN_ADDR
-        int "Low address space to protect from user allocation"
-        depends on SECURITY
-        default 0
-        help
-	  This is the portion of low virtual memory which should be protected
-	  from userspace allocation.  Keeping a user from writing to low pages
-	  can help reduce the impact of kernel NULL pointer bugs.
-
-	  For most ia64, ppc64 and x86 users with lots of address space
-	  a value of 65536 is reasonable and should cause no problems.
-	  On arm and other archs it should not be higher than 32768.
-	  Programs which use vm86 functionality would either need additional
-	  permissions from either the LSM or the capabilities module or have
-	  this protection disabled.
-
-	  This value can be changed after boot using the
-	  /proc/sys/vm/mmap_min_addr tunable.
 
+	  If you are unsure how to answer this question, answer N.
 
 source security/selinux/Kconfig
 source security/smack/Kconfig
diff -druNp linux-libre-2.6.30-gnu1/security/security.c linux-libre-2.6.30.10-gnu1/security/security.c
--- linux-libre-2.6.30-gnu1/security/security.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/security/security.c	2009-12-04 01:00:07.000000000 -0500
@@ -26,9 +26,6 @@ extern void security_fixup_ops(struct se
 
 struct security_operations *security_ops;	/* Initialized to NULL */
 
-/* amount of vm to protect from userspace access */
-unsigned long mmap_min_addr = CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR;
-
 static inline int verify(struct security_operations *ops)
 {
 	/* verify the security_operations structure exists */
diff -druNp linux-libre-2.6.30-gnu1/sound/core/pcm_lib.c linux-libre-2.6.30.10-gnu1/sound/core/pcm_lib.c
--- linux-libre-2.6.30-gnu1/sound/core/pcm_lib.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/core/pcm_lib.c	2009-12-04 01:00:07.000000000 -0500
@@ -876,47 +876,24 @@ static int snd_interval_ratden(struct sn
 int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask)
 {
         unsigned int k;
-	int changed = 0;
+	struct snd_interval list_range;
 
 	if (!count) {
 		i->empty = 1;
 		return -EINVAL;
 	}
+	snd_interval_any(&list_range);
+	list_range.min = UINT_MAX;
+	list_range.max = 0;
         for (k = 0; k < count; k++) {
 		if (mask && !(mask & (1 << k)))
 			continue;
-                if (i->min == list[k] && !i->openmin)
-                        goto _l1;
-                if (i->min < list[k]) {
-                        i->min = list[k];
-			i->openmin = 0;
-			changed = 1;
-                        goto _l1;
-                }
-        }
-        i->empty = 1;
-        return -EINVAL;
- _l1:
-        for (k = count; k-- > 0;) {
-		if (mask && !(mask & (1 << k)))
+		if (!snd_interval_test(i, list[k]))
 			continue;
-                if (i->max == list[k] && !i->openmax)
-                        goto _l2;
-                if (i->max > list[k]) {
-                        i->max = list[k];
-			i->openmax = 0;
-			changed = 1;
-                        goto _l2;
-                }
+		list_range.min = min(list_range.min, list[k]);
+		list_range.max = max(list_range.max, list[k]);
         }
-        i->empty = 1;
-        return -EINVAL;
- _l2:
-	if (snd_interval_checkempty(i)) {
-		i->empty = 1;
-		return -EINVAL;
-	}
-        return changed;
+	return snd_interval_refine(i, &list_range);
 }
 
 EXPORT_SYMBOL(snd_interval_list);
diff -druNp linux-libre-2.6.30-gnu1/sound/core/seq/seq_midi_event.c linux-libre-2.6.30.10-gnu1/sound/core/seq/seq_midi_event.c
--- linux-libre-2.6.30-gnu1/sound/core/seq/seq_midi_event.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/core/seq/seq_midi_event.c	2009-12-04 01:00:07.000000000 -0500
@@ -504,10 +504,10 @@ static int extra_decode_xrpn(struct snd_
 	if (dev->nostat && count < 12)
 		return -ENOMEM;
 	cmd = MIDI_CMD_CONTROL|(ev->data.control.channel & 0x0f);
-	bytes[0] = ev->data.control.param & 0x007f;
-	bytes[1] = (ev->data.control.param & 0x3f80) >> 7;
-	bytes[2] = ev->data.control.value & 0x007f;
-	bytes[3] = (ev->data.control.value & 0x3f80) >> 7;
+	bytes[0] = (ev->data.control.param & 0x3f80) >> 7;
+	bytes[1] = ev->data.control.param & 0x007f;
+	bytes[2] = (ev->data.control.value & 0x3f80) >> 7;
+	bytes[3] = ev->data.control.value & 0x007f;
 	if (cmd != dev->lastcmd && !dev->nostat) {
 		if (count < 9)
 			return -ENOMEM;
diff -druNp linux-libre-2.6.30-gnu1/sound/isa/cmi8330.c linux-libre-2.6.30.10-gnu1/sound/isa/cmi8330.c
--- linux-libre-2.6.30-gnu1/sound/isa/cmi8330.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/isa/cmi8330.c	2009-12-04 01:00:07.000000000 -0500
@@ -338,7 +338,7 @@ static int __devinit snd_cmi8330_pnp(int
 		return -EBUSY;
 
 	acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL);
-	if (acard->play == NULL)
+	if (acard->mpu == NULL)
 		return -EBUSY;
 
 	pdev = acard->cap;
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/ca0106/ca0106_main.c linux-libre-2.6.30.10-gnu1/sound/pci/ca0106/ca0106_main.c
--- linux-libre-2.6.30-gnu1/sound/pci/ca0106/ca0106_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/ca0106/ca0106_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -325,9 +325,9 @@ static struct snd_pcm_hardware snd_ca010
 	.rate_max =		192000,
 	.channels_min =		2,
 	.channels_max =		2,
-	.buffer_bytes_max =	((65536 - 64) * 8),
+	.buffer_bytes_max =	65536 - 128,
 	.period_bytes_min =	64,
-	.period_bytes_max =	(65536 - 64),
+	.period_bytes_max =	32768 - 64,
 	.periods_min =		2,
 	.periods_max =		2,
 	.fifo_size =		0,
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/ca0106/ca0106_mixer.c linux-libre-2.6.30.10-gnu1/sound/pci/ca0106/ca0106_mixer.c
--- linux-libre-2.6.30-gnu1/sound/pci/ca0106/ca0106_mixer.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/ca0106/ca0106_mixer.c	2009-12-04 01:00:07.000000000 -0500
@@ -841,6 +841,9 @@ int __devinit snd_ca0106_mixer(struct sn
 					      snd_ca0106_master_db_scale);
 	if (!vmaster)
 		return -ENOMEM;
+	err = snd_ctl_add(card, vmaster);
+	if (err < 0)
+		return err;
 	add_slaves(card, vmaster, slave_vols);
 
 	if (emu->details->spi_dac == 1) {
@@ -848,6 +851,9 @@ int __devinit snd_ca0106_mixer(struct sn
 						      NULL);
 		if (!vmaster)
 			return -ENOMEM;
+		err = snd_ctl_add(card, vmaster);
+		if (err < 0)
+			return err;
 		add_slaves(card, vmaster, slave_sws);
 	}
         return 0;
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/cs46xx/cs46xx_lib.h linux-libre-2.6.30.10-gnu1/sound/pci/cs46xx/cs46xx_lib.h
--- linux-libre-2.6.30-gnu1/sound/pci/cs46xx/cs46xx_lib.h	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/cs46xx/cs46xx_lib.h	2009-12-04 01:00:07.000000000 -0500
@@ -35,7 +35,7 @@
 
 
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
-#define CS46XX_MIN_PERIOD_SIZE 1
+#define CS46XX_MIN_PERIOD_SIZE 64
 #define CS46XX_MAX_PERIOD_SIZE 1024*1024
 #else
 #define CS46XX_MIN_PERIOD_SIZE 2048
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/hda/patch_realtek.c linux-libre-2.6.30.10-gnu1/sound/pci/hda/patch_realtek.c
--- linux-libre-2.6.30-gnu1/sound/pci/hda/patch_realtek.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/hda/patch_realtek.c	2009-12-04 01:00:07.000000000 -0500
@@ -6186,9 +6186,9 @@ static struct hda_verb alc885_mbp_ch2_in
 };
 
 /*
- * 6ch mode
+ * 4ch mode
  */
-static struct hda_verb alc885_mbp_ch6_init[] = {
+static struct hda_verb alc885_mbp_ch4_init[] = {
 	{ 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
 	{ 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{ 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -6197,9 +6197,9 @@ static struct hda_verb alc885_mbp_ch6_in
 	{ } /* end */
 };
 
-static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
+static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
 	{ 2, alc885_mbp_ch2_init },
-	{ 6, alc885_mbp_ch6_init },
+	{ 4, alc885_mbp_ch4_init },
 };
 
 
@@ -6232,10 +6232,11 @@ static struct snd_kcontrol_new alc882_ba
 };
 
 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
-	HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
-	HDA_BIND_MUTE   ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
-	HDA_CODEC_MUTE  ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
-	HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
+	HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
+	HDA_BIND_MUTE   ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
+	HDA_BIND_MUTE   ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
+	HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
 	HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
 	HDA_CODEC_MUTE  ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
 	HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
@@ -6481,14 +6482,18 @@ static struct hda_verb alc885_mbp3_init_
 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 	{0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
+	/* HP mixer */
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
+	{0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 	/* Front Pin: output 0 (0x0c) */
 	{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 	{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
 	{0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
-	/* HP Pin: output 0 (0x0d) */
+	/* HP Pin: output 0 (0x0e) */
 	{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
-	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
-	{0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
+	{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
+	{0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
 	{0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
 	/* Mic (rear) pin: input vref at 80% */
 	{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -6885,10 +6890,11 @@ static struct alc_config_preset alc882_p
 		.mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
 		.init_verbs = { alc885_mbp3_init_verbs,
 				alc880_gpio1_init_verbs },
-		.num_dacs = ARRAY_SIZE(alc882_dac_nids),
+		.num_dacs = 2,
 		.dac_nids = alc882_dac_nids,
-		.channel_mode = alc885_mbp_6ch_modes,
-		.num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
+		.hp_nid = 0x04,
+		.channel_mode = alc885_mbp_4ch_modes,
+		.num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
 		.input_mux = &alc882_capture_source,
 		.dig_out_nid = ALC882_DIGOUT_NID,
 		.dig_in_nid = ALC882_DIGIN_NID,
@@ -10204,6 +10210,18 @@ static void alc262_lenovo_3000_unsol_eve
 	alc262_lenovo_3000_automute(codec, 1);
 }
 
+static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
+				  int dir, int idx, long *valp)
+{
+	int i, change = 0;
+
+	for (i = 0; i < 2; i++, valp++)
+		change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
+						   HDA_AMP_MUTE,
+						   *valp ? 0 : HDA_AMP_MUTE);
+	return change;
+}
+
 /* bind hp and internal speaker mute (with plug check) */
 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
 					 struct snd_ctl_elem_value *ucontrol)
@@ -10212,13 +10230,8 @@ static int alc262_fujitsu_master_sw_put(
 	long *valp = ucontrol->value.integer.value;
 	int change;
 
-	change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
-						 HDA_AMP_MUTE,
-						 valp ? 0 : HDA_AMP_MUTE);
-	change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-						 HDA_AMP_MUTE,
-						 valp ? 0 : HDA_AMP_MUTE);
-
+	change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
+	change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
 	if (change)
 		alc262_fujitsu_automute(codec, 0);
 	return change;
@@ -10253,10 +10266,7 @@ static int alc262_lenovo_3000_master_sw_
 	long *valp = ucontrol->value.integer.value;
 	int change;
 
-	change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
-						 HDA_AMP_MUTE,
-						 valp ? 0 : HDA_AMP_MUTE);
-
+	change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
 	if (change)
 		alc262_lenovo_3000_automute(codec, 0);
 	return change;
@@ -10915,6 +10925,7 @@ static struct snd_pci_quirk alc262_cfg_t
 	SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
 	SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
 	SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
+	SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
 	SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
 			   ALC262_SONY_ASSAMD),
 	SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
@@ -11122,6 +11133,7 @@ static struct alc_config_preset alc262_p
 		.capsrc_nids = alc262_dmic_capsrc_nids,
 		.dac_nids = alc262_dac_nids,
 		.adc_nids = alc262_dmic_adc_nids, /* ADC0 */
+		.num_adc_nids = 1, /* single ADC */
 		.dig_out_nid = ALC262_DIGOUT_NID,
 		.num_channel_mode = ARRAY_SIZE(alc262_modes),
 		.channel_mode = alc262_modes,
@@ -11375,12 +11387,7 @@ static int alc268_acer_master_sw_put(str
 	long *valp = ucontrol->value.integer.value;
 	int change;
 
-	change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
-					  HDA_AMP_MUTE,
-					  valp[0] ? 0 : HDA_AMP_MUTE);
-	change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
-					   HDA_AMP_MUTE,
-					   valp[1] ? 0 : HDA_AMP_MUTE);
+	change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
 	if (change)
 		alc268_acer_automute(codec, 0);
 	return change;
@@ -13149,6 +13156,8 @@ static int patch_alc269(struct hda_codec
 		set_capture_mixer(spec);
 	set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
 
+	spec->vmaster_nid = 0x02;
+
 	codec->patch_ops = alc_patch_ops;
 	if (board_config == ALC269_AUTO)
 		spec->init_hook = alc269_auto_init;
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/hda/patch_sigmatel.c linux-libre-2.6.30.10-gnu1/sound/pci/hda/patch_sigmatel.c
--- linux-libre-2.6.30-gnu1/sound/pci/hda/patch_sigmatel.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/hda/patch_sigmatel.c	2009-12-04 01:00:07.000000000 -0500
@@ -2325,6 +2325,7 @@ static struct snd_pci_quirk stac9205_cfg
 	SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228,
 		      "Dell Vostro 1500", STAC_9205_DELL_M42),
 	/* Gateway */
+	SND_PCI_QUIRK(0x107b, 0x0560, "Gateway T6834c", STAC_9205_EAPD),
 	SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD),
 	{} /* terminator */
 };
@@ -5661,6 +5662,8 @@ static unsigned int *stac9872_brd_tbl[ST
 };
 
 static struct snd_pci_quirk stac9872_cfg_tbl[] = {
+	SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0,
+			   "Sony VAIO F/S", STAC_9872_VAIO),
 	{} /* terminator */
 };
 
@@ -5673,6 +5676,8 @@ static int patch_stac9872(struct hda_cod
 	if (spec == NULL)
 		return -ENOMEM;
 	codec->spec = spec;
+	spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
+	spec->pin_nids = stac9872_pin_nids;
 
 	spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
 							stac9872_models,
@@ -5684,8 +5689,6 @@ static int patch_stac9872(struct hda_cod
 		stac92xx_set_config_regs(codec,
 					 stac9872_brd_tbl[spec->board_config]);
 
-	spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
-	spec->pin_nids = stac9872_pin_nids;
 	spec->multiout.dac_nids = spec->dac_nids;
 	spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids);
 	spec->adc_nids = stac9872_adc_nids;
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/intel8x0.c linux-libre-2.6.30.10-gnu1/sound/pci/intel8x0.c
--- linux-libre-2.6.30-gnu1/sound/pci/intel8x0.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/intel8x0.c	2009-12-04 01:00:07.000000000 -0500
@@ -356,8 +356,6 @@ struct ichdev {
         unsigned int position;
 	unsigned int pos_shift;
 	unsigned int last_pos;
-	unsigned long last_pos_jiffies;
-	unsigned int jiffy_to_bytes;
         int frags;
         int lvi;
         int lvi_frag;
@@ -844,7 +842,6 @@ static int snd_intel8x0_pcm_trigger(stru
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		val = ICH_IOCE | ICH_STARTBM;
 		ichdev->last_pos = ichdev->position;
-		ichdev->last_pos_jiffies = jiffies;
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 		ichdev->suspended = 1;
@@ -1048,7 +1045,6 @@ static int snd_intel8x0_pcm_prepare(stru
 			ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1;
 	}
 	snd_intel8x0_setup_periods(chip, ichdev);
-	ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ;
 	return 0;
 }
 
@@ -1073,19 +1069,23 @@ static snd_pcm_uframes_t snd_intel8x0_pc
 		    ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb))
 			break;
 	} while (timeout--);
+	ptr = ichdev->last_pos;
 	if (ptr1 != 0) {
 		ptr1 <<= ichdev->pos_shift;
 		ptr = ichdev->fragsize1 - ptr1;
 		ptr += position;
-		ichdev->last_pos = ptr;
-		ichdev->last_pos_jiffies = jiffies;
-	} else {
-		ptr1 = jiffies - ichdev->last_pos_jiffies;
-		if (ptr1)
-			ptr1 -= 1;
-		ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes;
-		ptr %= ichdev->size;
+		if (ptr < ichdev->last_pos) {
+			unsigned int pos_base, last_base;
+			pos_base = position / ichdev->fragsize1;
+			last_base = ichdev->last_pos / ichdev->fragsize1;
+			/* another sanity check; ptr1 can go back to full
+			 * before the base position is updated
+			 */
+			if (pos_base == last_base)
+				ptr = ichdev->last_pos;
+		}
 	}
+	ichdev->last_pos = ptr;
 	spin_unlock(&chip->reg_lock);
 	if (ptr >= ichdev->size)
 		return 0;
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_io.c linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_io.c
--- linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_io.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_io.c	2009-12-04 01:00:07.000000000 -0500
@@ -215,17 +215,8 @@ EXPORT_SYMBOL(oxygen_write_spi);
 
 void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data)
 {
-	unsigned long timeout;
-
 	/* should not need more than about 300 us */
-	timeout = jiffies + msecs_to_jiffies(1);
-	do {
-		if (!(oxygen_read16(chip, OXYGEN_2WIRE_BUS_STATUS)
-		      & OXYGEN_2WIRE_BUSY))
-			break;
-		udelay(1);
-		cond_resched();
-	} while (time_after_eq(timeout, jiffies));
+	msleep(1);
 
 	oxygen_write8(chip, OXYGEN_2WIRE_MAP, map);
 	oxygen_write8(chip, OXYGEN_2WIRE_DATA, data);
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_lib.c linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_lib.c
--- linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_lib.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_lib.c	2009-12-04 01:00:07.000000000 -0500
@@ -260,6 +260,9 @@ oxygen_search_pci_id(struct oxygen *chip
 	 * chip didn't if the first EEPROM word was overwritten.
 	 */
 	subdevice = oxygen_read_eeprom(chip, 2);
+	/* use default ID if EEPROM is missing */
+	if (subdevice == 0xffff)
+		subdevice = 0x8788;
 	/*
 	 * We use only the subsystem device ID for searching because it is
 	 * unique even without the subsystem vendor ID, which may have been
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_pcm.c linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_pcm.c
--- linux-libre-2.6.30-gnu1/sound/pci/oxygen/oxygen_pcm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/oxygen_pcm.c	2009-12-04 01:00:07.000000000 -0500
@@ -469,9 +469,11 @@ static int oxygen_multich_hw_params(stru
 	oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
 			      oxygen_rate(hw_params) |
 			      chip->model.dac_i2s_format |
+			      oxygen_i2s_mclk(hw_params) |
 			      oxygen_i2s_bits(hw_params),
 			      OXYGEN_I2S_RATE_MASK |
 			      OXYGEN_I2S_FORMAT_MASK |
+			      OXYGEN_I2S_MCLK_MASK |
 			      OXYGEN_I2S_BITS_MASK);
 	oxygen_update_dac_routing(chip);
 	oxygen_update_spdif_source(chip);
diff -druNp linux-libre-2.6.30-gnu1/sound/pci/oxygen/virtuoso.c linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/virtuoso.c
--- linux-libre-2.6.30-gnu1/sound/pci/oxygen/virtuoso.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/pci/oxygen/virtuoso.c	2009-12-04 01:00:07.000000000 -0500
@@ -621,6 +621,8 @@ static void xonar_d2_resume(struct oxyge
 
 static void xonar_d1_resume(struct oxygen *chip)
 {
+	oxygen_set_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC);
+	msleep(1);
 	cs43xx_init(chip);
 	xonar_enable_output(chip);
 }
diff -druNp linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8350.c linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8350.c
--- linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8350.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8350.c	2009-12-04 01:00:07.000000000 -0500
@@ -613,7 +613,7 @@ SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VO
 
 /* Out4 Capture Mux */
 static const struct snd_kcontrol_new wm8350_out4_capture_controls =
-SOC_DAPM_ENUM("Route", wm8350_enum[8]);
+SOC_DAPM_ENUM("Route", wm8350_enum[7]);
 
 static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
 
diff -druNp linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8753.c linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8753.c
--- linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8753.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8753.c	2009-12-04 01:00:07.000000000 -0500
@@ -1664,7 +1664,7 @@ static int wm8753_register(struct wm8753
 	codec->reg_cache = &wm8753->reg_cache;
 	codec->private_data = wm8753;
 
-	memcpy(codec->reg_cache, wm8753_reg, sizeof(codec->reg_cache));
+	memcpy(codec->reg_cache, wm8753_reg, sizeof(wm8753->reg_cache));
 	INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
 
 	ret = wm8753_reset(codec);
diff -druNp linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8903.c linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8903.c
--- linux-libre-2.6.30-gnu1/sound/soc/codecs/wm8903.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/soc/codecs/wm8903.c	2009-12-04 01:00:07.000000000 -0500
@@ -1215,22 +1215,18 @@ static struct {
 	int div;
 } bclk_divs[] = {
 	{  10,  0 },
-	{  15,  1 },
 	{  20,  2 },
 	{  30,  3 },
 	{  40,  4 },
 	{  50,  5 },
-	{  55,  6 },
 	{  60,  7 },
 	{  80,  8 },
 	{ 100,  9 },
-	{ 110, 10 },
 	{ 120, 11 },
 	{ 160, 12 },
 	{ 200, 13 },
 	{ 220, 14 },
 	{ 240, 15 },
-	{ 250, 16 },
 	{ 300, 17 },
 	{ 320, 18 },
 	{ 440, 19 },
diff -druNp linux-libre-2.6.30-gnu1/sound/usb/usbaudio.c linux-libre-2.6.30.10-gnu1/sound/usb/usbaudio.c
--- linux-libre-2.6.30-gnu1/sound/usb/usbaudio.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/sound/usb/usbaudio.c	2009-12-04 01:00:07.000000000 -0500
@@ -2649,7 +2649,7 @@ static int parse_audio_endpoints(struct
 	struct usb_interface_descriptor *altsd;
 	int i, altno, err, stream;
 	int format;
-	struct audioformat *fp;
+	struct audioformat *fp = NULL;
 	unsigned char *fmt, *csep;
 	int num;
 
@@ -2722,6 +2722,18 @@ static int parse_audio_endpoints(struct
 			continue;
 		}
 
+		/*
+		 * Blue Microphones workaround: The last altsetting is identical
+		 * with the previous one, except for a larger packet size, but
+		 * is actually a mislabeled two-channel setting; ignore it.
+		 */
+		if (fmt[4] == 1 && fmt[5] == 2 && altno == 2 && num == 3 &&
+		    fp && fp->altsetting == 1 && fp->channels == 1 &&
+		    fp->format == SNDRV_PCM_FORMAT_S16_LE &&
+		    le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) ==
+							fp->maxpacksize * 2)
+			continue;
+
 		csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT);
 		/* Creamware Noah has this descriptor after the 2nd endpoint */
 		if (!csep && altsd->bNumEndpoints >= 2)
diff -druNp linux-libre-2.6.30-gnu1/virt/kvm/irq_comm.c linux-libre-2.6.30.10-gnu1/virt/kvm/irq_comm.c
--- linux-libre-2.6.30-gnu1/virt/kvm/irq_comm.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/virt/kvm/irq_comm.c	2009-12-04 01:00:07.000000000 -0500
@@ -141,7 +141,8 @@ void kvm_notify_acked_irq(struct kvm *kv
 	unsigned gsi = pin;
 
 	list_for_each_entry(e, &kvm->irq_routing, link)
-		if (e->irqchip.irqchip == irqchip &&
+		if (e->type == KVM_IRQ_ROUTING_IRQCHIP &&
+		    e->irqchip.irqchip == irqchip &&
 		    e->irqchip.pin == pin) {
 			gsi = e->gsi;
 			break;
@@ -240,6 +241,7 @@ static int setup_routing_entry(struct kv
 	int delta;
 
 	e->gsi = ue->gsi;
+	e->type = ue->type;
 	switch (ue->type) {
 	case KVM_IRQ_ROUTING_IRQCHIP:
 		delta = 0;
diff -druNp linux-libre-2.6.30-gnu1/virt/kvm/kvm_main.c linux-libre-2.6.30.10-gnu1/virt/kvm/kvm_main.c
--- linux-libre-2.6.30-gnu1/virt/kvm/kvm_main.c	2009-06-09 23:05:27.000000000 -0400
+++ linux-libre-2.6.30.10-gnu1/virt/kvm/kvm_main.c	2009-12-04 01:00:07.000000000 -0500
@@ -581,6 +581,7 @@ static bool make_all_cpus_request(struct
 		cpumask_clear(cpus);
 
 	me = get_cpu();
+	spin_lock(&kvm->requests_lock);
 	for (i = 0; i < KVM_MAX_VCPUS; ++i) {
 		vcpu = kvm->vcpus[i];
 		if (!vcpu)
@@ -597,6 +598,7 @@ static bool make_all_cpus_request(struct
 		smp_call_function_many(cpus, ack_flush, NULL, 1);
 	else
 		called = false;
+	spin_unlock(&kvm->requests_lock);
 	put_cpu();
 	free_cpumask_var(cpus);
 	return called;
@@ -817,6 +819,7 @@ static struct kvm *kvm_create_vm(void)
 	kvm->mm = current->mm;
 	atomic_inc(&kvm->mm->mm_count);
 	spin_lock_init(&kvm->mmu_lock);
+	spin_lock_init(&kvm->requests_lock);
 	kvm_io_bus_init(&kvm->pio_bus);
 	mutex_init(&kvm->lock);
 	kvm_io_bus_init(&kvm->mmio_bus);
@@ -878,6 +881,8 @@ static void kvm_destroy_vm(struct kvm *k
 #endif
 #if defined(CONFIG_MMU_NOTIFIER) && defined(KVM_ARCH_WANT_MMU_NOTIFIER)
 	mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm);
+#else
+	kvm_arch_flush_shadow(kvm);
 #endif
 	kvm_arch_destroy_vm(kvm);
 	mmdrop(mm);
@@ -919,9 +924,8 @@ int __kvm_set_memory_region(struct kvm *
 {
 	int r;
 	gfn_t base_gfn;
-	unsigned long npages;
-	int largepages;
-	unsigned long i;
+	unsigned long npages, ugfn;
+	unsigned long largepages, i;
 	struct kvm_memory_slot *memslot;
 	struct kvm_memory_slot old, new;
 
@@ -1010,6 +1014,14 @@ int __kvm_set_memory_region(struct kvm *
 			new.lpage_info[0].write_count = 1;
 		if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
 			new.lpage_info[largepages-1].write_count = 1;
+		ugfn = new.userspace_addr >> PAGE_SHIFT;
+		/*
+		 * If the gfn and userspace address are not aligned wrt each
+		 * other, disable large page support for this slot
+		 */
+		if ((base_gfn ^ ugfn) & (KVM_PAGES_PER_HPAGE - 1))
+			for (i = 0; i < largepages; ++i)
+				new.lpage_info[i].write_count = 1;
 	}
 
 	/* Allocate page dirty bitmap if needed */
@@ -1020,6 +1032,8 @@ int __kvm_set_memory_region(struct kvm *
 		if (!new.dirty_bitmap)
 			goto out_free;
 		memset(new.dirty_bitmap, 0, dirty_bytes);
+		if (old.npages)
+			kvm_arch_flush_shadow(kvm);
 	}
 #endif /* not defined CONFIG_S390 */
 
@@ -1043,8 +1057,10 @@ int __kvm_set_memory_region(struct kvm *
 
 	kvm_free_physmem_slot(&old, npages ? &new : NULL);
 	/* Slot deletion case: we have to update the current slot */
+	spin_lock(&kvm->mmu_lock);
 	if (!npages)
 		*memslot = old;
+	spin_unlock(&kvm->mmu_lock);
 #ifdef CONFIG_DMAR
 	/* map the pages in iommu page table */
 	r = kvm_iommu_map_pages(kvm, base_gfn, npages);
