[kernel] r11393 - in dists/sid/linux-2.6/debian: . patches/bugfix/all/stable

Maximilian Attems maks at alioth.debian.org
Thu May 15 22:26:08 UTC 2008


Author: maks
Date: Thu May 15 22:25:52 2008
New Revision: 11393

Log:
add stable 2.6.25.4


Added:
   dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.25.4.patch
Modified:
   dists/sid/linux-2.6/debian/changelog

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	(original)
+++ dists/sid/linux-2.6/debian/changelog	Thu May 15 22:25:52 2008
@@ -1,7 +1,46 @@
 linux-2.6 (2.6.25-4) UNRELEASED; urgency=low
 
   * Fix arm Kconfig logic disabling random drivers. (closes: #481410)
-
+  * Add stable release 2.6.25.4:
+    - OHCI: fix regression upon awakening from hibernation
+    - V4L/DVB (7473): PATCH for various Dibcom based devices
+    - {nfnetlink, ip, ip6}_queue: fix skb_over_panic when enlarging packets
+    - dccp: return -EINVAL on invalid feature length
+    - md: fix raid5 'repair' operations
+    - sparc: Fix SA_ONSTACK signal handling.
+    - sparc: Fix fork/clone/vfork system call restart.
+    - sparc64: Stop creating dummy root PCI host controller devices.
+    - sparc64: Fix wedged irq regression.
+    - SPARC64: Fix args to 64-bit sys_semctl() via sys_ipc().
+    - serial: Fix sparc driver name strings.
+    - sparc: Fix ptrace() detach.
+    - sparc: Fix mremap address range validation.
+    - sparc: Fix debugger syscall restart interactions.
+    - sparc32: Don't twiddle PT_DTRACE in exec.
+    - r8169: fix oops in r8169_get_mac_version
+    - SCSI: aha152x: Fix oops on module removal
+    - SCSI: aha152x: fix init suspiciously returned 1, it should follow
+      0/-E convention
+    - sch_htb: remove from event queue in htb_parent_to_leaf()
+    - i2c-piix4: Blacklist two mainboards
+    - SCSI: qla1280: Fix queue depth problem
+    - ipvs: fix oops in backup for fwmark conn templates
+    - USB: airprime: unlock mutex instead of trying to lock it again
+    - rtc: rtc_time_to_tm: use unsigned arithmetic
+    - SCSI: libiscsi regression in 2.6.25: fix nop timer handling
+    - SCSI: libiscsi regression in 2.6.25: fix setting of recv timer
+    - can: Fix can_send() handling on dev_queue_xmit() failures
+    - macvlan: Fix memleak on device removal/crash on module removal
+    - nf_conntrack: padding breaks conntrack hash on ARM
+    - sparc: sunzilog uart order
+    - r8169: fix past rtl_chip_info array size for unknown chipsets
+    - x86: use defconfigs from x86/configs/*
+    - vt: fix canonical input in UTF-8 mode
+    - ata_piix: verify SIDPR access before enabling it
+    - serial: access after NULL check in uart_flush_buffer()
+    - x86: sysfs cpu?/topology is empty in 2.6.25 (32-bit Intel system)
+    - XFRM: AUDIT: Fix flowlabel text format ambibuity.
+ 
  -- maximilian attems <maks at debian.org>  Fri, 16 May 2008 00:16:56 +0200
 
 linux-2.6 (2.6.25-3) unstable; urgency=low

Added: dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.25.4.patch
==============================================================================
--- (empty file)
+++ dists/sid/linux-2.6/debian/patches/bugfix/all/stable/2.6.25.4.patch	Thu May 15 22:25:52 2008
@@ -0,0 +1,2909 @@
+diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
+index c2eed8f..1ea92e7 100644
+--- a/arch/sparc/kernel/entry.S
++++ b/arch/sparc/kernel/entry.S
+@@ -1398,6 +1398,8 @@ ret_from_fork:
+ 	.align	4
+ 	.globl	linux_sparc_syscall
+ linux_sparc_syscall:
++	sethi	%hi(PSR_SYSCALL), %l4
++	or	%l0, %l4, %l0
+ 	/* Direct access to user regs, must faster. */
+ 	cmp	%g1, NR_SYSCALLS
+ 	bgeu	linux_sparc_ni_syscall
+diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
+index 70c0dd2..a65aed3 100644
+--- a/arch/sparc/kernel/process.c
++++ b/arch/sparc/kernel/process.c
+@@ -421,14 +421,26 @@ asmlinkage int sparc_do_fork(unsigned long clone_flags,
+                              unsigned long stack_size)
+ {
+ 	unsigned long parent_tid_ptr, child_tid_ptr;
++	unsigned long orig_i1 = regs->u_regs[UREG_I1];
++	long ret;
+ 
+ 	parent_tid_ptr = regs->u_regs[UREG_I2];
+ 	child_tid_ptr = regs->u_regs[UREG_I4];
+ 
+-	return do_fork(clone_flags, stack_start,
+-		       regs, stack_size,
+-		       (int __user *) parent_tid_ptr,
+-		       (int __user *) child_tid_ptr);
++	ret = do_fork(clone_flags, stack_start,
++		      regs, stack_size,
++		      (int __user *) parent_tid_ptr,
++		      (int __user *) child_tid_ptr);
++
++	/* If we get an error and potentially restart the system
++	 * call, we're screwed because copy_thread() clobbered
++	 * the parent's %o1.  So detect that case and restore it
++	 * here.
++	 */
++	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
++		regs->u_regs[UREG_I1] = orig_i1;
++
++	return ret;
+ }
+ 
+ /* Copy a Sparc thread.  The fork() return value conventions
+@@ -628,11 +640,6 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
+ 			  (char __user * __user *)regs->u_regs[base + UREG_I2],
+ 			  regs);
+ 	putname(filename);
+-	if (error == 0) {
+-		task_lock(current);
+-		current->ptrace &= ~PT_DTRACE;
+-		task_unlock(current);
+-	}
+ out:
+ 	return error;
+ }
+diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
+index 7f44ae6..81f3b92 100644
+--- a/arch/sparc/kernel/ptrace.c
++++ b/arch/sparc/kernel/ptrace.c
+@@ -170,8 +170,8 @@ static int genregs32_set(struct task_struct *target,
+ 		switch (pos) {
+ 		case 32: /* PSR */
+ 			psr = regs->psr;
+-			psr &= ~PSR_ICC;
+-			psr |= (reg & PSR_ICC);
++			psr &= ~(PSR_ICC | PSR_SYSCALL);
++			psr |= (reg & (PSR_ICC | PSR_SYSCALL));
+ 			regs->psr = psr;
+ 			break;
+ 		case 33: /* PC */
+@@ -441,6 +441,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 		break;
+ 
+ 	default:
++		if (request == PTRACE_SPARC_DETACH)
++			request = PTRACE_DETACH;
+ 		ret = ptrace_request(child, request, addr, data);
+ 		break;
+ 	}
+diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
+index 77ca6fd..ab818cd 100644
+--- a/arch/sparc/kernel/rtrap.S
++++ b/arch/sparc/kernel/rtrap.S
+@@ -50,8 +50,9 @@ rtrap_7win_patch5:	and	%g1, 0x7f, %g1
+ ret_trap_entry:
+ ret_trap_lockless_ipi:
+ 	andcc	%t_psr, PSR_PS, %g0
++	sethi	%hi(PSR_SYSCALL), %g1
+ 	be	1f
+-	 nop
++	 andn	%t_psr, %g1, %t_psr
+ 
+ 	wr	%t_psr, 0x0, %psr
+ 	b	ret_trap_kernel
+@@ -73,7 +74,6 @@ signal_p:
+ 	 ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
+ 
+ 	mov	%l5, %o1
+-	mov	%l6, %o2
+ 	call	do_signal
+ 	 add	%sp, STACKFRAME_SZ, %o0	! pt_regs ptr
+ 
+@@ -81,6 +81,8 @@ signal_p:
+ 	ld	[%sp + STACKFRAME_SZ + PT_PSR], %t_psr
+ 	clr	%l6
+ ret_trap_continue:
++	sethi	%hi(PSR_SYSCALL), %g1
++	andn	%t_psr, %g1, %t_psr
+ 	wr	%t_psr, 0x0, %psr
+ 	WRITE_PAUSE
+ 
+@@ -137,8 +139,9 @@ ret_trap_userwins_ok:
+ 	LOAD_PT_PRIV(sp, t_psr, t_pc, t_npc)
+ 	or	%t_pc, %t_npc, %g2
+ 	andcc	%g2, 0x3, %g0
++	sethi	%hi(PSR_SYSCALL), %g2
+ 	be	1f
+-	 nop
++	 andn	%t_psr, %g2, %t_psr
+ 
+ 	b	ret_trap_unaligned_pc
+ 	 add	%sp, STACKFRAME_SZ, %o0
+@@ -201,6 +204,8 @@ rtrap_patch5:	and	%g1, 0xff, %g1
+ 1:
+ 	LOAD_PT_ALL(sp, t_psr, t_pc, t_npc, g1)
+ 2:
++	sethi	%hi(PSR_SYSCALL), %twin_tmp1
++	andn	%t_psr, %twin_tmp1, %t_psr
+ 	wr	%t_psr, 0x0, %psr
+ 	WRITE_PAUSE
+ 
+diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
+index 9994cac..e85023b 100644
+--- a/arch/sparc/kernel/signal.c
++++ b/arch/sparc/kernel/signal.c
+@@ -178,6 +178,9 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
+ 	regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
+ 		  | (regs->psr & (PSR_ICC | PSR_EF));
+ 
++	/* Prevent syscall restart.  */
++	pt_regs_clear_syscall(regs);
++
+ 	err |= __get_user(fpu_save, &sf->fpu_save);
+ 
+ 	if (fpu_save)
+@@ -299,6 +302,9 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
+ 
+ 	regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
+ 
++	/* Prevent syscall restart.  */
++	pt_regs_clear_syscall(regs);
++
+ 	err |= __get_user(fpu_save, &sf->fpu_save);
+ 
+ 	if (fpu_save)
+@@ -345,15 +351,29 @@ static inline int invalid_frame_pointer(void __user *fp, int fplen)
+ 
+ static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
+ {
+-	unsigned long sp;
++	unsigned long sp = regs->u_regs[UREG_FP];
+ 
+-	sp = regs->u_regs[UREG_FP];
++	/*
++	 * If we are on the alternate signal stack and would overflow it, don't.
++	 * Return an always-bogus address instead so we will die with SIGSEGV.
++	 */
++	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
++		return (void __user *) -1L;
+ 
+ 	/* This is the X/Open sanctioned signal stack switching.  */
+ 	if (sa->sa_flags & SA_ONSTACK) {
+-		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
++		if (sas_ss_flags(sp) == 0)
+ 			sp = current->sas_ss_sp + current->sas_ss_size;
+ 	}
++
++	/* Always align the stack frame.  This handles two cases.  First,
++	 * sigaltstack need not be mindful of platform specific stack
++	 * alignment.  Second, if we took this signal because the stack
++	 * is not aligned properly, we'd like to take the signal cleanly
++	 * and report that.
++	 */
++	sp &= ~7UL;
++
+ 	return (void __user *)(sp - framesize);
+ }
+ 
+@@ -994,13 +1014,13 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
+  * want to handle. Thus you cannot kill init even with a SIGKILL even by
+  * mistake.
+  */
+-asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int restart_syscall)
++asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0)
+ {
+-	siginfo_t info;
+-	struct sparc_deliver_cookie cookie;
+ 	struct k_sigaction ka;
+-	int signr;
++	int restart_syscall;
+ 	sigset_t *oldset;
++	siginfo_t info;
++	int signr;
+ 
+ 	/*
+ 	 * XXX Disable svr4 signal handling until solaris emulation works.
+@@ -1013,18 +1033,28 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
+ 	int svr4_signal = current->personality == PER_SVR4;
+ #endif
+ 
+-	cookie.restart_syscall = restart_syscall;
+-	cookie.orig_i0 = orig_i0;
++ 	if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
++ 		restart_syscall = 1;
++ 	else
++ 		restart_syscall = 0;
+ 
+ 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ 		oldset = &current->saved_sigmask;
+ 	else
+ 		oldset = &current->blocked;
+ 
+-	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
++ 	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++ 	/* If the debugger messes with the program counter, it clears
++ 	 * the software "in syscall" bit, directing us to not perform
++ 	 * a syscall restart.
++ 	 */
++ 	if (restart_syscall && !pt_regs_is_syscall(regs))
++ 		restart_syscall = 0;
++
+ 	if (signr > 0) {
+-		if (cookie.restart_syscall)
+-			syscall_restart(cookie.orig_i0, regs, &ka.sa);
++		if (restart_syscall)
++			syscall_restart(orig_i0, regs, &ka.sa);
+ 		handle_signal(signr, &ka, &info, oldset,
+ 			      regs, svr4_signal);
+ 		/* a signal was successfully delivered; the saved
+@@ -1036,16 +1066,16 @@ asmlinkage void do_signal(struct pt_regs * regs, unsigned long orig_i0, int rest
+ 			clear_thread_flag(TIF_RESTORE_SIGMASK);
+ 		return;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ 		/* replay the system call when we are done */
+-		regs->u_regs[UREG_I0] = cookie.orig_i0;
++		regs->u_regs[UREG_I0] = orig_i0;
+ 		regs->pc -= 4;
+ 		regs->npc -= 4;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ 		regs->pc -= 4;
+@@ -1097,27 +1127,3 @@ do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
+ out:
+ 	return ret;
+ }
+-
+-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
+-{
+-	struct sparc_deliver_cookie *cp = cookie;
+-
+-	if (cp->restart_syscall &&
+-	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+-	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+-	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+-		/* replay the system call when we are done */
+-		regs->u_regs[UREG_I0] = cp->orig_i0;
+-		regs->pc -= 4;
+-		regs->npc -= 4;
+-		cp->restart_syscall = 0;
+-	}
+-
+-	if (cp->restart_syscall &&
+-	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+-		regs->u_regs[UREG_G1] = __NR_restart_syscall;
+-		regs->pc -= 4;
+-		regs->npc -= 4;
+-		cp->restart_syscall = 0;
+-	}
+-}
+diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
+index 9f8c8e1..3423d07 100644
+--- a/arch/sparc/kernel/sys_sparc.c
++++ b/arch/sparc/kernel/sys_sparc.c
+@@ -220,7 +220,7 @@ out:
+ 	return err;
+ }
+ 
+-int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
++int sparc_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (ARCH_SUN4C_SUN4 &&
+ 	    (len > 0x20000000 ||
+@@ -296,52 +296,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+-	if (ARCH_SUN4C_SUN4) {
+-		if (old_len > 0x20000000 || new_len > 0x20000000)
+-			goto out;
+-		if (addr < 0xe0000000 && addr + old_len > 0x20000000)
+-			goto out;
+-	}
+-	if (old_len > TASK_SIZE - PAGE_SIZE ||
+-	    new_len > TASK_SIZE - PAGE_SIZE)
++
++	if (unlikely(sparc_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (ARCH_SUN4C_SUN4 &&
+-		    new_addr < 0xe0000000 &&
+-		    new_addr + new_len > 0x20000000)
+-			goto out_sem;
+-		if (new_addr + new_len > TASK_SIZE - PAGE_SIZE)
+-			goto out_sem;
+-	} else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 &&
+-		    addr + new_len > 0x20000000) ||
+-		   addr + new_len > TASK_SIZE - PAGE_SIZE) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				     vma ? vma->vm_pgoff : 0,
+-				     map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
+index 4b2bf9e..b087e97 100644
+--- a/arch/sparc64/kernel/etrap.S
++++ b/arch/sparc64/kernel/etrap.S
+@@ -27,11 +27,12 @@
+ 
+ 		.text		
+ 		.align	64
+-		.globl	etrap, etrap_irq, etraptl1
++		.globl	etrap_syscall, etrap, etrap_irq, etraptl1
+ etrap:		rdpr	%pil, %g2
+-etrap_irq:
+-		TRAP_LOAD_THREAD_REG(%g6, %g1)
++etrap_irq:	clr	%g3
++etrap_syscall:	TRAP_LOAD_THREAD_REG(%g6, %g1)
+ 		rdpr	%tstate, %g1
++		or	%g1, %g3, %g1
+ 		sllx	%g2, 20, %g3
+ 		andcc	%g1, TSTATE_PRIV, %g0
+ 		or	%g1, %g3, %g1
+diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
+index eb88bd6..b441a26 100644
+--- a/arch/sparc64/kernel/irq.c
++++ b/arch/sparc64/kernel/irq.c
+@@ -1,6 +1,6 @@
+ /* irq.c: UltraSparc IRQ handling/init/registry.
+  *
+- * Copyright (C) 1997, 2007  David S. Miller  (davem at davemloft.net)
++ * Copyright (C) 1997, 2007, 2008 David S. Miller (davem at davemloft.net)
+  * Copyright (C) 1998  Eddie C. Dost    (ecd at skynet.be)
+  * Copyright (C) 1998  Jakub Jelinek    (jj at ultra.linux.cz)
+  */
+@@ -308,6 +308,7 @@ static void sun4u_irq_enable(unsigned int virt_irq)
+ 			 IMAP_AID_SAFARI | IMAP_NID_SAFARI);
+ 		val |= tid | IMAP_VALID;
+ 		upa_writeq(val, imap);
++		upa_writeq(ICLR_IDLE, data->iclr);
+ 	}
+ }
+ 
+diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
+index 545356b..39f0c46 100644
+--- a/arch/sparc64/kernel/pci.c
++++ b/arch/sparc64/kernel/pci.c
+@@ -351,8 +351,7 @@ static void pci_parse_of_addrs(struct of_device *op,
+ 
+ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
+ 				  struct device_node *node,
+-				  struct pci_bus *bus, int devfn,
+-				  int host_controller)
++				  struct pci_bus *bus, int devfn)
+ {
+ 	struct dev_archdata *sd;
+ 	struct pci_dev *dev;
+@@ -389,43 +388,28 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
+ 	dev->devfn = devfn;
+ 	dev->multifunction = 0;		/* maybe a lie? */
+ 
+-	if (host_controller) {
+-		if (tlb_type != hypervisor) {
+-			pci_read_config_word(dev, PCI_VENDOR_ID,
+-					     &dev->vendor);
+-			pci_read_config_word(dev, PCI_DEVICE_ID,
+-					     &dev->device);
+-		} else {
+-			dev->vendor = PCI_VENDOR_ID_SUN;
+-			dev->device = 0x80f0;
+-		}
+-		dev->cfg_size = 256;
+-		dev->class = PCI_CLASS_BRIDGE_HOST << 8;
+-		sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+-			0x00, PCI_SLOT(devfn), PCI_FUNC(devfn));
+-	} else {
+-		dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
+-		dev->device = of_getintprop_default(node, "device-id", 0xffff);
+-		dev->subsystem_vendor =
+-			of_getintprop_default(node, "subsystem-vendor-id", 0);
+-		dev->subsystem_device =
+-			of_getintprop_default(node, "subsystem-id", 0);
+-
+-		dev->cfg_size = pci_cfg_space_size(dev);
+-
+-		/* We can't actually use the firmware value, we have
+-		 * to read what is in the register right now.  One
+-		 * reason is that in the case of IDE interfaces the
+-		 * firmware can sample the value before the the IDE
+-		 * interface is programmed into native mode.
+-		 */
+-		pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
+-		dev->class = class >> 8;
+-		dev->revision = class & 0xff;
++	dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
++	dev->device = of_getintprop_default(node, "device-id", 0xffff);
++	dev->subsystem_vendor =
++		of_getintprop_default(node, "subsystem-vendor-id", 0);
++	dev->subsystem_device =
++		of_getintprop_default(node, "subsystem-id", 0);
++
++	dev->cfg_size = pci_cfg_space_size(dev);
++
++	/* We can't actually use the firmware value, we have
++	 * to read what is in the register right now.  One
++	 * reason is that in the case of IDE interfaces the
++	 * firmware can sample the value before the the IDE
++	 * interface is programmed into native mode.
++	 */
++	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class);
++	dev->class = class >> 8;
++	dev->revision = class & 0xff;
++
++	sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
++		dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ 
+-		sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+-			dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
+-	}
+ 	if (ofpci_verbose)
+ 		printk("    class: 0x%x device name: %s\n",
+ 		       dev->class, pci_name(dev));
+@@ -440,26 +424,21 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
+ 	dev->current_state = 4;		/* unknown power state */
+ 	dev->error_state = pci_channel_io_normal;
+ 
+-	if (host_controller) {
++	if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
++		/* a PCI-PCI bridge */
+ 		dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+ 		dev->rom_base_reg = PCI_ROM_ADDRESS1;
+-		dev->irq = PCI_IRQ_NONE;
++	} else if (!strcmp(type, "cardbus")) {
++		dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+ 	} else {
+-		if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+-			/* a PCI-PCI bridge */
+-			dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
+-			dev->rom_base_reg = PCI_ROM_ADDRESS1;
+-		} else if (!strcmp(type, "cardbus")) {
+-			dev->hdr_type = PCI_HEADER_TYPE_CARDBUS;
+-		} else {
+-			dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
+-			dev->rom_base_reg = PCI_ROM_ADDRESS;
++		dev->hdr_type = PCI_HEADER_TYPE_NORMAL;
++		dev->rom_base_reg = PCI_ROM_ADDRESS;
+ 
+-			dev->irq = sd->op->irqs[0];
+-			if (dev->irq == 0xffffffff)
+-				dev->irq = PCI_IRQ_NONE;
+-		}
++		dev->irq = sd->op->irqs[0];
++		if (dev->irq == 0xffffffff)
++			dev->irq = PCI_IRQ_NONE;
+ 	}
++
+ 	pci_parse_of_addrs(sd->op, node, dev);
+ 
+ 	if (ofpci_verbose)
+@@ -748,7 +727,7 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm,
+ 		prev_devfn = devfn;
+ 
+ 		/* create a new pci_dev for this device */
+-		dev = of_create_pci_dev(pbm, child, bus, devfn, 0);
++		dev = of_create_pci_dev(pbm, child, bus, devfn);
+ 		if (!dev)
+ 			continue;
+ 		if (ofpci_verbose)
+@@ -795,48 +774,9 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus)
+ 		pci_bus_register_of_sysfs(child_bus);
+ }
+ 
+-int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
+-				 unsigned int devfn,
+-				 int where, int size,
+-				 u32 *value)
+-{
+-	static u8 fake_pci_config[] = {
+-		0x8e, 0x10, /* Vendor: 0x108e (Sun) */
+-		0xf0, 0x80, /* Device: 0x80f0 (Fire) */
+-		0x46, 0x01, /* Command: 0x0146 (SERR, PARITY, MASTER, MEM) */
+-		0xa0, 0x22, /* Status: 0x02a0 (DEVSEL_MED, FB2B, 66MHZ) */
+-		0x00, 0x00, 0x00, 0x06, /* Class: 0x06000000 host bridge */
+-		0x00, /* Cacheline: 0x00 */
+-		0x40, /* Latency: 0x40 */
+-		0x00, /* Header-Type: 0x00 normal */
+-	};
+-
+-	*value = 0;
+-	if (where >= 0 && where < sizeof(fake_pci_config) &&
+-	    (where + size) >= 0 &&
+-	    (where + size) < sizeof(fake_pci_config) &&
+-	    size <= sizeof(u32)) {
+-		while (size--) {
+-			*value <<= 8;
+-			*value |= fake_pci_config[where + size];
+-		}
+-	}
+-
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+-int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
+-				  unsigned int devfn,
+-				  int where, int size,
+-				  u32 value)
+-{
+-	return PCIBIOS_SUCCESSFUL;
+-}
+-
+ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm)
+ {
+ 	struct device_node *node = pbm->prom_node;
+-	struct pci_dev *host_pdev;
+ 	struct pci_bus *bus;
+ 
+ 	printk("PCI: Scanning PBM %s\n", node->full_name);
+@@ -854,10 +794,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm)
+ 	bus->resource[0] = &pbm->io_space;
+ 	bus->resource[1] = &pbm->mem_space;
+ 
+-	/* Create the dummy host bridge and link it in.  */
+-	host_pdev = of_create_pci_dev(pbm, node, bus, 0x00, 1);
+-	bus->self = host_pdev;
+-
+ 	pci_of_scan_bus(pbm, node, bus);
+ 	pci_bus_add_devices(bus);
+ 	pci_bus_register_of_sysfs(bus);
+diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
+index 923e0bc..19fa621 100644
+--- a/arch/sparc64/kernel/pci_common.c
++++ b/arch/sparc64/kernel/pci_common.c
+@@ -264,9 +264,6 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+ 	unsigned int func = PCI_FUNC(devfn);
+ 	unsigned long ret;
+ 
+-	if (!bus && devfn == 0x00)
+-		return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where,
+-						    size, value);
+ 	if (config_out_of_range(pbm, bus, devfn, where)) {
+ 		ret = ~0UL;
+ 	} else {
+@@ -300,9 +297,6 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn,
+ 	unsigned int func = PCI_FUNC(devfn);
+ 	unsigned long ret;
+ 
+-	if (!bus && devfn == 0x00)
+-		return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where,
+-						     size, value);
+ 	if (config_out_of_range(pbm, bus, devfn, where)) {
+ 		/* Do nothing. */
+ 	} else {
+diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h
+index 4a50da1..37b4403 100644
+--- a/arch/sparc64/kernel/pci_impl.h
++++ b/arch/sparc64/kernel/pci_impl.h
+@@ -167,15 +167,6 @@ extern void pci_get_pbm_props(struct pci_pbm_info *pbm);
+ extern struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm);
+ extern void pci_determine_mem_io_space(struct pci_pbm_info *pbm);
+ 
+-extern int pci_host_bridge_read_pci_cfg(struct pci_bus *bus_dev,
+-					unsigned int devfn,
+-					int where, int size,
+-					u32 *value);
+-extern int pci_host_bridge_write_pci_cfg(struct pci_bus *bus_dev,
+-					 unsigned int devfn,
+-					 int where, int size,
+-					 u32 value);
+-
+ /* Error reporting support. */
+ extern void pci_scan_for_target_abort(struct pci_pbm_info *, struct pci_bus *);
+ extern void pci_scan_for_master_abort(struct pci_pbm_info *, struct pci_bus *);
+diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
+index acf8c52..334e64c 100644
+--- a/arch/sparc64/kernel/process.c
++++ b/arch/sparc64/kernel/process.c
+@@ -507,6 +507,8 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
+ 			      unsigned long stack_size)
+ {
+ 	int __user *parent_tid_ptr, *child_tid_ptr;
++	unsigned long orig_i1 = regs->u_regs[UREG_I1];
++	long ret;
+ 
+ #ifdef CONFIG_COMPAT
+ 	if (test_thread_flag(TIF_32BIT)) {
+@@ -519,9 +521,19 @@ asmlinkage long sparc_do_fork(unsigned long clone_flags,
+ 		child_tid_ptr = (int __user *) regs->u_regs[UREG_I4];
+ 	}
+ 
+-	return do_fork(clone_flags, stack_start,
+-		       regs, stack_size,
+-		       parent_tid_ptr, child_tid_ptr);
++	ret = do_fork(clone_flags, stack_start,
++		      regs, stack_size,
++		      parent_tid_ptr, child_tid_ptr);
++
++	/* If we get an error and potentially restart the system
++	 * call, we're screwed because copy_thread() clobbered
++	 * the parent's %o1.  So detect that case and restore it
++	 * here.
++	 */
++	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
++		regs->u_regs[UREG_I1] = orig_i1;
++
++	return ret;
+ }
+ 
+ /* Copy a Sparc thread.  The fork() return value conventions
+diff --git a/arch/sparc64/kernel/ptrace.c b/arch/sparc64/kernel/ptrace.c
+index e9fc0aa..f6c9fc9 100644
+--- a/arch/sparc64/kernel/ptrace.c
++++ b/arch/sparc64/kernel/ptrace.c
+@@ -287,11 +287,11 @@ static int genregs64_set(struct task_struct *target,
+ 					 32 * sizeof(u64),
+ 					 33 * sizeof(u64));
+ 		if (!ret) {
+-			/* Only the condition codes can be modified
+-			 * in the %tstate register.
++			/* Only the condition codes and the "in syscall"
++			 * state can be modified in the %tstate register.
+ 			 */
+-			tstate &= (TSTATE_ICC | TSTATE_XCC);
+-			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
++			tstate &= (TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
++			regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ 			regs->tstate |= tstate;
+ 		}
+ 	}
+@@ -657,8 +657,10 @@ static int genregs32_set(struct task_struct *target,
+ 		switch (pos) {
+ 		case 32: /* PSR */
+ 			tstate = regs->tstate;
+-			tstate &= ~(TSTATE_ICC | TSTATE_XCC);
++			tstate &= ~(TSTATE_ICC | TSTATE_XCC | TSTATE_SYSCALL);
+ 			tstate |= psr_to_tstate_icc(reg);
++			if (reg & PSR_SYSCALL)
++				tstate |= TSTATE_SYSCALL;
+ 			regs->tstate = tstate;
+ 			break;
+ 		case 33: /* PC */
+@@ -944,6 +946,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+ 		break;
+ 
+ 	default:
++		if (request == PTRACE_SPARC_DETACH)
++			request = PTRACE_DETACH;
+ 		ret = compat_ptrace_request(child, request, addr, data);
+ 		break;
+ 	}
+@@ -1036,6 +1040,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+ 		break;
+ 
+ 	default:
++		if (request == PTRACE_SPARC_DETACH)
++			request = PTRACE_DETACH;
+ 		ret = ptrace_request(child, request, addr, data);
+ 		break;
+ 	}
+diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
+index 079d18a..5bfa79d 100644
+--- a/arch/sparc64/kernel/rtrap.S
++++ b/arch/sparc64/kernel/rtrap.S
+@@ -270,6 +270,7 @@ rt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
+ 		wr			%o3, %g0, %y
+ 		wrpr			%l4, 0x0, %pil
+ 		wrpr			%g0, 0x1, %tl
++		andn			%l1, TSTATE_SYSCALL, %l1
+ 		wrpr			%l1, %g0, %tstate
+ 		wrpr			%l2, %g0, %tpc
+ 		wrpr			%o2, %g0, %tnpc
+diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
+index 9d51956..ec016cb 100644
+--- a/arch/sparc64/kernel/signal.c
++++ b/arch/sparc64/kernel/signal.c
+@@ -336,6 +336,9 @@ void do_rt_sigreturn(struct pt_regs *regs)
+ 	regs->tpc = tpc;
+ 	regs->tnpc = tnpc;
+ 
++	/* Prevent syscall restart.  */
++	pt_regs_clear_syscall(regs);
++
+ 	sigdelsetmask(&set, ~_BLOCKABLE);
+ 	spin_lock_irq(&current->sighand->siglock);
+ 	current->blocked = set;
+@@ -377,16 +380,29 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+ 
+ static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
+ {
+-	unsigned long sp;
++	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
+ 
+-	sp = regs->u_regs[UREG_FP] + STACK_BIAS;
++	/*
++	 * If we are on the alternate signal stack and would overflow it, don't.
++	 * Return an always-bogus address instead so we will die with SIGSEGV.
++	 */
++	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
++		return (void __user *) -1L;
+ 
+ 	/* This is the X/Open sanctioned signal stack switching.  */
+ 	if (ka->sa.sa_flags & SA_ONSTACK) {
+-		if (!on_sig_stack(sp) &&
+-		    !((current->sas_ss_sp + current->sas_ss_size) & 7))
++		if (sas_ss_flags(sp) == 0)
+ 			sp = current->sas_ss_sp + current->sas_ss_size;
+ 	}
++
++	/* Always align the stack frame.  This handles two cases.  First,
++	 * sigaltstack need not be mindful of platform specific stack
++	 * alignment.  Second, if we took this signal because the stack
++	 * is not aligned properly, we'd like to take the signal cleanly
++	 * and report that.
++	 */
++	sp &= ~7UL;
++
+ 	return (void __user *)(sp - framesize);
+ }
+ 
+@@ -487,7 +503,7 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
+ }
+ 
+ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
+-				     struct sigaction *sa)
++				   struct sigaction *sa)
+ {
+ 	switch (regs->u_regs[UREG_I0]) {
+ 	case ERESTART_RESTARTBLOCK:
+@@ -511,16 +527,19 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
+  * want to handle. Thus you cannot kill init even with a SIGKILL even by
+  * mistake.
+  */
+-static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_syscall)
++static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int __ignored)
+ {
+-	siginfo_t info;
+-	struct signal_deliver_cookie cookie;
+ 	struct k_sigaction ka;
+-	int signr;
++	int restart_syscall;
+ 	sigset_t *oldset;
++	siginfo_t info;
++	int signr;
+ 	
+-	cookie.restart_syscall = restart_syscall;
+-	cookie.orig_i0 = orig_i0;
++ 	if (pt_regs_is_syscall(regs) &&
++ 	    (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
++ 		restart_syscall = 1;
++ 	} else
++ 		restart_syscall = 0;
+ 
+ 	if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ 		oldset = &current->saved_sigmask;
+@@ -530,16 +549,24 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
+ #ifdef CONFIG_SPARC32_COMPAT
+ 	if (test_thread_flag(TIF_32BIT)) {
+ 		extern void do_signal32(sigset_t *, struct pt_regs *,
+-					unsigned long, int);
+-		do_signal32(oldset, regs, orig_i0,
+-			    cookie.restart_syscall);
++					int restart_syscall,
++					unsigned long orig_i0);
++		do_signal32(oldset, regs, restart_syscall, orig_i0);
+ 		return;
+ 	}
+ #endif	
+ 
+-	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
++	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++	/* If the debugger messes with the program counter, it clears
++	 * the software "in syscall" bit, directing us to not perform
++	 * a syscall restart.
++	 */
++	if (restart_syscall && !pt_regs_is_syscall(regs))
++		restart_syscall = 0;
++
+ 	if (signr > 0) {
+-		if (cookie.restart_syscall)
++		if (restart_syscall)
+ 			syscall_restart(orig_i0, regs, &ka.sa);
+ 		handle_signal(signr, &ka, &info, oldset, regs);
+ 
+@@ -552,16 +579,16 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0, int restart_s
+ 			clear_thread_flag(TIF_RESTORE_SIGMASK);
+ 		return;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ 		/* replay the system call when we are done */
+-		regs->u_regs[UREG_I0] = cookie.orig_i0;
++		regs->u_regs[UREG_I0] = orig_i0;
+ 		regs->tpc -= 4;
+ 		regs->tnpc -= 4;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ 		regs->tpc -= 4;
+@@ -583,26 +610,3 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, int restart_s
+ 	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
+ 		do_signal(regs, orig_i0, restart_syscall);
+ }
+-
+-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
+-{
+-	struct signal_deliver_cookie *cp = cookie;
+-
+-	if (cp->restart_syscall &&
+-	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+-	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+-	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+-		/* replay the system call when we are done */
+-		regs->u_regs[UREG_I0] = cp->orig_i0;
+-		regs->tpc -= 4;
+-		regs->tnpc -= 4;
+-		cp->restart_syscall = 0;
+-	}
+-	if (cp->restart_syscall &&
+-	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+-		regs->u_regs[UREG_G1] = __NR_restart_syscall;
+-		regs->tpc -= 4;
+-		regs->tnpc -= 4;
+-		cp->restart_syscall = 0;
+-	}
+-}
+diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
+index 8c1c121..c1b06e2 100644
+--- a/arch/sparc64/kernel/signal32.c
++++ b/arch/sparc64/kernel/signal32.c
+@@ -295,6 +295,9 @@ void do_new_sigreturn32(struct pt_regs *regs)
+ 	regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
+ 	regs->tstate |= psr_to_tstate_icc(psr);
+ 
++ 	/* Prevent syscall restart.  */
++ 	pt_regs_clear_syscall(regs);
++
+ 	err |= __get_user(fpu_save, &sf->fpu_save);
+ 	if (fpu_save)
+ 		err |= restore_fpu_state32(regs, &sf->fpu_state);
+@@ -448,6 +451,9 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
+ 	regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
+ 	regs->tstate |= psr_to_tstate_icc(psr);
+ 
++ 	/* Prevent syscall restart.  */
++ 	pt_regs_clear_syscall(regs);
++
+ 	err |= __get_user(fpu_save, &sf->fpu_save);
+ 	if (fpu_save)
+ 		err |= restore_fpu_state32(regs, &sf->fpu_state);
+@@ -497,11 +503,27 @@ static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
+ 	regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
+ 	sp = regs->u_regs[UREG_FP];
+ 	
++	/*
++	 * If we are on the alternate signal stack and would overflow it, don't.
++	 * Return an always-bogus address instead so we will die with SIGSEGV.
++	 */
++	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
++		return (void __user *) -1L;
++
+ 	/* This is the X/Open sanctioned signal stack switching.  */
+ 	if (sa->sa_flags & SA_ONSTACK) {
+-		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
++		if (sas_ss_flags(sp) == 0)
+ 			sp = current->sas_ss_sp + current->sas_ss_size;
+ 	}
++
++	/* Always align the stack frame.  This handles two cases.  First,
++	 * sigaltstack need not be mindful of platform specific stack
++	 * alignment.  Second, if we took this signal because the stack
++	 * is not aligned properly, we'd like to take the signal cleanly
++	 * and report that.
++	 */
++	sp &= ~7UL;
++
+ 	return (void __user *)(sp - framesize);
+ }
+ 
+@@ -1264,20 +1286,24 @@ static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs
+  * mistake.
+  */
+ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+-		 unsigned long orig_i0, int restart_syscall)
++		 int restart_syscall, unsigned long orig_i0)
+ {
+-	siginfo_t info;
+-	struct signal_deliver_cookie cookie;
+ 	struct k_sigaction ka;
++	siginfo_t info;
+ 	int signr;
+ 	int svr4_signal = current->personality == PER_SVR4;
+ 	
+-	cookie.restart_syscall = restart_syscall;
+-	cookie.orig_i0 = orig_i0;
++	signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++
++	/* If the debugger messes with the program counter, it clears
++	 * the "in syscall" bit, directing us to not perform a syscall
++	 * restart.
++	 */
++	if (restart_syscall && !pt_regs_is_syscall(regs))
++		restart_syscall = 0;
+ 
+-	signr = get_signal_to_deliver(&info, &ka, regs, &cookie);
+ 	if (signr > 0) {
+-		if (cookie.restart_syscall)
++		if (restart_syscall)
+ 			syscall_restart32(orig_i0, regs, &ka.sa);
+ 		handle_signal32(signr, &ka, &info, oldset,
+ 				regs, svr4_signal);
+@@ -1291,16 +1317,16 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
+ 			clear_thread_flag(TIF_RESTORE_SIGMASK);
+ 		return;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+ 	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+ 		/* replay the system call when we are done */
+-		regs->u_regs[UREG_I0] = cookie.orig_i0;
++		regs->u_regs[UREG_I0] = orig_i0;
+ 		regs->tpc -= 4;
+ 		regs->tnpc -= 4;
+ 	}
+-	if (cookie.restart_syscall &&
++	if (restart_syscall &&
+ 	    regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
+ 		regs->u_regs[UREG_G1] = __NR_restart_syscall;
+ 		regs->tpc -= 4;
+diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
+index cc37936..4b495fe 100644
+--- a/arch/sparc64/kernel/sys_sparc.c
++++ b/arch/sparc64/kernel/sys_sparc.c
+@@ -454,8 +454,8 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
+ 			err = sys_semget(first, (int)second, (int)third);
+ 			goto out;
+ 		case SEMCTL: {
+-			err = sys_semctl(first, third,
+-					 (int)second | IPC_64,
++			err = sys_semctl(first, second,
++					 (int)third | IPC_64,
+ 					 (union semun) ptr);
+ 			goto out;
+ 		}
+@@ -542,8 +542,7 @@ asmlinkage long sparc64_personality(unsigned long personality)
+ 	return ret;
+ }
+ 
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags)
++int sparc64_mmap_check(unsigned long addr, unsigned long len)
+ {
+ 	if (test_thread_flag(TIF_32BIT)) {
+ 		if (len >= STACK_TOP32)
+@@ -609,46 +608,19 @@ asmlinkage unsigned long sys64_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, unsigned long new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 
+ 	if (test_thread_flag(TIF_32BIT))
+ 		goto out;
+ 	if (unlikely(new_len >= VA_EXCLUDE_START))
+ 		goto out;
+-	if (unlikely(invalid_64bit_range(addr, old_len)))
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
++		goto out;
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (invalid_64bit_range(new_addr, new_len))
+-			goto out_sem;
+-	} else if (invalid_64bit_range(addr, new_len)) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
+index 2455fa4..54df31a 100644
+--- a/arch/sparc64/kernel/sys_sparc32.c
++++ b/arch/sparc64/kernel/sys_sparc32.c
+@@ -906,44 +906,15 @@ asmlinkage unsigned long sys32_mremap(unsigned long addr,
+ 	unsigned long old_len, unsigned long new_len,
+ 	unsigned long flags, u32 __new_addr)
+ {
+-	struct vm_area_struct *vma;
+ 	unsigned long ret = -EINVAL;
+ 	unsigned long new_addr = __new_addr;
+ 
+-	if (old_len > STACK_TOP32 || new_len > STACK_TOP32)
++	if (unlikely(sparc64_mmap_check(addr, old_len)))
+ 		goto out;
+-	if (addr > STACK_TOP32 - old_len)
++	if (unlikely(sparc64_mmap_check(new_addr, new_len)))
+ 		goto out;
+ 	down_write(&current->mm->mmap_sem);
+-	if (flags & MREMAP_FIXED) {
+-		if (new_addr > STACK_TOP32 - new_len)
+-			goto out_sem;
+-	} else if (addr > STACK_TOP32 - new_len) {
+-		unsigned long map_flags = 0;
+-		struct file *file = NULL;
+-
+-		ret = -ENOMEM;
+-		if (!(flags & MREMAP_MAYMOVE))
+-			goto out_sem;
+-
+-		vma = find_vma(current->mm, addr);
+-		if (vma) {
+-			if (vma->vm_flags & VM_SHARED)
+-				map_flags |= MAP_SHARED;
+-			file = vma->vm_file;
+-		}
+-
+-		/* MREMAP_FIXED checked above. */
+-		new_addr = get_unmapped_area(file, addr, new_len,
+-				    vma ? vma->vm_pgoff : 0,
+-				    map_flags);
+-		ret = new_addr;
+-		if (new_addr & ~PAGE_MASK)
+-			goto out_sem;
+-		flags |= MREMAP_FIXED;
+-	}
+ 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
+-out_sem:
+ 	up_write(&current->mm->mmap_sem);
+ out:
+ 	return ret;       
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
+index 6c70fed..99a4ed3 100644
+--- a/arch/x86/Kconfig
++++ b/arch/x86/Kconfig
+@@ -24,6 +24,18 @@ config X86
+ 	select HAVE_KRETPROBES
+ 	select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
+ 
++config DEFCONFIG_LIST
++	string
++	depends on X86_32
++	option defconfig_list
++	default "arch/x86/configs/i386_defconfig"
++
++config DEFCONFIG_LIST
++	string
++	depends on X86_64
++	option defconfig_list
++	default "arch/x86/configs/x86_64_defconfig"
++
+ 
+ config GENERIC_LOCKBREAK
+ 	def_bool n
+diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
+index fae8404..815b8c3 100644
+--- a/drivers/ata/ata_piix.c
++++ b/drivers/ata/ata_piix.c
+@@ -1531,6 +1531,8 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
+ {
+ 	struct pci_dev *pdev = to_pci_dev(host->dev);
+ 	struct piix_host_priv *hpriv = host->private_data;
++	struct ata_device *dev0 = &host->ports[0]->link.device[0];
++	u32 scontrol;
+ 	int i;
+ 
+ 	/* check for availability */
+@@ -1549,6 +1551,29 @@ static void __devinit piix_init_sidpr(struct ata_host *host)
+ 		return;
+ 
+ 	hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
++
++	/* SCR access via SIDPR doesn't work on some configurations.
++	 * Give it a test drive by inhibiting power save modes which
++	 * we'll do anyway.
++	 */
++	scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
++
++	/* if IPM is already 3, SCR access is probably working.  Don't
++	 * un-inhibit power save modes as BIOS might have inhibited
++	 * them for a reason.
++	 */
++	if ((scontrol & 0xf00) != 0x300) {
++		scontrol |= 0x300;
++		piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
++		scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
++
++		if ((scontrol & 0xf00) != 0x300) {
++			dev_printk(KERN_INFO, host->dev, "SCR access via "
++				   "SIDPR is available but doesn't work\n");
++			return;
++		}
++	}
++
+ 	host->ports[0]->ops = &piix_sidpr_sata_ops;
+ 	host->ports[1]->ops = &piix_sidpr_sata_ops;
+ }
+diff --git a/drivers/char/vt.c b/drivers/char/vt.c
+index 9b58b89..c2e1a83 100644
+--- a/drivers/char/vt.c
++++ b/drivers/char/vt.c
+@@ -2723,6 +2723,10 @@ static int con_open(struct tty_struct *tty, struct file *filp)
+ 				tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
+ 				tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
+ 			}
++			if (vc->vc_utf)
++				tty->termios->c_iflag |= IUTF8;
++			else
++				tty->termios->c_iflag &= ~IUTF8;
+ 			release_console_sem();
+ 			vcs_make_sysfs(tty);
+ 			return ret;
+@@ -2899,6 +2903,8 @@ int __init vty_init(void)
+ 	console_driver->minor_start = 1;
+ 	console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
+ 	console_driver->init_termios = tty_std_termios;
++	if (default_utf8)
++		console_driver->init_termios.c_iflag |= IUTF8;
+ 	console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
+ 	tty_set_operations(console_driver, &con_ops);
+ 	if (tty_register_driver(console_driver))
+diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
+index 9bbe96c..f0b4073 100644
+--- a/drivers/i2c/busses/i2c-piix4.c
++++ b/drivers/i2c/busses/i2c-piix4.c
+@@ -108,7 +108,27 @@ static unsigned short piix4_smba;
+ static struct pci_driver piix4_driver;
+ static struct i2c_adapter piix4_adapter;
+ 
+-static struct dmi_system_id __devinitdata piix4_dmi_table[] = {
++static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
++	{
++		.ident = "Sapphire AM2RD790",
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
++			DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
++		},
++	},
++	{
++		.ident = "DFI Lanparty UT 790FX",
++		.matches = {
++			DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
++			DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
++		},
++	},
++	{ }
++};
++
++/* The IBM entry is in a separate table because we only check it
++   on Intel-based systems */
++static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
+ 	{
+ 		.ident = "IBM",
+ 		.matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
+@@ -123,8 +143,16 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
+ 
+ 	dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
+ 
++	/* On some motherboards, it was reported that accessing the SMBus
++	   caused severe hardware problems */
++	if (dmi_check_system(piix4_dmi_blacklist)) {
++		dev_err(&PIIX4_dev->dev,
++			"Accessing the SMBus on this system is unsafe!\n");
++		return -EPERM;
++	}
++
+ 	/* Don't access SMBus on IBM systems which get corrupted eeproms */
+-	if (dmi_check_system(piix4_dmi_table) &&
++	if (dmi_check_system(piix4_dmi_ibm) &&
+ 			PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
+ 		dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
+ 			"may corrupt your serial eeprom! Refusing to load "
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index b162b83..18a1379 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -2354,8 +2354,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 
+ 	/* complete a check operation */
+ 	if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
+-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
+-	    clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
++		clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
++		clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+ 		if (s->failed == 0) {
+ 			if (sh->ops.zero_sum_result == 0)
+ 				/* parity is correct (on disc,
+@@ -2385,16 +2385,6 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 			canceled_check = 1; /* STRIPE_INSYNC is not set */
+ 	}
+ 
+-	/* check if we can clear a parity disk reconstruct */
+-	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
+-		test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
+-
+-		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
+-		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
+-	}
+-
+ 	/* start a new check operation if there are no failures, the stripe is
+ 	 * not insync, and a repair is not in flight
+ 	 */
+@@ -2409,6 +2399,17 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
+ 		}
+ 	}
+ 
++	/* check if we can clear a parity disk reconstruct */
++	if (test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete) &&
++	    test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
++
++		clear_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.complete);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.ack);
++		clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
++	}
++
++
+ 	/* Wait for check parity and compute block operations to complete
+ 	 * before write-back.  If a failure occurred while the check operation
+ 	 * was in flight we need to cycle this stripe through handle_stripe
+diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
+index e709382..9fd8399 100644
+--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
++++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
+@@ -13,6 +13,7 @@
+ #include "dib7000p.h"
+ #include "mt2060.h"
+ #include "mt2266.h"
++#include "tuner-xc2028.h"
+ #include "dib0070.h"
+ 
+ static int force_lna_activation;
+@@ -297,6 +298,149 @@ static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap)
+ 		&stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0;;
+ }
+ 
++/* STK7700-PH: Digital/Analog Hybrid Tuner, e.h. Cinergy HT USB HE */
++struct dibx000_agc_config xc3028_agc_config = {
++	BAND_VHF | BAND_UHF,       /* band_caps */
++
++	/* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0,
++	 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
++	 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=2, P_agc_write=0 */
++	(0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) |
++	(3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */
++
++	712,	/* inv_gain */
++	21,	/* time_stabiliz */
++
++	0,	/* alpha_level */
++	118,	/* thlock */
++
++	0,	/* wbd_inv */
++	2867,	/* wbd_ref */
++	0,	/* wbd_sel */
++	2,	/* wbd_alpha */
++
++	0,	/* agc1_max */
++	0,	/* agc1_min */
++	39718,	/* agc2_max */
++	9930,	/* agc2_min */
++	0,	/* agc1_pt1 */
++	0,	/* agc1_pt2 */
++	0,	/* agc1_pt3 */
++	0,	/* agc1_slope1 */
++	0,	/* agc1_slope2 */
++	0,	/* agc2_pt1 */
++	128,	/* agc2_pt2 */
++	29,	/* agc2_slope1 */
++	29,	/* agc2_slope2 */
++
++	17,	/* alpha_mant */
++	27,	/* alpha_exp */
++	23,	/* beta_mant */
++	51,	/* beta_exp */
++
++	1,	/* perform_agc_softsplit */
++};
++
++/* PLL Configuration for COFDM BW_MHz = 8.00 with external clock = 30.00 */
++struct dibx000_bandwidth_config xc3028_bw_config = {
++	60000, 30000, /* internal, sampling */
++	1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */
++	0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, ADClkSrc,
++			  modulo */
++	(3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */
++	(1 << 25) | 5816102, /* ifreq = 5.200000 MHz */
++	20452225, /* timf */
++	30000000, /* xtal_hz */
++};
++
++static struct dib7000p_config stk7700ph_dib7700_xc3028_config = {
++	.output_mpeg2_in_188_bytes = 1,
++	.tuner_is_baseband = 1,
++
++	.agc_config_count = 1,
++	.agc = &xc3028_agc_config,
++	.bw  = &xc3028_bw_config,
++
++	.gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
++	.gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
++	.gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
++};
++
++static int stk7700ph_xc3028_callback(void *ptr, int command, int arg)
++{
++	struct dvb_usb_adapter *adap = ptr;
++
++	switch (command) {
++	case XC2028_TUNER_RESET:
++		/* Send the tuner in then out of reset */
++		dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10);
++		dib7000p_set_gpio(adap->fe, 8, 0, 1);
++		break;
++	case XC2028_RESET_CLK:
++		break;
++	default:
++		err("%s: unknown command %d, arg %d\n", __func__,
++			command, arg);
++		return -EINVAL;
++	}
++	return 0;
++}
++
++static struct xc2028_ctrl stk7700ph_xc3028_ctrl = {
++	.fname = XC2028_DEFAULT_FIRMWARE,
++	.max_len = 64,
++	.demod = XC3028_FE_DIBCOM52,
++};
++
++static struct xc2028_config stk7700ph_xc3028_config = {
++	.i2c_addr = 0x61,
++	.callback = stk7700ph_xc3028_callback,
++	.ctrl = &stk7700ph_xc3028_ctrl,
++};
++
++static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
++{
++	struct usb_device_descriptor *desc = &adap->dev->udev->descriptor;
++
++	if (desc->idVendor  == USB_VID_PINNACLE &&
++	    desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX)
++	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
++	else
++	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
++	msleep(20);
++	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
++	dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
++	dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
++	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
++	msleep(10);
++	dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
++	msleep(20);
++	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
++	msleep(10);
++
++	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
++		&stk7700ph_dib7700_xc3028_config);
++
++	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
++		&stk7700ph_dib7700_xc3028_config);
++
++	return adap->fe == NULL ? -ENODEV : 0;
++}
++
++static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap)
++{
++	struct i2c_adapter *tun_i2c;
++
++	tun_i2c = dib7000p_get_i2c_master(adap->fe,
++		DIBX000_I2C_INTERFACE_TUNER, 1);
++
++	stk7700ph_xc3028_config.i2c_adap = tun_i2c;
++	stk7700ph_xc3028_config.video_dev = adap;
++
++	return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config)
++		== NULL ? -ENODEV : 0;
++}
++
+ #define DEFAULT_RC_INTERVAL 150
+ 
+ static u8 rc_request[] = { REQUEST_POLL_RC, 0 };
+@@ -794,6 +938,10 @@ static struct dib7000p_config dib7070p_dib7000p_config = {
+ /* STK7070P */
+ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
+ {
++	if (adap->dev->udev->descriptor.idVendor  == USB_VID_PINNACLE &&
++	adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E)
++	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
++	else
+ 	dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ 	msleep(10);
+ 	dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
+@@ -808,9 +956,11 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
+ 	msleep(10);
+ 	dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+ 
+-	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, &dib7070p_dib7000p_config);
++	dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
++		&dib7070p_dib7000p_config);
+ 
+-	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config);
++	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
++		&dib7070p_dib7000p_config);
+ 	return adap->fe == NULL ? -ENODEV : 0;
+ }
+ 
+@@ -878,34 +1028,41 @@ static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap)
+ /* DVB-USB and USB stuff follows */
+ struct usb_device_id dib0700_usb_id_table[] = {
+ /* 0 */	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P) },
+-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
+-
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
++	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700P_PC) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_500_2) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK) },
+ /* 5 */	{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR) },
+-		{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
+-		{ USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
+-		{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
++	{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500) },
++	{ USB_DEVICE(USB_VID_UNIWILL,   USB_PID_UNIWILL_STK7700P) },
++	{ USB_DEVICE(USB_VID_LEADTEK,   USB_PID_WINFAST_DTV_DONGLE_STK7700P) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_2) },
+ /* 10 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_VOLAR_2) },
+-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
+-		{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
+-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
++	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV2000E) },
++	{ USB_DEVICE(USB_VID_TERRATEC,
++			USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_TD_STICK) },
++	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7700D) },
+ /* 15 */{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070P) },
+-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
+-		{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
+-		{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
+-		{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
++	{ USB_DEVICE(USB_VID_PINNACLE,  USB_PID_PINNACLE_PCTV_DVB_T_FLASH) },
++	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_STK7070PD) },
++	{ USB_DEVICE(USB_VID_PINNACLE,
++			USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T) },
++	{ USB_DEVICE(USB_VID_COMPRO,    USB_PID_COMPRO_VIDEOMATE_U500_PC) },
+ /* 20 */{ USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_EXPRESS) },
+-		{ USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
+-		{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
+-		{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
+-		{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
+-/* 25 */	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
+-		{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
+-		{ 0 }		/* Terminating entry */
++	{ USB_DEVICE(USB_VID_GIGABYTE,  USB_PID_GIGABYTE_U7000) },
++	{ USB_DEVICE(USB_VID_ULTIMA_ELECTRONIC, USB_PID_ARTEC_T14BR) },
++	{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3000) },
++	{ USB_DEVICE(USB_VID_ASUS,      USB_PID_ASUS_U3100) },
++/* 25 */{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_NOVA_T_STICK_3) },
++	{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_MYTV_T) },
++	{ USB_DEVICE(USB_VID_TERRATEC,  USB_PID_TERRATEC_CINERGY_HT_USB_XE) },
++	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_EXPRESSCARD_320CX) },
++	{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV72E) },
++/* 30 */{ USB_DEVICE(USB_VID_PINNACLE,	USB_PID_PINNACLE_PCTV73E) },
++	{ USB_DEVICE(USB_VID_YUAN,	USB_PID_YUAN_EC372S) },
++	{ USB_DEVICE(USB_VID_TERRATEC,	USB_PID_TERRATEC_CINERGY_HT_EXPRESS) },
++	{ 0 }		/* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
+ 
+@@ -1069,12 +1226,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+ 			},
+ 		},
+ 
+-		.num_device_descs = 1,
++		.num_device_descs = 2,
+ 		.devices = {
+ 			{   "ASUS My Cinema U3000 Mini DVBT Tuner",
+ 				{ &dib0700_usb_id_table[23], NULL },
+ 				{ NULL },
+ 			},
++			{   "Yuan EC372S",
++				{ &dib0700_usb_id_table[31], NULL },
++				{ NULL },
++			}
+ 		}
+ 	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ 
+@@ -1090,7 +1251,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+ 			},
+ 		},
+ 
+-		.num_device_descs = 6,
++		.num_device_descs = 8,
+ 		.devices = {
+ 			{   "DiBcom STK7070P reference design",
+ 				{ &dib0700_usb_id_table[15], NULL },
+@@ -1116,6 +1277,14 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+ 				{ &dib0700_usb_id_table[26], NULL },
+ 				{ NULL },
+ 			},
++			{   "Pinnacle PCTV 72e",
++				{ &dib0700_usb_id_table[29], NULL },
++				{ NULL },
++			},
++			{   "Pinnacle PCTV 73e",
++				{ &dib0700_usb_id_table[30], NULL },
++				{ NULL },
++			},
+ 		},
+ 
+ 		.rc_interval      = DEFAULT_RC_INTERVAL,
+@@ -1155,6 +1324,40 @@ struct dvb_usb_device_properties dib0700_devices[] = {
+ 				{ NULL },
+ 			}
+ 		}
++	}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
++
++		.num_adapters = 1,
++		.adapter = {
++			{
++				.frontend_attach  = stk7700ph_frontend_attach,
++				.tuner_attach     = stk7700ph_tuner_attach,
++
++				DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
++
++				.size_of_priv = sizeof(struct
++						dib0700_adapter_state),
++			},
++		},
++
++		.num_device_descs = 3,
++		.devices = {
++			{   "Terratec Cinergy HT USB XE",
++				{ &dib0700_usb_id_table[27], NULL },
++				{ NULL },
++			},
++			{   "Pinnacle Expresscard 320cx",
++				{ &dib0700_usb_id_table[28], NULL },
++				{ NULL },
++			},
++			{   "Terratec Cinergy HT Express",
++				{ &dib0700_usb_id_table[32], NULL },
++				{ NULL },
++			},
++		},
++		.rc_interval      = DEFAULT_RC_INTERVAL,
++		.rc_key_map       = dib0700_rc_keys,
++		.rc_key_map_size  = ARRAY_SIZE(dib0700_rc_keys),
++		.rc_query         = dib0700_rc_query
+ 	},
+ };
+ 
+diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+index aa4844e..49a44f2 100644
+--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
++++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+@@ -46,8 +46,8 @@
+ #define USB_VID_ULTIMA_ELECTRONIC		0x05d8
+ #define USB_VID_UNIWILL				0x1584
+ #define USB_VID_WIDEVIEW			0x14aa
+-/* dom : pour gigabyte u7000 */
+ #define USB_VID_GIGABYTE			0x1044
++#define USB_VID_YUAN				0x1164
+ 
+ 
+ /* Product IDs */
+@@ -135,9 +135,14 @@
+ #define USB_PID_AVERMEDIA_VOLAR				0xa807
+ #define USB_PID_AVERMEDIA_VOLAR_2			0xb808
+ #define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY	0x005a
++#define USB_PID_TERRATEC_CINERGY_HT_USB_XE		0x0058
++#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS		0x0060
++#define USB_PID_PINNACLE_EXPRESSCARD_320CX		0x022e
+ #define USB_PID_PINNACLE_PCTV2000E			0x022c
+ #define USB_PID_PINNACLE_PCTV_DVB_T_FLASH		0x0228
+ #define USB_PID_PINNACLE_PCTV_DUAL_DIVERSITY_DVB_T	0x0229
++#define USB_PID_PINNACLE_PCTV72E			0x0236
++#define USB_PID_PINNACLE_PCTV73E			0x0237
+ #define USB_PID_PCTV_200E				0x020e
+ #define USB_PID_PCTV_400E				0x020f
+ #define USB_PID_PCTV_450E				0x0222
+@@ -183,9 +188,9 @@
+ #define USB_PID_OPERA1_WARM				0x3829
+ #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_COLD		0x0514
+ #define USB_PID_LIFEVIEW_TV_WALKER_TWIN_WARM		0x0513
+-/* dom pour gigabyte u7000 */
+ #define USB_PID_GIGABYTE_U7000				0x7001
+ #define USB_PID_ASUS_U3000				0x171f
+ #define USB_PID_ASUS_U3100				0x173f
++#define  USB_PID_YUAN_EC372S				0x1edc
+ 
+ #endif
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index f651a81..34c2b98 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -450,7 +450,7 @@ static void macvlan_dellink(struct net_device *dev)
+ 	unregister_netdevice(dev);
+ 
+ 	if (list_empty(&port->vlans))
+-		macvlan_port_destroy(dev);
++		macvlan_port_destroy(port->dev);
+ }
+ 
+ static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
+diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
+index 3acfeea..6572425 100644
+--- a/drivers/net/r8169.c
++++ b/drivers/net/r8169.c
+@@ -1617,6 +1617,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	SET_NETDEV_DEV(dev, &pdev->dev);
+ 	tp = netdev_priv(dev);
+ 	tp->dev = dev;
++	tp->pci_dev = pdev;
+ 	tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
+ 
+ 	/* enable device (incl. PCI PM wakeup and hotplug setup) */
+@@ -1705,18 +1706,18 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	rtl8169_print_mac_version(tp);
+ 
+-	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
++	for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
+ 		if (tp->mac_version == rtl_chip_info[i].mac_version)
+ 			break;
+ 	}
+-	if (i < 0) {
++	if (i == ARRAY_SIZE(rtl_chip_info)) {
+ 		/* Unknown chip: assume array element #0, original RTL-8169 */
+ 		if (netif_msg_probe(tp)) {
+ 			dev_printk(KERN_DEBUG, &pdev->dev,
+ 				"unknown chip version, assuming %s\n",
+ 				rtl_chip_info[0].name);
+ 		}
+-		i++;
++		i = 0;
+ 	}
+ 	tp->chipset = i;
+ 
+@@ -1777,7 +1778,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ #endif
+ 
+ 	tp->intr_mask = 0xffff;
+-	tp->pci_dev = pdev;
+ 	tp->mmio_addr = ioaddr;
+ 	tp->align = cfg->align;
+ 	tp->hw_start = cfg->hw_start;
+diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
+index ba795a4..9f996ec 100644
+--- a/drivers/rtc/rtc-lib.c
++++ b/drivers/rtc/rtc-lib.c
+@@ -51,7 +51,7 @@ EXPORT_SYMBOL(rtc_year_days);
+  */
+ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
+ {
+-	register int days, month, year;
++	unsigned int days, month, year;
+ 
+ 	days = time / 86400;
+ 	time -= days * 86400;
+diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
+index 6ccdc96..d9bc859 100644
+--- a/drivers/scsi/aha152x.c
++++ b/drivers/scsi/aha152x.c
+@@ -3835,7 +3835,7 @@ static int __init aha152x_init(void)
+ 			iounmap(p);
+ 		}
+ 		if (!ok && setup_count == 0)
+-			return 0;
++			return -ENODEV;
+ 
+ 		printk(KERN_INFO "aha152x: BIOS test: passed, ");
+ #else
+@@ -3914,14 +3914,14 @@ static int __init aha152x_init(void)
+ #endif
+ 	}
+ 
+-	return 1;
++	return 0;
+ }
+ 
+ static void __exit aha152x_exit(void)
+ {
+-	struct aha152x_hostdata *hd;
++	struct aha152x_hostdata *hd, *tmp;
+ 
+-	list_for_each_entry(hd, &aha152x_host_list, host_list) {
++	list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {
+ 		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
+ 
+ 		aha152x_release(shost);
+diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
+index bdd7de7..9975095 100644
+--- a/drivers/scsi/libiscsi.c
++++ b/drivers/scsi/libiscsi.c
+@@ -635,7 +635,9 @@ static int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ 				if (iscsi_recv_pdu(conn->cls_conn, hdr, data,
+ 						   datalen))
+ 					rc = ISCSI_ERR_CONN_FAILED;
+-			}
++			} else
++				mod_timer(&conn->transport_timer,
++					  jiffies + conn->recv_timeout);
+ 			iscsi_free_mgmt_task(conn, mtask);
+ 			break;
+ 		default:
+@@ -1353,19 +1355,20 @@ static void iscsi_check_transport_timeouts(unsigned long data)
+ {
+ 	struct iscsi_conn *conn = (struct iscsi_conn *)data;
+ 	struct iscsi_session *session = conn->session;
+-	unsigned long timeout, next_timeout = 0, last_recv;
++	unsigned long recv_timeout, next_timeout = 0, last_recv;
+ 
+ 	spin_lock(&session->lock);
+ 	if (session->state != ISCSI_STATE_LOGGED_IN)
+ 		goto done;
+ 
+-	timeout = conn->recv_timeout;
+-	if (!timeout)
++	recv_timeout = conn->recv_timeout;
++	if (!recv_timeout)
+ 		goto done;
+ 
+-	timeout *= HZ;
++	recv_timeout *= HZ;
+ 	last_recv = conn->last_recv;
+-	if (time_before_eq(last_recv + timeout + (conn->ping_timeout * HZ),
++	if (conn->ping_mtask &&
++	    time_before_eq(conn->last_ping + (conn->ping_timeout * HZ),
+ 			   jiffies)) {
+ 		iscsi_conn_printk(KERN_ERR, conn, "ping timeout of %d secs "
+ 				  "expired, last rx %lu, last ping %lu, "
+@@ -1376,15 +1379,13 @@ static void iscsi_check_transport_timeouts(unsigned long data)
+ 		return;
+ 	}
+ 
+-	if (time_before_eq(last_recv + timeout, jiffies)) {
+-		if (time_before_eq(conn->last_ping, last_recv)) {
+-			/* send a ping to try to provoke some traffic */
+-			debug_scsi("Sending nopout as ping on conn %p\n", conn);
+-			iscsi_send_nopout(conn, NULL);
+-		}
+-		next_timeout = last_recv + timeout + (conn->ping_timeout * HZ);
++	if (time_before_eq(last_recv + recv_timeout, jiffies)) {
++		/* send a ping to try to provoke some traffic */
++		debug_scsi("Sending nopout as ping on conn %p\n", conn);
++		iscsi_send_nopout(conn, NULL);
++		next_timeout = conn->last_ping + (conn->ping_timeout * HZ);
+ 	} else
+-		next_timeout = last_recv + timeout;
++		next_timeout = last_recv + recv_timeout;
+ 
+ 	debug_scsi("Setting next tmo %lu\n", next_timeout);
+ 	mod_timer(&conn->transport_timer, next_timeout);
+diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
+index 68c0d09..624e616 100644
+--- a/drivers/scsi/qla1280.c
++++ b/drivers/scsi/qla1280.c
+@@ -2012,7 +2012,7 @@ qla1280_set_defaults(struct scsi_qla_host *ha)
+ 		nv->bus[bus].config_2.req_ack_active_negation = 1;
+ 		nv->bus[bus].config_2.data_line_active_negation = 1;
+ 		nv->bus[bus].selection_timeout = 250;
+-		nv->bus[bus].max_queue_depth = 256;
++		nv->bus[bus].max_queue_depth = 32;
+ 
+ 		if (IS_ISP1040(ha)) {
+ 			nv->bus[bus].bus_reset_delay = 3;
+@@ -2056,7 +2056,7 @@ qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
+ 	status = qla1280_mailbox_command(ha, 0x0f, mb);
+ 
+ 	/* Save Tag queuing enable flag. */
+-	flag = (BIT_0 << target) & mb[0];
++	flag = (BIT_0 << target);
+ 	if (nv->bus[bus].target[target].parameter.tag_queuing)
+ 		ha->bus_settings[bus].qtag_enables |= flag;
+ 
+diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
+index 0f5a179..3bf9294 100644
+--- a/drivers/serial/serial_core.c
++++ b/drivers/serial/serial_core.c
+@@ -535,7 +535,7 @@ static int uart_chars_in_buffer(struct tty_struct *tty)
+ static void uart_flush_buffer(struct tty_struct *tty)
+ {
+ 	struct uart_state *state = tty->driver_data;
+-	struct uart_port *port = state->port;
++	struct uart_port *port;
+ 	unsigned long flags;
+ 
+ 	/*
+@@ -547,6 +547,7 @@ static void uart_flush_buffer(struct tty_struct *tty)
+ 		return;
+ 	}
+ 
++	port = state->port;
+ 	pr_debug("uart_flush_buffer(%d) called\n", tty->index);
+ 
+ 	spin_lock_irqsave(&port->lock, flags);
+diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
+index be0fe15..145c028 100644
+--- a/drivers/serial/sunhv.c
++++ b/drivers/serial/sunhv.c
+@@ -392,7 +392,7 @@ static struct uart_ops sunhv_pops = {
+ 
+ static struct uart_driver sunhv_reg = {
+ 	.owner			= THIS_MODULE,
+-	.driver_name		= "serial",
++	.driver_name		= "sunhv",
+ 	.dev_name		= "ttyS",
+ 	.major			= TTY_MAJOR,
+ };
+diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
+index 543f937..9ff5b38 100644
+--- a/drivers/serial/sunsab.c
++++ b/drivers/serial/sunsab.c
+@@ -826,7 +826,7 @@ static struct uart_ops sunsab_pops = {
+ 
+ static struct uart_driver sunsab_reg = {
+ 	.owner			= THIS_MODULE,
+-	.driver_name		= "serial",
++	.driver_name		= "sunsab",
+ 	.dev_name		= "ttyS",
+ 	.major			= TTY_MAJOR,
+ };
+diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
+index 4e2302d..03806a9 100644
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1173,7 +1173,7 @@ out:
+ 
+ static struct uart_driver sunsu_reg = {
+ 	.owner			= THIS_MODULE,
+-	.driver_name		= "serial",
++	.driver_name		= "sunsu",
+ 	.dev_name		= "ttyS",
+ 	.major			= TTY_MAJOR,
+ };
+diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
+index cb2e405..87210c0 100644
+--- a/drivers/serial/sunzilog.c
++++ b/drivers/serial/sunzilog.c
+@@ -1015,6 +1015,7 @@ static struct uart_ops sunzilog_pops = {
+ 	.verify_port	=	sunzilog_verify_port,
+ };
+ 
++static int uart_chip_count;
+ static struct uart_sunzilog_port *sunzilog_port_table;
+ static struct zilog_layout __iomem **sunzilog_chip_regs;
+ 
+@@ -1022,7 +1023,7 @@ static struct uart_sunzilog_port *sunzilog_irq_chain;
+ 
+ static struct uart_driver sunzilog_reg = {
+ 	.owner		=	THIS_MODULE,
+-	.driver_name	=	"ttyS",
++	.driver_name	=	"sunzilog",
+ 	.dev_name	=	"ttyS",
+ 	.major		=	TTY_MAJOR,
+ };
+@@ -1350,16 +1351,22 @@ static int zilog_irq = -1;
+ 
+ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
+ {
+-	static int inst;
++	static int kbm_inst, uart_inst;
++	int inst;
+ 	struct uart_sunzilog_port *up;
+ 	struct zilog_layout __iomem *rp;
+-	int keyboard_mouse;
++	int keyboard_mouse = 0;
+ 	int err;
+ 
+-	keyboard_mouse = 0;
+ 	if (of_find_property(op->node, "keyboard", NULL))
+ 		keyboard_mouse = 1;
+ 
++	/* uarts must come before keyboards/mice */
++	if (keyboard_mouse)
++		inst = uart_chip_count + kbm_inst;
++	else
++		inst = uart_inst;
++
+ 	sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
+ 					      sizeof(struct zilog_layout),
+ 					      "zs");
+@@ -1427,6 +1434,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
+ 				   rp, sizeof(struct zilog_layout));
+ 			return err;
+ 		}
++		uart_inst++;
+ 	} else {
+ 		printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) "
+ 		       "is a %s\n",
+@@ -1438,12 +1446,11 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
+ 		       op->dev.bus_id,
+ 		       (unsigned long long) up[1].port.mapbase,
+ 		       op->irqs[0], sunzilog_type(&up[1].port));
++		kbm_inst++;
+ 	}
+ 
+ 	dev_set_drvdata(&op->dev, &up[0]);
+ 
+-	inst++;
+-
+ 	return 0;
+ }
+ 
+@@ -1491,28 +1498,25 @@ static struct of_platform_driver zs_driver = {
+ static int __init sunzilog_init(void)
+ {
+ 	struct device_node *dp;
+-	int err, uart_count;
+-	int num_keybms;
++	int err;
++	int num_keybms = 0;
+ 	int num_sunzilog = 0;
+ 
+-	num_keybms = 0;
+ 	for_each_node_by_name(dp, "zs") {
+ 		num_sunzilog++;
+ 		if (of_find_property(dp, "keyboard", NULL))
+ 			num_keybms++;
+ 	}
+ 
+-	uart_count = 0;
+ 	if (num_sunzilog) {
+-		int uart_count;
+-
+ 		err = sunzilog_alloc_tables(num_sunzilog);
+ 		if (err)
+ 			goto out;
+ 
+-		uart_count = (num_sunzilog * 2) - (2 * num_keybms);
++		uart_chip_count = num_sunzilog - num_keybms;
+ 
+-		err = sunserial_register_minors(&sunzilog_reg, uart_count);
++		err = sunserial_register_minors(&sunzilog_reg,
++						uart_chip_count * 2);
+ 		if (err)
+ 			goto out_free_tables;
+ 	}
+diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
+index d72dc07..e534f9d 100644
+--- a/drivers/usb/host/ohci-at91.c
++++ b/drivers/usb/host/ohci-at91.c
+@@ -348,6 +348,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
+ 	if (!clocked)
+ 		at91_start_clock();
+ 
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ #else
+diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c
+index 156e93a..963ed60 100644
+--- a/drivers/usb/host/ohci-ep93xx.c
++++ b/drivers/usb/host/ohci-ep93xx.c
+@@ -194,8 +194,8 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev)
+ 
+ 	ep93xx_start_hc(&pdev->dev);
+ 	pdev->dev.power.power_state = PMSG_ON;
+-	usb_hcd_resume_root_hub(hcd);
+ 
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ #endif
+diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
+index 48e4b11..9eff2de 100644
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -326,6 +326,49 @@ static int ohci_bus_resume (struct usb_hcd *hcd)
+ 	return rc;
+ }
+ 
++/* Carry out the final steps of resuming the controller device */
++static void ohci_finish_controller_resume(struct usb_hcd *hcd)
++{
++	struct ohci_hcd		*ohci = hcd_to_ohci(hcd);
++	int			port;
++	bool			need_reinit = false;
++
++	/* See if the controller is already running or has been reset */
++	ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
++	if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) {
++		need_reinit = true;
++	} else {
++		switch (ohci->hc_control & OHCI_CTRL_HCFS) {
++		case OHCI_USB_OPER:
++		case OHCI_USB_RESET:
++			need_reinit = true;
++		}
++	}
++
++	/* If needed, reinitialize and suspend the root hub */
++	if (need_reinit) {
++		spin_lock_irq(&ohci->lock);
++		hcd->state = HC_STATE_RESUMING;
++		ohci_rh_resume(ohci);
++		hcd->state = HC_STATE_QUIESCING;
++		ohci_rh_suspend(ohci, 0);
++		hcd->state = HC_STATE_SUSPENDED;
++		spin_unlock_irq(&ohci->lock);
++	}
++
++	/* Normally just turn on port power and enable interrupts */
++	else {
++		ohci_dbg(ohci, "powerup ports\n");
++		for (port = 0; port < ohci->num_ports; port++)
++			ohci_writel(ohci, RH_PS_PPS,
++					&ohci->regs->roothub.portstatus[port]);
++
++		ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
++		ohci_readl(ohci, &ohci->regs->intrenable);
++		msleep(20);
++	}
++}
++
+ /* Carry out polling-, autostop-, and autoresume-related state changes */
+ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
+ 		int any_connected)
+diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
+index 7bfca1e..611bc9f 100644
+--- a/drivers/usb/host/ohci-omap.c
++++ b/drivers/usb/host/ohci-omap.c
+@@ -519,7 +519,7 @@ static int ohci_omap_resume(struct platform_device *dev)
+ 
+ 	omap_ohci_clock_power(1);
+ 	dev->dev.power.power_state = PMSG_ON;
+-	usb_hcd_resume_root_hub(platform_get_drvdata(dev));
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
+index b0e2275..b4886e1 100644
+--- a/drivers/usb/host/ohci-pci.c
++++ b/drivers/usb/host/ohci-pci.c
+@@ -238,42 +238,6 @@ static int __devinit ohci_pci_start (struct usb_hcd *hcd)
+ 	return ret;
+ }
+ 
+-#if	defined(CONFIG_USB_PERSIST) && (defined(CONFIG_USB_EHCI_HCD) || \
+-		defined(CONFIG_USB_EHCI_HCD_MODULE))
+-
+-/* Following a power loss, we must prepare to regain control of the ports
+- * we used to own.  This means turning on the port power before ehci-hcd
+- * tries to switch ownership.
+- *
+- * This isn't a 100% perfect solution.  On most systems the OHCI controllers
+- * lie at lower PCI addresses than the EHCI controller, so they will be
+- * discovered (and hence resumed) first.  But there is no guarantee things
+- * will always work this way.  If the EHCI controller is resumed first and
+- * the OHCI ports are unpowered, then the handover will fail.
+- */
+-static void prepare_for_handover(struct usb_hcd *hcd)
+-{
+-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+-	int		port;
+-
+-	/* Here we "know" root ports should always stay powered */
+-	ohci_dbg(ohci, "powerup ports\n");
+-	for (port = 0; port < ohci->num_ports; port++)
+-		ohci_writel(ohci, RH_PS_PPS,
+-				&ohci->regs->roothub.portstatus[port]);
+-
+-	/* Flush those writes */
+-	ohci_readl(ohci, &ohci->regs->control);
+-	msleep(20);
+-}
+-
+-#else
+-
+-static inline void prepare_for_handover(struct usb_hcd *hcd)
+-{ }
+-
+-#endif	/* CONFIG_USB_PERSIST etc. */
+-
+ #ifdef	CONFIG_PM
+ 
+ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
+@@ -312,13 +276,8 @@ static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message)
+ 
+ static int ohci_pci_resume (struct usb_hcd *hcd)
+ {
+-	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+-
+ 	set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+-
+-	/* FIXME: we should try to detect loss of VBUS power here */
+-	prepare_for_handover(hcd);
+-	ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrenable);
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
+index 8ad9b3b..3de3b00 100644
+--- a/drivers/usb/host/ohci-pxa27x.c
++++ b/drivers/usb/host/ohci-pxa27x.c
+@@ -358,8 +358,7 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
+ 		return status;
+ 
+ 	pdev->dev.power.power_state = PMSG_ON;
+-	usb_hcd_resume_root_hub(hcd);
+-
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ #endif
+diff --git a/drivers/usb/host/ohci-sm501.c b/drivers/usb/host/ohci-sm501.c
+index 4ea9276..c852f03 100644
+--- a/drivers/usb/host/ohci-sm501.c
++++ b/drivers/usb/host/ohci-sm501.c
+@@ -239,7 +239,7 @@ static int ohci_sm501_resume(struct platform_device *pdev)
+ 
+ 	sm501_unit_power(dev->parent, SM501_GATE_USB_HOST, 1);
+ 	dev->power.power_state = PMSG_ON;
+-	usb_hcd_resume_root_hub(platform_get_drvdata(pdev));
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ #endif
+diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c
+index 6e9c2d6..1c0867a 100644
+--- a/drivers/usb/host/ohci-ssb.c
++++ b/drivers/usb/host/ohci-ssb.c
+@@ -224,6 +224,7 @@ static int ssb_ohci_resume(struct ssb_device *dev)
+ 
+ 	ssb_device_enable(dev, ohcidev->enable_flags);
+ 
++	ohci_finish_controller_resume(hcd);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
+index f156dba..a3482fc 100644
+--- a/drivers/usb/serial/airprime.c
++++ b/drivers/usb/serial/airprime.c
+@@ -220,7 +220,7 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
+ 	mutex_lock(&port->serial->disc_mutex);
+ 	if (!port->serial->disconnected)
+ 		airprime_send_setup(port);
+-	mutex_lock(&port->serial->disc_mutex);
++	mutex_unlock(&port->serial->disc_mutex);
+ 
+ 	for (i = 0; i < NUM_READ_URBS; ++i) {
+ 		usb_kill_urb (priv->read_urbp[i]);
+diff --git a/include/asm-sparc/mman.h b/include/asm-sparc/mman.h
+index b7dc40b..632cd8a 100644
+--- a/include/asm-sparc/mman.h
++++ b/include/asm-sparc/mman.h
+@@ -37,9 +37,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc_mmap_check
+-int sparc_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc_mmap_check(addr,len)
++int sparc_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 
+diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h
+index 19c9780..2139704 100644
+--- a/include/asm-sparc/psr.h
++++ b/include/asm-sparc/psr.h
+@@ -25,6 +25,7 @@
+ #define PSR_PIL     0x00000f00         /* processor interrupt level  */
+ #define PSR_EF      0x00001000         /* enable floating point      */
+ #define PSR_EC      0x00002000         /* enable co-processor        */
++#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
+ #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+ #define PSR_ICC     0x00f00000         /* integer condition codes    */
+ #define PSR_C       0x00100000         /* carry bit                  */
+diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
+index 8201a7b..0afb867 100644
+--- a/include/asm-sparc/ptrace.h
++++ b/include/asm-sparc/ptrace.h
+@@ -10,6 +10,8 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
++#include <linux/types.h>
++
+ struct pt_regs {
+ 	unsigned long psr;
+ 	unsigned long pc;
+@@ -39,6 +41,16 @@ struct pt_regs {
+ #define UREG_FP        UREG_I6
+ #define UREG_RETPC     UREG_I7
+ 
++static inline bool pt_regs_is_syscall(struct pt_regs *regs)
++{
++	return (regs->psr & PSR_SYSCALL);
++}
++
++static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
++{
++	return (regs->psr &= ~PSR_SYSCALL);
++}
++
+ /* A register window */
+ struct reg_window {
+ 	unsigned long locals[8];
+@@ -149,6 +161,7 @@ extern void show_regs(struct pt_regs *);
+ #define SF_XXARG  0x5c
+ 
+ /* Stuff for the ptrace system call */
++#define PTRACE_SPARC_DETACH       11
+ #define PTRACE_GETREGS            12
+ #define PTRACE_SETREGS            13
+ #define PTRACE_GETFPREGS          14
+diff --git a/include/asm-sparc/signal.h b/include/asm-sparc/signal.h
+index d03a21c..94071c7 100644
+--- a/include/asm-sparc/signal.h
++++ b/include/asm-sparc/signal.h
+@@ -199,13 +199,7 @@ typedef struct sigaltstack {
+ 	size_t		ss_size;
+ } stack_t;
+ 
+-struct sparc_deliver_cookie {
+-	int restart_syscall;
+-	unsigned long orig_i0;
+-};
+-
+-struct pt_regs;
+-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+ 
+ #endif /* !(__KERNEL__) */
+ 
+diff --git a/include/asm-sparc64/mman.h b/include/asm-sparc64/mman.h
+index 8cc1860..e0fcfca 100644
+--- a/include/asm-sparc64/mman.h
++++ b/include/asm-sparc64/mman.h
+@@ -37,9 +37,8 @@
+ 
+ #ifdef __KERNEL__
+ #ifndef __ASSEMBLY__
+-#define arch_mmap_check	sparc64_mmap_check
+-int sparc64_mmap_check(unsigned long addr, unsigned long len,
+-		unsigned long flags);
++#define arch_mmap_check(addr,len,flags)	sparc64_mmap_check(addr,len)
++int sparc64_mmap_check(unsigned long addr, unsigned long len);
+ #endif
+ #endif
+ 
+diff --git a/include/asm-sparc64/psrcompat.h b/include/asm-sparc64/psrcompat.h
+index 5590ce6..3614ca0 100644
+--- a/include/asm-sparc64/psrcompat.h
++++ b/include/asm-sparc64/psrcompat.h
+@@ -12,6 +12,7 @@
+ #define PSR_PIL     0x00000f00         /* processor interrupt level  */
+ #define PSR_EF      0x00001000         /* enable floating point      */
+ #define PSR_EC      0x00002000         /* enable co-processor        */
++#define PSR_SYSCALL 0x00004000         /* inside of a syscall        */
+ #define PSR_LE      0x00008000         /* SuperSparcII little-endian */
+ #define PSR_ICC     0x00f00000         /* integer condition codes    */
+ #define PSR_C       0x00100000         /* carry bit                  */
+@@ -30,6 +31,7 @@ static inline unsigned int tstate_to_psr(unsigned long tstate)
+ 		PSR_S					|
+ 		((tstate & TSTATE_ICC) >> 12)		|
+ 		((tstate & TSTATE_XCC) >> 20)		|
++		((tstate & TSTATE_SYSCALL) ? PSR_SYSCALL : 0) |
+ 		PSR_V8PLUS);
+ }
+ 
+diff --git a/include/asm-sparc64/pstate.h b/include/asm-sparc64/pstate.h
+index f3c4548..949aeba 100644
+--- a/include/asm-sparc64/pstate.h
++++ b/include/asm-sparc64/pstate.h
+@@ -62,6 +62,7 @@
+ #define TSTATE_PRIV	_AC(0x0000000000000400,UL) /* Privilege.	*/
+ #define TSTATE_IE	_AC(0x0000000000000200,UL) /* Interrupt Enable.	*/
+ #define TSTATE_AG	_AC(0x0000000000000100,UL) /* Alternate Globals.*/
++#define TSTATE_SYSCALL	_AC(0x0000000000000020,UL) /* in syscall trap   */
+ #define TSTATE_CWP	_AC(0x000000000000001f,UL) /* Curr Win-Pointer.	*/
+ 
+ /* Floating-Point Registers State Register.
+diff --git a/include/asm-sparc64/ptrace.h b/include/asm-sparc64/ptrace.h
+index 6da1978..0093f60 100644
+--- a/include/asm-sparc64/ptrace.h
++++ b/include/asm-sparc64/ptrace.h
+@@ -10,6 +10,8 @@
+ 
+ #ifndef __ASSEMBLY__
+ 
++#include <linux/types.h>
++
+ struct pt_regs {
+ 	unsigned long u_regs[16]; /* globals and ins */
+ 	unsigned long tstate;
+@@ -27,6 +29,16 @@ struct pt_regs32 {
+ 	unsigned int u_regs[16]; /* globals and ins */
+ };
+ 
++static inline bool pt_regs_is_syscall(struct pt_regs *regs)
++{
++	return (regs->tstate & TSTATE_SYSCALL);
++}
++
++static inline bool pt_regs_clear_syscall(struct pt_regs *regs)
++{
++	return (regs->tstate &= ~TSTATE_SYSCALL);
++}
++
+ #define UREG_G0        0
+ #define UREG_G1        1
+ #define UREG_G2        2
+@@ -263,6 +275,7 @@ extern void __show_regs(struct pt_regs *);
+ #define SF_XXARG  0x5c
+ 
+ /* Stuff for the ptrace system call */
++#define PTRACE_SPARC_DETACH       11
+ #define PTRACE_GETREGS            12
+ #define PTRACE_SETREGS            13
+ #define PTRACE_GETFPREGS          14
+diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h
+index fa6f467..c49f32d 100644
+--- a/include/asm-sparc64/signal.h
++++ b/include/asm-sparc64/signal.h
+@@ -186,13 +186,7 @@ struct k_sigaction {
+ 	void __user		*ka_restorer;
+ };
+ 
+-struct signal_deliver_cookie {
+-	int restart_syscall;
+-	unsigned long orig_i0;
+-};
+-
+-struct pt_regs;
+-extern void ptrace_signal_deliver(struct pt_regs *regs, void *cookie);
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
+ 
+ #endif /* !(__KERNEL__) */
+ 
+diff --git a/include/asm-sparc64/ttable.h b/include/asm-sparc64/ttable.h
+index bbb9c8f..6ef3d3b 100644
+--- a/include/asm-sparc64/ttable.h
++++ b/include/asm-sparc64/ttable.h
+@@ -91,13 +91,14 @@
+ 	 clr	%l6;
+ 	
+ #define SYSCALL_TRAP(routine, systbl)			\
++	rdpr	%pil, %g2;				\
++	mov	TSTATE_SYSCALL, %g3;			\
+ 	sethi	%hi(109f), %g7;				\
+-	ba,pt	%xcc, etrap;				\
++	ba,pt	%xcc, etrap_syscall;			\
+ 109:	 or	%g7, %lo(109b), %g7;			\
+ 	sethi	%hi(systbl), %l7;			\
+ 	ba,pt	%xcc, routine;				\
+-	 or	%l7, %lo(systbl), %l7;			\
+-	nop; nop;
++	 or	%l7, %lo(systbl), %l7;
+ 	
+ #define INDIRECT_SOLARIS_SYSCALL(num)			\
+ 	sethi	%hi(109f), %g7;				\
+diff --git a/include/asm-x86/topology.h b/include/asm-x86/topology.h
+index 8af05a9..db684e1 100644
+--- a/include/asm-x86/topology.h
++++ b/include/asm-x86/topology.h
+@@ -25,6 +25,16 @@
+ #ifndef _ASM_X86_TOPOLOGY_H
+ #define _ASM_X86_TOPOLOGY_H
+ 
++#ifdef CONFIG_X86_32
++# ifdef CONFIG_X86_HT
++#  define ENABLE_TOPO_DEFINES
++# endif
++#else
++# ifdef CONFIG_SMP
++#  define ENABLE_TOPO_DEFINES
++# endif
++#endif
++
+ #ifdef CONFIG_NUMA
+ #include <linux/cpumask.h>
+ #include <asm/mpspec.h>
+@@ -112,10 +122,6 @@ extern unsigned long node_end_pfn[];
+ extern unsigned long node_remap_size[];
+ #define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
+ 
+-# ifdef CONFIG_X86_HT
+-#  define ENABLE_TOPO_DEFINES
+-# endif
+-
+ # define SD_CACHE_NICE_TRIES	1
+ # define SD_IDLE_IDX		1
+ # define SD_NEWIDLE_IDX		2
+@@ -123,10 +129,6 @@ extern unsigned long node_remap_size[];
+ 
+ #else
+ 
+-# ifdef CONFIG_SMP
+-#  define ENABLE_TOPO_DEFINES
+-# endif
+-
+ # define SD_CACHE_NICE_TRIES	2
+ # define SD_IDLE_IDX		2
+ # define SD_NEWIDLE_IDX		0
+diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
+index 56f3c94..9a51eba 100644
+--- a/include/net/ip_vs.h
++++ b/include/net/ip_vs.h
+@@ -405,7 +405,8 @@ struct sk_buff;
+ struct ip_vs_protocol {
+ 	struct ip_vs_protocol	*next;
+ 	char			*name;
+-	__u16			protocol;
++	u16			protocol;
++	u16			num_states;
+ 	int			dont_defrag;
+ 	atomic_t		appcnt;		/* counter of proto app incs */
+ 	int			*timeout_table;	/* protocol timeout table */
+diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
+index e69ab2e..d9a4f7f 100644
+--- a/include/net/netfilter/nf_conntrack_tuple.h
++++ b/include/net/netfilter/nf_conntrack_tuple.h
+@@ -101,16 +101,6 @@ struct nf_conntrack_tuple_mask
+ 	} src;
+ };
+ 
+-/* This is optimized opposed to a memset of the whole structure.  Everything we
+- * really care about is the  source/destination unions */
+-#define NF_CT_TUPLE_U_BLANK(tuple)                              	\
+-        do {                                                    	\
+-                (tuple)->src.u.all = 0;                         	\
+-                (tuple)->dst.u.all = 0;                         	\
+-		memset(&(tuple)->src.u3, 0, sizeof((tuple)->src.u3));	\
+-		memset(&(tuple)->dst.u3, 0, sizeof((tuple)->dst.u3));	\
+-        } while (0)
+-
+ #ifdef __KERNEL__
+ 
+ #define NF_CT_DUMP_TUPLE(tp)						     \
+diff --git a/net/can/af_can.c b/net/can/af_can.c
+index 36b9f22..6b956f5 100644
+--- a/net/can/af_can.c
++++ b/net/can/af_can.c
+@@ -208,6 +208,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
+  */
+ int can_send(struct sk_buff *skb, int loop)
+ {
++	struct sk_buff *newskb = NULL;
+ 	int err;
+ 
+ 	if (skb->dev->type != ARPHRD_CAN) {
+@@ -244,8 +245,7 @@ int can_send(struct sk_buff *skb, int loop)
+ 			 * If the interface is not capable to do loopback
+ 			 * itself, we do it here.
+ 			 */
+-			struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
+-
++			newskb = skb_clone(skb, GFP_ATOMIC);
+ 			if (!newskb) {
+ 				kfree_skb(skb);
+ 				return -ENOMEM;
+@@ -254,7 +254,6 @@ int can_send(struct sk_buff *skb, int loop)
+ 			newskb->sk = skb->sk;
+ 			newskb->ip_summed = CHECKSUM_UNNECESSARY;
+ 			newskb->pkt_type = PACKET_BROADCAST;
+-			netif_rx(newskb);
+ 		}
+ 	} else {
+ 		/* indication for the CAN driver: no loopback required */
+@@ -266,11 +265,20 @@ int can_send(struct sk_buff *skb, int loop)
+ 	if (err > 0)
+ 		err = net_xmit_errno(err);
+ 
++	if (err) {
++		if (newskb)
++			kfree_skb(newskb);
++		return err;
++	}
++
++	if (newskb)
++		netif_rx(newskb);
++
+ 	/* update statistics */
+ 	can_stats.tx_frames++;
+ 	can_stats.tx_frames_delta++;
+ 
+-	return err;
++	return 0;
+ }
+ EXPORT_SYMBOL(can_send);
+ 
+diff --git a/net/dccp/feat.c b/net/dccp/feat.c
+index 4a4f6ce..933a0ec 100644
+--- a/net/dccp/feat.c
++++ b/net/dccp/feat.c
+@@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
+ 
+ 	if (len > 3) {
+ 		DCCP_WARN("invalid length %d\n", len);
+-		return 1;
++		return -EINVAL;
+ 	}
+ 	/* XXX add further sanity checks */
+ 
+diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
+index dde28a2..4b1c16c 100644
+--- a/net/ipv4/ipvs/ip_vs_proto.c
++++ b/net/ipv4/ipvs/ip_vs_proto.c
+@@ -148,7 +148,7 @@ const char * ip_vs_state_name(__u16 proto, int state)
+ 	struct ip_vs_protocol *pp = ip_vs_proto_get(proto);
+ 
+ 	if (pp == NULL || pp->state_name == NULL)
+-		return "ERR!";
++		return (IPPROTO_IP == proto) ? "NONE" : "ERR!";
+ 	return pp->state_name(state);
+ }
+ 
+diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
+index a842676..4bf835e 100644
+--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
++++ b/net/ipv4/ipvs/ip_vs_proto_ah.c
+@@ -160,6 +160,7 @@ static void ah_exit(struct ip_vs_protocol *pp)
+ struct ip_vs_protocol ip_vs_protocol_ah = {
+ 	.name =			"AH",
+ 	.protocol =		IPPROTO_AH,
++	.num_states =		1,
+ 	.dont_defrag =		1,
+ 	.init =			ah_init,
+ 	.exit =			ah_exit,
+diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
+index aef0d3e..db6a6b7 100644
+--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
++++ b/net/ipv4/ipvs/ip_vs_proto_esp.c
+@@ -159,6 +159,7 @@ static void esp_exit(struct ip_vs_protocol *pp)
+ struct ip_vs_protocol ip_vs_protocol_esp = {
+ 	.name =			"ESP",
+ 	.protocol =		IPPROTO_ESP,
++	.num_states =		1,
+ 	.dont_defrag =		1,
+ 	.init =			esp_init,
+ 	.exit =			esp_exit,
+diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
+index 12dc0d6..480f876 100644
+--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
++++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
+@@ -594,6 +594,7 @@ static void ip_vs_tcp_exit(struct ip_vs_protocol *pp)
+ struct ip_vs_protocol ip_vs_protocol_tcp = {
+ 	.name =			"TCP",
+ 	.protocol =		IPPROTO_TCP,
++	.num_states =		IP_VS_TCP_S_LAST,
+ 	.dont_defrag =		0,
+ 	.appcnt =		ATOMIC_INIT(0),
+ 	.init =			ip_vs_tcp_init,
+diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
+index 1fa7b33..8e3b059 100644
+--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
++++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
+@@ -409,6 +409,7 @@ static void udp_exit(struct ip_vs_protocol *pp)
+ struct ip_vs_protocol ip_vs_protocol_udp = {
+ 	.name =			"UDP",
+ 	.protocol =		IPPROTO_UDP,
++	.num_states =		IP_VS_UDP_S_LAST,
+ 	.dont_defrag =		0,
+ 	.init =			udp_init,
+ 	.exit =			udp_exit,
+diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
+index 948378d..a392d6e 100644
+--- a/net/ipv4/ipvs/ip_vs_sync.c
++++ b/net/ipv4/ipvs/ip_vs_sync.c
+@@ -288,11 +288,16 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
+ 	char *p;
+ 	int i;
+ 
++	if (buflen < sizeof(struct ip_vs_sync_mesg)) {
++		IP_VS_ERR_RL("sync message header too short\n");
++		return;
++	}
++
+ 	/* Convert size back to host byte order */
+ 	m->size = ntohs(m->size);
+ 
+ 	if (buflen != m->size) {
+-		IP_VS_ERR("bogus message\n");
++		IP_VS_ERR_RL("bogus sync message size\n");
+ 		return;
+ 	}
+ 
+@@ -307,9 +312,48 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
+ 	for (i=0; i<m->nr_conns; i++) {
+ 		unsigned flags, state;
+ 
+-		s = (struct ip_vs_sync_conn *)p;
++		if (p + SIMPLE_CONN_SIZE > buffer+buflen) {
++			IP_VS_ERR_RL("bogus conn in sync message\n");
++			return;
++		}
++		s = (struct ip_vs_sync_conn *) p;
+ 		flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC;
++		flags &= ~IP_VS_CONN_F_HASHED;
++		if (flags & IP_VS_CONN_F_SEQ_MASK) {
++			opt = (struct ip_vs_sync_conn_options *)&s[1];
++			p += FULL_CONN_SIZE;
++			if (p > buffer+buflen) {
++				IP_VS_ERR_RL("bogus conn options in sync message\n");
++				return;
++			}
++		} else {
++			opt = NULL;
++			p += SIMPLE_CONN_SIZE;
++		}
++
+ 		state = ntohs(s->state);
++		if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
++			pp = ip_vs_proto_get(s->protocol);
++			if (!pp) {
++				IP_VS_ERR_RL("Unsupported protocol %u in sync msg\n",
++					s->protocol);
++				continue;
++			}
++			if (state >= pp->num_states) {
++				IP_VS_DBG(2, "Invalid %s state %u in sync msg\n",
++					pp->name, state);
++				continue;
++			}
++		} else {
++			/* protocol in templates is not used for state/timeout */
++			pp = NULL;
++			if (state > 0) {
++				IP_VS_DBG(2, "Invalid template state %u in sync msg\n",
++					state);
++				state = 0;
++			}
++		}
++
+ 		if (!(flags & IP_VS_CONN_F_TEMPLATE))
+ 			cp = ip_vs_conn_in_get(s->protocol,
+ 					       s->caddr, s->cport,
+@@ -345,14 +389,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
+ 				IP_VS_ERR("ip_vs_conn_new failed\n");
+ 				return;
+ 			}
+-			cp->state = state;
+ 		} else if (!cp->dest) {
+ 			dest = ip_vs_try_bind_dest(cp);
+-			if (!dest) {
+-				/* it is an unbound entry created by
+-				 * synchronization */
+-				cp->flags = flags | IP_VS_CONN_F_HASHED;
+-			} else
++			if (dest)
+ 				atomic_dec(&dest->refcnt);
+ 		} else if ((cp->dest) && (cp->protocol == IPPROTO_TCP) &&
+ 			   (cp->state != state)) {
+@@ -371,23 +410,22 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
+ 			}
+ 		}
+ 
+-		if (flags & IP_VS_CONN_F_SEQ_MASK) {
+-			opt = (struct ip_vs_sync_conn_options *)&s[1];
++		if (opt)
+ 			memcpy(&cp->in_seq, opt, sizeof(*opt));
+-			p += FULL_CONN_SIZE;
+-		} else
+-			p += SIMPLE_CONN_SIZE;
+-
+ 		atomic_set(&cp->in_pkts, sysctl_ip_vs_sync_threshold[0]);
+ 		cp->state = state;
+-		pp = ip_vs_proto_get(s->protocol);
+-		cp->timeout = pp->timeout_table[cp->state];
++		cp->old_state = cp->state;
++		/*
++		 * We can not recover the right timeout for templates
++		 * in all cases, we can not find the right fwmark
++		 * virtual service. If needed, we can do it for
++		 * non-fwmark persistent services.
++		 */
++		if (!(flags & IP_VS_CONN_F_TEMPLATE) && pp->timeout_table)
++			cp->timeout = pp->timeout_table[state];
++		else
++			cp->timeout = (3*60*HZ);
+ 		ip_vs_conn_put(cp);
+-
+-		if (p > buffer+buflen) {
+-			IP_VS_ERR("bogus message\n");
+-			return;
+-		}
+ 	}
+ }
+ 
+diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
+index 4dc1628..e46d8fa 100644
+--- a/net/ipv4/netfilter/ip_queue.c
++++ b/net/ipv4/netfilter/ip_queue.c
+@@ -296,9 +296,8 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
+ 		if (v->data_len > 0xFFFF)
+ 			return -EINVAL;
+ 		if (diff > skb_tailroom(e->skb)) {
+-			nskb = skb_copy_expand(e->skb, 0,
+-					       diff - skb_tailroom(e->skb),
+-					       GFP_ATOMIC);
++			nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++					       diff, GFP_ATOMIC);
+ 			if (!nskb) {
+ 				printk(KERN_WARNING "ip_queue: error "
+ 				      "in mangle, dropping packet\n");
+diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+index a65b845..50ad6ef 100644
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -305,7 +305,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
+ 	const struct nf_conntrack_tuple_hash *h;
+ 	struct nf_conntrack_tuple tuple;
+ 
+-	NF_CT_TUPLE_U_BLANK(&tuple);
++	memset(&tuple, 0, sizeof(tuple));
+ 	tuple.src.u3.ip = inet->rcv_saddr;
+ 	tuple.src.u.tcp.port = inet->sport;
+ 	tuple.dst.u3.ip = inet->daddr;
+diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
+index 8d366f7..12b4dc5 100644
+--- a/net/ipv6/netfilter/ip6_queue.c
++++ b/net/ipv6/netfilter/ip6_queue.c
+@@ -298,9 +298,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct nf_queue_entry *e)
+ 		if (v->data_len > 0xFFFF)
+ 			return -EINVAL;
+ 		if (diff > skb_tailroom(e->skb)) {
+-			nskb = skb_copy_expand(e->skb, 0,
+-					       diff - skb_tailroom(e->skb),
+-					       GFP_ATOMIC);
++			nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++					       diff, GFP_ATOMIC);
+ 			if (!nskb) {
+ 				printk(KERN_WARNING "ip6_queue: OOM "
+ 				      "in mangle, dropping packet\n");
+diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
+index b77eb56..4147de6 100644
+--- a/net/netfilter/nf_conntrack_core.c
++++ b/net/netfilter/nf_conntrack_core.c
+@@ -104,7 +104,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
+ 		const struct nf_conntrack_l3proto *l3proto,
+ 		const struct nf_conntrack_l4proto *l4proto)
+ {
+-	NF_CT_TUPLE_U_BLANK(tuple);
++	memset(tuple, 0, sizeof(*tuple));
+ 
+ 	tuple->src.l3num = l3num;
+ 	if (l3proto->pkt_to_tuple(skb, nhoff, tuple) == 0)
+@@ -153,7 +153,7 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
+ 		   const struct nf_conntrack_l3proto *l3proto,
+ 		   const struct nf_conntrack_l4proto *l4proto)
+ {
+-	NF_CT_TUPLE_U_BLANK(inverse);
++	memset(inverse, 0, sizeof(*inverse));
+ 
+ 	inverse->src.l3num = orig->src.l3num;
+ 	if (l3proto->invert_tuple(inverse, orig) == 0)
+diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
+index 10522c0..bcaf967 100644
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -454,9 +454,8 @@ nfqnl_mangle(void *data, int data_len, struct nf_queue_entry *e)
+ 		if (data_len > 0xFFFF)
+ 			return -EINVAL;
+ 		if (diff > skb_tailroom(e->skb)) {
+-			nskb = skb_copy_expand(e->skb, 0,
+-					       diff - skb_tailroom(e->skb),
+-					       GFP_ATOMIC);
++			nskb = skb_copy_expand(e->skb, skb_headroom(e->skb),
++					       diff, GFP_ATOMIC);
+ 			if (!nskb) {
+ 				printk(KERN_WARNING "nf_queue: OOM "
+ 				      "in mangle, dropping packet\n");
+diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
+index 66148cc..5bc1ed4 100644
+--- a/net/sched/sch_htb.c
++++ b/net/sched/sch_htb.c
+@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl)
+ 	return 1;
+ }
+ 
+-static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q)
++static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
++			       struct Qdisc *new_q)
+ {
+ 	struct htb_class *parent = cl->parent;
+ 
+ 	BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
+ 
++	if (parent->cmode != HTB_CAN_SEND)
++		htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level);
++
+ 	parent->level = 0;
+ 	memset(&parent->un.inner, 0, sizeof(parent->un.inner));
+ 	INIT_LIST_HEAD(&parent->un.leaf.drop_list);
+@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
+ 		htb_deactivate(q, cl);
+ 
+ 	if (last_child)
+-		htb_parent_to_leaf(cl, new_q);
++		htb_parent_to_leaf(q, cl, new_q);
+ 
+ 	if (--cl->refcnt == 0)
+ 		htb_destroy_class(sch, cl);
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
+index 58f1f93..413885c 100644
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -2093,7 +2093,7 @@ static void xfrm_audit_helper_pktinfo(struct sk_buff *skb, u16 family,
+ 		iph6 = ipv6_hdr(skb);
+ 		audit_log_format(audit_buf,
+ 				 " src=" NIP6_FMT " dst=" NIP6_FMT
+-				 " flowlbl=0x%x%x%x",
++				 " flowlbl=0x%x%02x%02x",
+ 				 NIP6(iph6->saddr),
+ 				 NIP6(iph6->daddr),
+ 				 iph6->flow_lbl[0] & 0x0f,



More information about the Kernel-svn-changes mailing list