From 82f1b07b9ad88066c0fa867dd6b32ce43ae7ad22 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Tue, 13 Sep 2005 08:50:39 -0700 Subject: [PATCH 01/34] [IA64] fix circular dependency on generation of asm-offsets.h Fix? One ugly hack is replaced by a different ugly hack. Signed-off-by: Tony Luck --- arch/ia64/Makefile | 12 +----------- arch/ia64/kernel/asm-offsets.c | 1 + include/asm-ia64/ptrace.h | 2 ++ include/asm-ia64/thread_info.h | 7 +++++++ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 70f8ed2748d1..67932ad53082 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -82,17 +82,7 @@ unwcheck: vmlinux archclean: $(Q)$(MAKE) $(clean)=$(boot) -archprepare: include/asm-ia64/.offsets.h.stamp - -include/asm-ia64/.offsets.h.stamp: - mkdir -p include/asm-ia64 - [ -s include/asm-ia64/asm-offsets.h ] \ - || echo "#define IA64_TASK_SIZE 0" > include/asm-ia64/asm-offsets.h - touch $@ - - - -CLEAN_FILES += vmlinux.gz bootloader include/asm-ia64/.offsets.h.stamp +CLEAN_FILES += vmlinux.gz bootloader boot: lib/lib.a vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index f6a234289341..77225659e968 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c @@ -4,6 +4,7 @@ * to extract and format the required data. */ +#define ASM_OFFSETS_C 1 #include #include diff --git a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h index fc544929ac34..a79d1a7ecc77 100644 --- a/include/asm-ia64/ptrace.h +++ b/include/asm-ia64/ptrace.h @@ -57,7 +57,9 @@ #include #include +#ifndef ASM_OFFSETS_C #include +#endif /* * Base-2 logarithm of number of pages to allocate per task structure diff --git a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h index cf4a950a0f4f..171b2207bde4 100644 --- a/include/asm-ia64/thread_info.h +++ b/include/asm-ia64/thread_info.h @@ -5,7 +5,9 @@ #ifndef _ASM_IA64_THREAD_INFO_H #define _ASM_IA64_THREAD_INFO_H +#ifndef ASM_OFFSETS_C #include +#endif #include #include @@ -51,9 +53,14 @@ struct thread_info { }, \ } +#ifndef ASM_OFFSETS_C /* how to get the thread information struct from C */ #define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE)) #define alloc_thread_info(tsk) ((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE)) +#else +#define current_thread_info() ((struct thread_info *) 0) +#define alloc_thread_info(tsk) ((struct thread_info *) 0) +#endif #define free_thread_info(ti) /* nothing */ #define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR From ad4162f3712ddf25e148cff1e7dc37eafdff3e51 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 14 Sep 2005 09:56:38 +0100 Subject: [PATCH 02/34] [ARM SMP] Add timer/watchdog defines for MPCore The timer/watchdog register definitions were missing from the mpcore watchdog patch. Add them. Signed-off-by: Russell King --- drivers/char/watchdog/mpcore_wdt.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c index c694eee1fb24..75ca84ed4adf 100644 --- a/drivers/char/watchdog/mpcore_wdt.c +++ b/drivers/char/watchdog/mpcore_wdt.c @@ -30,6 +30,8 @@ #include #include #include + +#include #include struct mpcore_wdt { From 39eb936c7ec8ef1dccb88d3bcfc1c5fa2410c472 Mon Sep 17 00:00:00 2001 From: Arnaud Patard Date: Tue, 13 Sep 2005 00:36:45 +0200 Subject: [PATCH 03/34] [PATCH] sata_sis: Fix typo in sata port2 initialisation This patch fixes a nasty typo I introduced in my previous patch (commit f2c853bca542f5ac0b036377637192a74f2091c2). The right offset of the second port in pure sata mode is 64 and not 0x64. Thanks to Martin Schuster for pointing this to me Signed-off-by: Arnaud Patard --- Signed-off-by: Jeff Garzik --- drivers/scsi/sata_sis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index a63f93186e41..237c1986f012 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -289,7 +289,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if (ent->device != 0x182) { if ((pmr & SIS_PMR_COMBINED) == 0) { printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in SATA mode\n"); - port2_start=0x64; + port2_start = 64; } else { printk(KERN_INFO "sata_sis: Detected SiS 180/181 chipset in combined mode\n"); From 668e4bc7229c1866f65f3bef6ab011f8c9034089 Mon Sep 17 00:00:00 2001 From: Uwe Koziolek Date: Sun, 11 Sep 2005 17:03:35 +0200 Subject: [PATCH 04/34] [PATCH] sata_sis: uninitialized variable There is an uninitialized variable issue in sata_sis.c Signed-off-by: Jeff Garzik --- drivers/scsi/sata_sis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 237c1986f012..b227e51d12f4 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -161,7 +161,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); unsigned int cfg_addr = get_scr_cfg_addr(ap->port_no, sc_reg, pdev->device); - u32 val, val2; + u32 val, val2 = 0; u8 pmr; if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */ From 32a3658533c6f4c6bf370dd730213e802464ef9b Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 14 Sep 2005 09:52:42 -0400 Subject: [PATCH 05/34] [PATCH] pci: only call pci_restore_bars at boot Certain (SGI?) ia64 boxes object to having their PCI BARs restored unless absolutely necessary. This patch restricts calling pci_restore_bars from pci_set_power_state unless the current state is PCI_UNKNOWN, the actual (i.e. physical) state of the device is PCI_D3hot, and the device indicates that it will lose its configuration when transitioning to PCI_D0. Signed-off-by: John W. Linville Signed-off-by: Linus Torvalds --- drivers/pci/pci.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 992db89adce7..259d247b7551 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -309,17 +309,25 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) pci_read_config_word(dev, pm + PCI_PM_CTRL, &pmcsr); - /* If we're in D3, force entire word to 0. + /* If we're (effectively) in D3, force entire word to 0. * This doesn't affect PME_Status, disables PME_En, and * sets PowerState to 0. */ - if (dev->current_state >= PCI_D3hot) { - if (!(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) + switch (dev->current_state) { + case PCI_UNKNOWN: /* Boot-up */ + if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot + && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) need_restore = 1; + /* Fall-through: force to D0 */ + case PCI_D3hot: + case PCI_D3cold: + case PCI_POWER_ERROR: pmcsr = 0; - } else { + break; + default: pmcsr &= ~PCI_PM_CTRL_STATE_MASK; pmcsr |= state; + break; } /* enter specified state */ From fb085cf1d4294824571815d487daccc0609543f0 Mon Sep 17 00:00:00 2001 From: Alexander Nyberg Date: Wed, 14 Sep 2005 18:54:06 +0200 Subject: [PATCH 06/34] [PATCH] Fix fs/exec.c:788 (de_thread()) BUG_ON It turns out that the BUG_ON() in fs/exec.c: de_thread() is unreliable and can trigger due to the test itself being racy. de_thread() does while (atomic_read(&sig->count) > count) { } ..... ..... BUG_ON(!thread_group_empty(current)); but release_task does write_lock_irq(&tasklist_lock) __exit_signal (this is where atomic_dec(&sig->count) is run) __exit_sighand __unhash_process takes write lock on tasklist_lock remove itself out of PIDTYPE_TGID list write_unlock_irq(&tasklist_lock) so there's a clear (although small) window between the atomic_dec(&sig->count) and the actual PIDTYPE_TGID unhashing of the thread. And actually there is no need for all threads to have exited at this point, so we simply kill the BUG_ON. Big thanks to Marc Lehmann who provided the test-case. Fixes Bug 5170 (http://bugme.osdl.org/show_bug.cgi?id=5170) Signed-off-by: Alexander Nyberg Cc: Roland McGrath Cc: Andrew Morton Cc: Ingo Molnar Acked-by: Andi Kleen Signed-off-by: Linus Torvalds --- fs/exec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 14dd03907ccb..6fae59a22b43 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -745,8 +745,8 @@ static inline int de_thread(struct task_struct *tsk) } /* - * Now there are really no other threads at all, - * so it's safe to stop telling them to kill themselves. + * There may be one thread left which is just exiting, + * but it's safe to stop telling the group to kill themselves. */ sig->flags = 0; @@ -785,7 +785,6 @@ no_thread_group: kmem_cache_free(sighand_cachep, oldsighand); } - BUG_ON(!thread_group_empty(current)); BUG_ON(!thread_group_leader(current)); return 0; } From 2fd4ef85e0db9ed75c98e13953257a967ea55e03 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 14 Sep 2005 06:13:02 +0100 Subject: [PATCH 07/34] [PATCH] error path in setup_arg_pages() misses vm_unacct_memory() Pavel Emelianov and Kirill Korotaev observe that fs and arch users of security_vm_enough_memory tend to forget to vm_unacct_memory when a failure occurs further down (typically in setup_arg_pages variants). These are all users of insert_vm_struct, and that reservation will only be unaccounted on exit if the vma is marked VM_ACCOUNT: which in some cases it is (hidden inside VM_STACK_FLAGS) and in some cases it isn't. So x86_64 32-bit and ppc64 vDSO ELFs have been leaking memory into Committed_AS each time they're run. But don't add VM_ACCOUNT to them, it's inappropriate to reserve against the very unlikely case that gdb be used to COW a vDSO page - we ought to do something about that in do_wp_page, but there are yet other inconsistencies to be resolved. The safe and economical way to fix this is to let insert_vm_struct do the security_vm_enough_memory check when it finds VM_ACCOUNT is set. And the MIPS irix_brk has been calling security_vm_enough_memory before calling do_brk which repeats it, doubly accounting and so also leaking. Remove that, and all the fs and arch calls to security_vm_enough_memory: give it a less misleading name later on. Signed-off-by: Hugh Dickins Signed-Off-By: Kirill Korotaev Signed-off-by: Linus Torvalds --- arch/ia64/ia32/binfmt_elf32.c | 6 ------ arch/mips/kernel/sysirix.c | 9 ++------- arch/ppc64/kernel/vdso.c | 15 +++++++++------ arch/x86_64/ia32/ia32_binfmt.c | 5 ----- arch/x86_64/ia32/syscall32.c | 6 +----- fs/exec.c | 5 ----- mm/mmap.c | 3 +++ 7 files changed, 15 insertions(+), 34 deletions(-) diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c index 31de70b7c67f..a7280d9f6c16 100644 --- a/arch/ia64/ia32/binfmt_elf32.c +++ b/arch/ia64/ia32/binfmt_elf32.c @@ -216,12 +216,6 @@ ia32_setup_arg_pages (struct linux_binprm *bprm, int executable_stack) if (!mpnt) return -ENOMEM; - if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p)) - >> PAGE_SHIFT)) { - kmem_cache_free(vm_area_cachep, mpnt); - return -ENOMEM; - } - memset(mpnt, 0, sizeof(*mpnt)); down_write(¤t->mm->mmap_sem); diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 4de155699c4f..7ae4af476974 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -581,18 +581,13 @@ asmlinkage int irix_brk(unsigned long brk) } /* - * Check if we have enough memory.. + * Ok, looks good - let it rip. */ - if (security_vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT)) { + if (do_brk(oldbrk, newbrk-oldbrk) != oldbrk) { ret = -ENOMEM; goto out; } - - /* - * Ok, looks good - let it rip. - */ mm->brk = brk; - do_brk(oldbrk, newbrk-oldbrk); ret = 0; out: diff --git a/arch/ppc64/kernel/vdso.c b/arch/ppc64/kernel/vdso.c index 4777676365fe..efa985f05aca 100644 --- a/arch/ppc64/kernel/vdso.c +++ b/arch/ppc64/kernel/vdso.c @@ -224,10 +224,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (vma == NULL) return -ENOMEM; - if (security_vm_enough_memory(vdso_pages)) { - kmem_cache_free(vm_area_cachep, vma); - return -ENOMEM; - } + memset(vma, 0, sizeof(*vma)); /* @@ -237,8 +234,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) */ vdso_base = get_unmapped_area(NULL, vdso_base, vdso_pages << PAGE_SHIFT, 0, 0); - if (vdso_base & ~PAGE_MASK) + if (vdso_base & ~PAGE_MASK) { + kmem_cache_free(vm_area_cachep, vma); return (int)vdso_base; + } current->thread.vdso_base = vdso_base; @@ -266,7 +265,11 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int executable_stack) vma->vm_ops = &vdso_vmops; down_write(&mm->mmap_sem); - insert_vm_struct(mm, vma); + if (insert_vm_struct(mm, vma)) { + up_write(&mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return -ENOMEM; + } mm->total_vm += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; up_write(&mm->mmap_sem); diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c index c8131f342cfc..d9161e395978 100644 --- a/arch/x86_64/ia32/ia32_binfmt.c +++ b/arch/x86_64/ia32/ia32_binfmt.c @@ -353,11 +353,6 @@ int setup_arg_pages(struct linux_binprm *bprm, unsigned long stack_top, int exec mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!mpnt) return -ENOMEM; - - if (security_vm_enough_memory((IA32_STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT)) { - kmem_cache_free(vm_area_cachep, mpnt); - return -ENOMEM; - } memset(mpnt, 0, sizeof(*mpnt)); diff --git a/arch/x86_64/ia32/syscall32.c b/arch/x86_64/ia32/syscall32.c index adbc5f8089e9..3a01329473ab 100644 --- a/arch/x86_64/ia32/syscall32.c +++ b/arch/x86_64/ia32/syscall32.c @@ -52,17 +52,13 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack) vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); if (!vma) return -ENOMEM; - if (security_vm_enough_memory(npages)) { - kmem_cache_free(vm_area_cachep, vma); - return -ENOMEM; - } memset(vma, 0, sizeof(struct vm_area_struct)); /* Could randomize here */ vma->vm_start = VSYSCALL32_BASE; vma->vm_end = VSYSCALL32_END; /* MAYWRITE to allow gdb to COW and set breakpoints */ - vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYEXEC|VM_MAYWRITE; + vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE; vma->vm_flags |= mm->def_flags; vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &syscall32_vm_ops; diff --git a/fs/exec.c b/fs/exec.c index 6fae59a22b43..a04a575ad433 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -421,11 +421,6 @@ int setup_arg_pages(struct linux_binprm *bprm, if (!mpnt) return -ENOMEM; - if (security_vm_enough_memory(arg_size >> PAGE_SHIFT)) { - kmem_cache_free(vm_area_cachep, mpnt); - return -ENOMEM; - } - memset(mpnt, 0, sizeof(*mpnt)); down_write(&mm->mmap_sem); diff --git a/mm/mmap.c b/mm/mmap.c index 12334aecf8ad..8b8e05f07cdb 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1993,6 +1993,9 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) __vma = find_vma_prepare(mm,vma->vm_start,&prev,&rb_link,&rb_parent); if (__vma && __vma->vm_start < vma->vm_end) return -ENOMEM; + if ((vma->vm_flags & VM_ACCOUNT) && + security_vm_enough_memory(vma_pages(vma))) + return -ENOMEM; vma_link(mm, vma, prev, rb_link, rb_parent); return 0; } From c7fb0b35ada6e0e691e70af5591a2006fbec85b5 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Wed, 14 Sep 2005 23:05:30 +0400 Subject: [PATCH 08/34] [PATCH] yenta oops fix In some cases, especially on modern laptops with a lot of PCI and cardbus bridges, we're unable to assign correct secondary/subordinate bus numbers to all cardbus bridges due to BIOS limitations unless we are using "pci=assign-busses" boot option. So some cardbus controllers may not have attached subordinate pci_bus structure, and yenta driver must cope with it - just ignore such cardbus bridges. For example, see https://bugzilla.novell.com/show_bug.cgi?id=113778 Signed-off-by: Ivan Kokshaysky Signed-off-by: Linus Torvalds --- drivers/pcmcia/yenta_socket.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index f0997c36c9b7..2e43911b4876 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1045,7 +1045,18 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i { struct yenta_socket *socket; int ret; - + + /* + * If we failed to assign proper bus numbers for this cardbus + * controller during PCI probe, its subordinate pci_bus is NULL. + * Bail out if so. + */ + if (!dev->subordinate) { + printk(KERN_ERROR "Yenta: no bus associated with %s!\n", + pci_name(dev)); + return -ENODEV; + } + socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); if (!socket) return -ENOMEM; From c7e43c78ae4d8630c418ce3495787b995e61a580 Mon Sep 17 00:00:00 2001 From: Alok Kataria Date: Wed, 14 Sep 2005 12:17:53 -0700 Subject: [PATCH 09/34] [PATCH] Fix slab BUG_ON() triggered by change in array cache size With the new changes that we made in the initialization of the slab allocator, we first setup the cache from which array caches are allocated, and then the cache, from which kmem_list3's are allocated. Now if the array cache comes from a cache in which objsize > 32, (in this instance size-64) then, first size-64 cache will be allocated and then the size-128 (if this is the cache from which kmem_list3's are going to be allocated). So with these new changes, we are not guaranteed that we will be initializing the malloc_sizes array in a serialized order. Thus there is a bug in __find_general_cachep, as we are checking whether the first cache_sizes ptr is NULL. This is replaced by checking whether the array-cache cache is initialized. Attached is a patch which does that. Boots fine on a x86-64, with DEBUG_SPIN, DEBUG_SLAB, and preempt. Attached is a patch which does that. Boots fine on a x86-64, with DEBUG_SPIN, DEBUG_SLAB, and preempt.Thanks & Regards, Alok Signed-off-by: Alok N Kataria Signed-off-by: Shobhit Dayal Cc: Manfred Spraul Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/slab.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/slab.c b/mm/slab.c index 9e876d6dfad9..437d3388054b 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -659,7 +659,7 @@ static inline kmem_cache_t *__find_general_cachep(size_t size, * kmem_cache_create(), or __kmalloc(), before * the generic caches are initialized. */ - BUG_ON(csizep->cs_cachep == NULL); + BUG_ON(malloc_sizes[INDEX_AC].cs_cachep == NULL); #endif while (size > csizep->cs_size) csizep++; From 0b175a7e68c2f51555820efb0a01681e3419c1bc Mon Sep 17 00:00:00 2001 From: Dipankar Sarma Date: Thu, 15 Sep 2005 00:48:42 +0530 Subject: [PATCH 10/34] [PATCH] Fix the fdtable freeing in the case of vmalloced fdset/arrays Noted by David Miller: "The bug is that free_fd_array() takes a "num" argument, but when calling it from __free_fdtable() we're instead passing in the size in bytes (ie. "num * sizeof(struct file *)")." Yes it is a bug. I think I messed it up while merging newer changes with an older version where I was using size in bytes to optimize. Signed-off-by: Dipankar Sarma Signed-off-by: Linus Torvalds --- fs/file.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/file.c b/fs/file.c index 2127a7b9dc3a..fd066b261c75 100644 --- a/fs/file.c +++ b/fs/file.c @@ -69,13 +69,9 @@ void free_fd_array(struct file **array, int num) static void __free_fdtable(struct fdtable *fdt) { - int fdset_size, fdarray_size; - - fdset_size = fdt->max_fdset / 8; - fdarray_size = fdt->max_fds * sizeof(struct file *); - free_fdset(fdt->open_fds, fdset_size); - free_fdset(fdt->close_on_exec, fdset_size); - free_fd_array(fdt->fd, fdarray_size); + free_fdset(fdt->open_fds, fdt->max_fdset); + free_fdset(fdt->close_on_exec, fdt->max_fdset); + free_fd_array(fdt->fd, fdt->max_fds); kfree(fdt); } From 5a23f34798f15838fe1b7f0fd7e5be388e08c2b2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 14 Sep 2005 13:05:17 -0700 Subject: [PATCH 11/34] Fix yenta error message when unable to find a bus assignment And mention 'pci=assign-busses' as a possible fix. Signed-off-by: Linus Torvalds --- drivers/pcmcia/yenta_socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 2e43911b4876..ba4d78e5b121 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1052,8 +1052,8 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i * Bail out if so. */ if (!dev->subordinate) { - printk(KERN_ERROR "Yenta: no bus associated with %s!\n", - pci_name(dev)); + printk(KERN_ERR "Yenta: no bus associated with %s! " + "(try 'pci=assign-busses')\n", pci_name(dev)); return -ENODEV; } From 84d370b906b0eb00277a841216987285cf4114d4 Mon Sep 17 00:00:00 2001 From: Karsten Keil Date: Wed, 14 Sep 2005 14:19:13 -0700 Subject: [PATCH 12/34] [PATCH] i4l: Sedlbauer speed star II V 3.1 exist with various subversions the 4th id field should be not used Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/sedlbauer_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index c6b5bf7d2aca..dc334aab433e 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -611,7 +611,7 @@ static int sedlbauer_event(event_t event, int priority, } /* sedlbauer_event */ static struct pcmcia_device_id sedlbauer_ids[] = { - PCMCIA_DEVICE_PROD_ID1234("SEDLBAUER", "speed star II", "V 3.1", "(c) 93 - 98 cb ", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a, 0x50d4149c), + PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90), PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce), PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", " (C) 93-94 VK", 0x81fb79f5, 0xe4e9bc12, 0x8db143fe), From 8fd9808aec0198b25ff9f8bb19508d9492f86920 Mon Sep 17 00:00:00 2001 From: Pantelis Antoniou Date: Wed, 14 Sep 2005 14:19:14 -0700 Subject: [PATCH 13/34] [PATCH] ppc32 8xx: flush_tlb_range() declaration uses wrong pointer type On 8xx flush_tlb_range() declaration is using a "struct mm_struct *" pointer type while the function itself uses "struct vm_area_struct *". Signed-off-by: Marcelo Tosatti Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc/tlbflush.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h index 9850f53f54b0..9afee4ffc835 100644 --- a/include/asm-ppc/tlbflush.h +++ b/include/asm-ppc/tlbflush.h @@ -72,7 +72,7 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, static inline void flush_tlb_page_nohash(struct vm_area_struct *vma, unsigned long vmaddr) { _tlbie(vmaddr); } -static inline void flush_tlb_range(struct mm_struct *mm, +static inline void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) { __tlbia(); } static inline void flush_tlb_kernel_range(unsigned long start, From 0ed8e048c9e11e69ec951f94066105e80cdc59fd Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Wed, 14 Sep 2005 14:19:15 -0700 Subject: [PATCH 14/34] [PATCH] nv_i2c oops fix The call to fb_firmware_edid may return NULL but this is not checked before trying to memcpy using this pointer. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/nvidia/nv_i2c.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c index ace484fa61ce..12f2884d3f0b 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/nvidia/nv_i2c.c @@ -209,10 +209,13 @@ int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) if (!edid && conn == 1) { /* try to get from firmware */ - edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (edid) - memcpy(edid, fb_firmware_edid(info->device), - EDID_LENGTH); + const u8 *e = fb_firmware_edid(info->device); + + if (e != NULL) { + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); + } } if (out_edid) From 8b7fc4214b550fafe595330e28d7c2c72b8b62f6 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 14 Sep 2005 14:19:17 -0700 Subject: [PATCH 15/34] [PATCH] add PCI IDs so RME32 and RME96 drivers build While doing an allyesconfig build, I noticed that the commit commit 8cdfd2519c6c9a1e6057dc5970b2542b35895738 Author: Takashi Iwai Date: Wed Sep 7 14:08:11 2005 +0200 [ALSA] Remove superfluous PCI ID definitions broke the RME32 and RME96 drivers, since the PCI IDs they use seem to have changed names. Here's a patch to fix this -- compile tested only, since I have no idea what the hardware even is. Fix the build of the RME32 and RME96 drivers by having them use the PCI_DEVICE_ID_RME_xxx names defined in instead of the PCI_DEVICE_ID_xxx names that they used to define themselves. Also fix the typo in the id PCI_DEVICE_IDRME__DIGI96_8_PAD_OR_PST so the name is PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST. Signed-off-by: Roland Dreier Acked-by: Takashi Iwai Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 2 +- sound/pci/rme32.c | 44 +++++++++++++++--------------- sound/pci/rme96.c | 60 ++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f6c1a142286a..72fe3385743c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1355,7 +1355,7 @@ #define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 #define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1 #define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2 -#define PCI_DEVICE_IDRME__DIGI96_8_PAD_OR_PST 0x3fc3 +#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3 #define PCI_DEVICE_ID_XILINX_HAMMERFALL 0x3fc4 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 #define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 3daeecb9eb0e..cd313af6ebcf 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -228,11 +228,11 @@ typedef struct snd_rme32 { } rme32_t; static struct pci_device_id snd_rme32_ids[] = { - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_8, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, - {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_DIGI32_PRO, + {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, {0,} }; @@ -240,7 +240,7 @@ static struct pci_device_id snd_rme32_ids[] = { MODULE_DEVICE_TABLE(pci, snd_rme32_ids); #define RME32_ISWORKING(rme32) ((rme32)->wcreg & RME32_WCR_START) -#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414) +#define RME32_PRO_WITH_8414(rme32) ((rme32)->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO && (rme32)->rev == RME32_PRO_REVISION_WITH_8414) static int snd_rme32_playback_prepare(snd_pcm_substream_t * substream); @@ -527,21 +527,21 @@ static int snd_rme32_playback_setrate(rme32_t * rme32, int rate) RME32_WCR_FREQ_1; break; case 64000: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) & ~RME32_WCR_FREQ_1; break; case 88200: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_1) & ~RME32_WCR_FREQ_0; break; case 96000: - if (rme32->pci->device != PCI_DEVICE_ID_DIGI32_PRO) + if (rme32->pci->device != PCI_DEVICE_ID_RME_DIGI32_PRO) return -EINVAL; rme32->wcreg |= RME32_WCR_DS_BM; rme32->wcreg = (rme32->wcreg | RME32_WCR_FREQ_0) | @@ -881,7 +881,7 @@ static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream) runtime->hw = snd_rme32_spdif_fd_info; else runtime->hw = snd_rme32_spdif_info; - if (rme32->pci->device == PCI_DEVICE_ID_DIGI32_PRO) { + if (rme32->pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO) { runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000; runtime->hw.rate_max = 96000; } @@ -1408,8 +1408,8 @@ static int __devinit snd_rme32_create(rme32_t * rme32) } /* set up ALSA pcm device for ADAT */ - if ((pci->device == PCI_DEVICE_ID_DIGI32) || - (pci->device == PCI_DEVICE_ID_DIGI32_PRO)) { + if ((pci->device == PCI_DEVICE_ID_RME_DIGI32) || + (pci->device == PCI_DEVICE_ID_RME_DIGI32_PRO)) { /* ADAT is not available on DIGI32 and DIGI32 Pro */ rme32->adat_pcm = NULL; } @@ -1639,11 +1639,11 @@ snd_rme32_info_inputtype_control(snd_kcontrol_t * kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: uinfo->value.enumerated.items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: uinfo->value.enumerated.items = 4; break; default: @@ -1670,11 +1670,11 @@ snd_rme32_get_inputtype_control(snd_kcontrol_t * kcontrol, ucontrol->value.enumerated.item[0] = snd_rme32_getinputtype(rme32); switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: items = 4; break; default: @@ -1697,11 +1697,11 @@ snd_rme32_put_inputtype_control(snd_kcontrol_t * kcontrol, int change, items = 3; switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32_8: items = 3; break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: items = 4; break; default: @@ -1982,13 +1982,13 @@ snd_rme32_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) strcpy(card->driver, "Digi32"); switch (rme32->pci->device) { - case PCI_DEVICE_ID_DIGI32: + case PCI_DEVICE_ID_RME_DIGI32: strcpy(card->shortname, "RME Digi32"); break; - case PCI_DEVICE_ID_DIGI32_8: + case PCI_DEVICE_ID_RME_DIGI32_8: strcpy(card->shortname, "RME Digi32/8"); break; - case PCI_DEVICE_ID_DIGI32_PRO: + case PCI_DEVICE_ID_RME_DIGI32_PRO: strcpy(card->shortname, "RME Digi32 PRO"); break; } diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 9983b66dc564..c495cae78dbf 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -233,13 +233,13 @@ typedef struct snd_rme96 { } rme96_t; static struct pci_device_id snd_rme96_ids[] = { - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PRO, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, - { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST, + { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, { 0, } }; @@ -248,12 +248,12 @@ MODULE_DEVICE_TABLE(pci, snd_rme96_ids); #define RME96_ISPLAYING(rme96) ((rme96)->wcreg & RME96_WCR_START) #define RME96_ISRECORDING(rme96) ((rme96)->wcreg & RME96_WCR_START_2) -#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST) -#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO || \ - (rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST) +#define RME96_HAS_ANALOG_IN(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST) +#define RME96_HAS_ANALOG_OUT(rme96) ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO || \ + (rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST) #define RME96_DAC_IS_1852(rme96) (RME96_HAS_ANALOG_OUT(rme96) && (rme96)->rev >= 4) -#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \ - ((rme96)->pci->device == PCI_DEVICE_ID_DIGI96_8_PRO && (rme96)->rev == 2)) +#define RME96_DAC_IS_1855(rme96) (((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && (rme96)->rev < 4) || \ + ((rme96)->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PRO && (rme96)->rev == 2)) #define RME96_185X_MAX_OUT(rme96) ((1 << (RME96_DAC_IS_1852(rme96) ? RME96_AD1852_VOL_BITS : RME96_AD1855_VOL_BITS)) - 1) static int @@ -830,9 +830,9 @@ snd_rme96_setinputtype(rme96_t *rme96, RME96_WCR_INP_1; break; case RME96_INPUT_XLR: - if ((rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && - rme96->pci->device != PCI_DEVICE_ID_DIGI96_8_PRO) || - (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && + if ((rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && + rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PRO) || + (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4)) { /* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */ @@ -1598,7 +1598,7 @@ snd_rme96_create(rme96_t *rme96) rme96->spdif_pcm->info_flags = 0; /* set up ALSA pcm device for ADAT */ - if (pci->device == PCI_DEVICE_ID_DIGI96) { + if (pci->device == PCI_DEVICE_ID_RME_DIGI96) { /* ADAT is not available on the base model */ rme96->adat_pcm = NULL; } else { @@ -1858,14 +1858,14 @@ snd_rme96_info_inputtype_control(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: uinfo->value.enumerated.items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: uinfo->value.enumerated.items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { /* PST */ uinfo->value.enumerated.items = 4; @@ -1895,14 +1895,14 @@ snd_rme96_get_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96); switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { /* for handling PST case, (INPUT_ANALOG is moved to INPUT_XLR */ if (ucontrol->value.enumerated.item[0] == RME96_INPUT_ANALOG) { @@ -1932,14 +1932,14 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t int change, items = 3; switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96_8: items = 3; break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: items = 4; break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: if (rme96->rev > 4) { items = 4; } else { @@ -1953,7 +1953,7 @@ snd_rme96_put_inputtype_control(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t val = ucontrol->value.enumerated.item[0] % items; /* special case for PST */ - if (rme96->pci->device == PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST && rme96->rev > 4) { + if (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4) { if (val == RME96_INPUT_XLR) { val = RME96_INPUT_ANALOG; } @@ -2375,16 +2375,16 @@ snd_rme96_probe(struct pci_dev *pci, strcpy(card->driver, "Digi96"); switch (rme96->pci->device) { - case PCI_DEVICE_ID_DIGI96: + case PCI_DEVICE_ID_RME_DIGI96: strcpy(card->shortname, "RME Digi96"); break; - case PCI_DEVICE_ID_DIGI96_8: + case PCI_DEVICE_ID_RME_DIGI96_8: strcpy(card->shortname, "RME Digi96/8"); break; - case PCI_DEVICE_ID_DIGI96_8_PRO: + case PCI_DEVICE_ID_RME_DIGI96_8_PRO: strcpy(card->shortname, "RME Digi96/8 PRO"); break; - case PCI_DEVICE_ID_DIGI96_8_PAD_OR_PST: + case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: pci_read_config_byte(rme96->pci, 8, &val); if (val < 5) { strcpy(card->shortname, "RME Digi96/8 PAD"); From ef4cbee0b0d0f791bb593f99b702410f3c0efce6 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 14 Sep 2005 14:19:18 -0700 Subject: [PATCH 16/34] [PATCH] hvc_console: start kernel thread before registering tty Its possible that we can write to the hvc_console tty as soon it is registered. Recently this started happening due to (what looks like) a change to the hotplug code. Unfortunately at this stage we have not started the khvcd kernel thread and oops. The solution is to start the kernel thread before registering the tty. Signed-off-by: Anton Blanchard Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/hvc_console.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index cddb789902db..f92177634677 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -839,9 +839,6 @@ int __init hvc_init(void) hvc_driver->flags = TTY_DRIVER_REAL_RAW; tty_set_operations(hvc_driver, &hvc_ops); - if (tty_register_driver(hvc_driver)) - panic("Couldn't register hvc console driver\n"); - /* Always start the kthread because there can be hotplug vty adapters * added later. */ hvc_task = kthread_run(khvcd, NULL, "khvcd"); @@ -851,6 +848,9 @@ int __init hvc_init(void) return -EIO; } + if (tty_register_driver(hvc_driver)) + panic("Couldn't register hvc console driver\n"); + return 0; } module_init(hvc_init); From 2d93486c6c110cf81db720359b4ec20de9c91450 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 14 Sep 2005 22:36:03 +0100 Subject: [PATCH 17/34] [ARM] 2907/1: GCC 4 serial driver compile fixes Patch from Vincent Sanders When building the ARM platforms several serial drivers fail to compile with GCC 4.01 due to extern/static ambiguity. Signed-off-by: Vincent Sanders Signed-off-by: Russell King --- drivers/serial/21285.c | 2 +- drivers/serial/amba-pl010.c | 2 +- drivers/serial/amba-pl011.c | 2 +- drivers/serial/clps711x.c | 2 +- drivers/serial/pxa.c | 4 ++-- drivers/serial/sa1100.c | 2 +- drivers/serial/serial_lh7a40x.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index aec39fb261ca..b5cf39468d18 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c @@ -463,7 +463,7 @@ static int __init serial21285_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -extern struct uart_driver serial21285_reg; +static struct uart_driver serial21285_reg; static struct console serial21285_console = { diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 978e12437e61..679e678c7e6a 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c @@ -689,7 +689,7 @@ static int __init pl010_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -extern struct uart_driver amba_reg; +static struct uart_driver amba_reg; static struct console amba_console = { .name = "ttyAM", .write = pl010_console_write, diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index 56071309744c..1ff629c74750 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c @@ -701,7 +701,7 @@ static int __init pl011_console_setup(struct console *co, char *options) return uart_set_options(&uap->port, co, baud, parity, bits, flow); } -extern struct uart_driver amba_reg; +static struct uart_driver amba_reg; static struct console amba_console = { .name = "ttyAMA", .write = pl011_console_write, diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index d822896b488c..78c1f36ad9b7 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c @@ -525,7 +525,7 @@ static int __init clps711xuart_console_setup(struct console *co, char *options) return uart_set_options(port, co, baud, parity, bits, flow); } -extern struct uart_driver clps711x_reg; +static struct uart_driver clps711x_reg; static struct console clps711x_console = { .name = "ttyCL", .write = clps711xuart_console_write, diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index eaa0af835290..672b359b07ce 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -589,8 +589,8 @@ serial_pxa_type(struct uart_port *port) #ifdef CONFIG_SERIAL_PXA_CONSOLE -extern struct uart_pxa_port serial_pxa_ports[]; -extern struct uart_driver serial_pxa_reg; +static struct uart_pxa_port serial_pxa_ports[]; +static struct uart_driver serial_pxa_reg; #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 1225b14f6e9d..dd8aed242357 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c @@ -799,7 +799,7 @@ sa1100_console_setup(struct console *co, char *options) return uart_set_options(&sport->port, co, baud, parity, bits, flow); } -extern struct uart_driver sa1100_reg; +static struct uart_driver sa1100_reg; static struct console sa1100_console = { .name = "ttySA", .write = sa1100_console_write, diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index 8302376800c0..d01dbe5da3b9 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c @@ -632,7 +632,7 @@ static int __init lh7a40xuart_console_setup (struct console* co, char* options) return uart_set_options (port, co, baud, parity, bits, flow); } -extern struct uart_driver lh7a40x_reg; +static struct uart_driver lh7a40x_reg; static struct console lh7a40x_console = { .name = "ttyAM", .write = lh7a40xuart_console_write, From 2cef2d552f75b7feb7859d29a71388c020023872 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 14 Sep 2005 22:42:31 +0100 Subject: [PATCH 18/34] [ARM] 2910/1: missing Lubbock audio device declaration Patch from Nicolas Pitre This apparently fell in the crack somewhere. Add it back. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/mach-pxa/lubbock.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index 923f6eb774c0..1f38033921e9 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -146,6 +146,11 @@ static struct pxa2xx_udc_mach_info udc_info __initdata = { // no D+ pullup; lubbock can't connect/disconnect in software }; +static struct platform_device lub_audio_device = { + .name = "pxa2xx-ac97", + .id = -1, +}; + static struct resource sa1111_resources[] = { [0] = { .start = 0x10000000, @@ -195,6 +200,7 @@ static struct platform_device smc91x_device = { static struct platform_device *devices[] __initdata = { &sa1111_device, + &lub_audio_device, &smc91x_device, }; From da16e3245a4827d969943ca0493a4a6e34009342 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 14 Sep 2005 22:54:45 +0100 Subject: [PATCH 19/34] [I2C] Add a functionality method, and remove algorithm ids This allows i2c-pxa to finally build. Signed-off-by: Russell King --- drivers/i2c/busses/i2c-pxa.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index fdf53ce04248..44b595d90a4a 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c @@ -914,19 +914,23 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num return ret; } +static u32 i2c_pxa_functionality(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + static struct i2c_algorithm i2c_pxa_algorithm = { - .name = "PXA-I2C-Algorithm", - .id = I2C_ALGO_PXA, .master_xfer = i2c_pxa_xfer, + .functionality = i2c_pxa_functionality, }; static struct pxa_i2c i2c_pxa = { .lock = SPIN_LOCK_UNLOCKED, .wait = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait), .adap = { - .name = "pxa2xx-i2c", - .id = I2C_ALGO_PXA, + .owner = THIS_MODULE, .algo = &i2c_pxa_algorithm, + .name = "pxa2xx-i2c", .retries = 5, }, }; From f6af5da388a5d058cd9a5a47d030e3966b22e991 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 14 Sep 2005 23:10:48 +0100 Subject: [PATCH 20/34] [ARM SMP] Add timer/watchdog defines for MPCore Actually add the file this time. Signed-off-by: Russell King --- include/asm-arm/hardware/arm_twd.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/asm-arm/hardware/arm_twd.h diff --git a/include/asm-arm/hardware/arm_twd.h b/include/asm-arm/hardware/arm_twd.h new file mode 100644 index 000000000000..131d5b40e072 --- /dev/null +++ b/include/asm-arm/hardware/arm_twd.h @@ -0,0 +1,16 @@ +#ifndef __ASM_HARDWARE_TWD_H +#define __ASM_HARDWARE_TWD_H + +#define TWD_TIMER_LOAD 0x00 +#define TWD_TIMER_COUNTER 0x04 +#define TWD_TIMER_CONTROL 0x08 +#define TWD_TIMER_INTSTAT 0x0C + +#define TWD_WDOG_LOAD 0x20 +#define TWD_WDOG_COUNTER 0x24 +#define TWD_WDOG_CONTROL 0x28 +#define TWD_WDOG_INTSTAT 0x2C +#define TWD_WDOG_RESETSTAT 0x30 +#define TWD_WDOG_DISABLE 0x34 + +#endif From 1619cca2921f6927f4240e03f413d4165c7002fc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 14 Sep 2005 15:56:27 -0700 Subject: [PATCH 21/34] Partially revert "Fix time going twice as fast problem on ATI Xpress chipsets" Commit 66759a01adbfe8828dd063e32cf5ed3f46696181 introduced the fix for time ticking too fast on some boards by disabling one of the doubly connected timer pins on ATI boards. However, it ends up being _much_ too broad a brush, and that just makes some other ATI boards not work at all since they now have no timer source. So disable the automatic ATI southbridge detection, and just rely on people who see this problem disabling it by hand with the option "disable_timer_pin_1" on the kernel command line. Maybe somebody can figure out the proper tests at a later date. Acked-by: Peter Osterlund Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/earlyquirk.c | 10 ---------- arch/x86_64/kernel/io_apic.c | 9 --------- 2 files changed, 19 deletions(-) diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 1ae2aeeda18b..f1b9d2a46dab 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -7,7 +7,6 @@ #include #include #include -#include static int __init check_bridge(int vendor, int device) { @@ -16,15 +15,6 @@ static int __init check_bridge(int vendor, int device) if (vendor == PCI_VENDOR_ID_NVIDIA) { acpi_skip_timer_override = 1; } -#ifdef CONFIG_X86_LOCAL_APIC - /* - * ATI IXP chipsets get double timer interrupts. - * For now just do this for all ATI chipsets. - * FIXME: this needs to be checked for the non ACPI case too. - */ - if (vendor == PCI_VENDOR_ID_ATI) - disable_timer_pin_1 = 1; -#endif return 0; } diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 522944a000ad..c8eee20cd519 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -299,15 +299,6 @@ void __init check_ioapic(void) #endif /* RED-PEN skip them on mptables too? */ return; - case PCI_VENDOR_ID_ATI: - /* All timer interrupts on atiixp - are doubled. Disable one. */ - if (disable_timer_pin_1 == 0) { - disable_timer_pin_1 = 1; - printk(KERN_INFO - "ATI board detected. Disabling timer pin 1.\n"); - } - return; } /* No multi-function device? */ From 3c05d92ed49f644d1f5a960fa48637d63b946016 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 14 Sep 2005 20:50:35 -0700 Subject: [PATCH 22/34] [TCP]: Compute in_sacked properly when we split up a TSO frame. The problem is that the SACK fragmenting code may incorrectly call tcp_fragment() with a length larger than the skb->len. This happens when the skb on the transmit queue completely falls to the LHS of the SACK. And add a BUG() check to tcp_fragment() so we can spot this kind of error more quickly in the future. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 16 +++++++++------- net/ipv4/tcp_output.c | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 29222b964951..a7537c7bbd06 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -979,14 +979,19 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (!before(TCP_SKB_CB(skb)->seq, end_seq)) break; + in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && + !before(end_seq, TCP_SKB_CB(skb)->end_seq); + pcount = tcp_skb_pcount(skb); - if (pcount > 1 && - (after(start_seq, TCP_SKB_CB(skb)->seq) || - before(end_seq, TCP_SKB_CB(skb)->end_seq))) { + if (pcount > 1 && !in_sack && + after(TCP_SKB_CB(skb)->end_seq, start_seq)) { unsigned int pkt_len; - if (after(start_seq, TCP_SKB_CB(skb)->seq)) + in_sack = !after(start_seq, + TCP_SKB_CB(skb)->seq); + + if (!in_sack) pkt_len = (start_seq - TCP_SKB_CB(skb)->seq); else @@ -999,9 +1004,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ fack_count += pcount; - in_sack = !after(start_seq, TCP_SKB_CB(skb)->seq) && - !before(end_seq, TCP_SKB_CB(skb)->end_seq); - sacked = TCP_SKB_CB(skb)->sacked; /* Account D-SACK for retransmitted packet. */ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c10e4435e3b1..b018e31b6530 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -435,6 +435,8 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss int nsize, old_factor; u16 flags; + BUG_ON(len >= skb->len); + nsize = skb_headlen(skb) - len; if (nsize < 0) nsize = 0; From 20ae975dfd54de581287b2ca8a1ad97099ab0396 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Sep 2005 20:52:37 -0700 Subject: [PATCH 23/34] [NETLINK]: Reserve a slot for NETLINK_GENERIC. As requested by Jamal. Signed-off-by: David S. Miller --- include/linux/netlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 7bbd25970c9e..bdebdc564506 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -20,6 +20,7 @@ #define NETLINK_IP6_FW 13 #define NETLINK_DNRTMSG 14 /* DECnet routing messages */ #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ +#define NETLINK_GENERIC 16 #define MAX_LINKS 32 From de9daad90ecb54f3c37c3f8967d581e20d927539 Mon Sep 17 00:00:00 2001 From: Denis Lukianov Date: Wed, 14 Sep 2005 20:53:42 -0700 Subject: [PATCH 24/34] [MCAST]: Fix MCAST_EXCLUDE line dupes This patch fixes line dupes at /ipv4/igmp.c and /ipv6/mcast.c in the 2.6 kernel, where MCAST_EXCLUDE is mistakenly used instead of MCAST_INCLUDE. Signed-off-by: Denis Lukianov Signed-off-by: David L Stevens Signed-off-by: David S. Miller --- net/ipv4/igmp.c | 2 +- net/ipv6/mcast.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 44607f4767b8..70c44e4c3ceb 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1603,7 +1603,7 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc) } pmc->sources = NULL; pmc->sfmode = MCAST_EXCLUDE; - pmc->sfcount[MCAST_EXCLUDE] = 0; + pmc->sfcount[MCAST_INCLUDE] = 0; pmc->sfcount[MCAST_EXCLUDE] = 1; } diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 29fed6e58d0a..519899fb11d5 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -1968,7 +1968,7 @@ static void ip6_mc_clear_src(struct ifmcaddr6 *pmc) } pmc->mca_sources = NULL; pmc->mca_sfmode = MCAST_EXCLUDE; - pmc->mca_sfcount[MCAST_EXCLUDE] = 0; + pmc->mca_sfcount[MCAST_INCLUDE] = 0; pmc->mca_sfcount[MCAST_EXCLUDE] = 1; } From 1c011bed5f49ce9e6193b18b226106a41ecfa95c Mon Sep 17 00:00:00 2001 From: Bart De Schuymer Date: Wed, 14 Sep 2005 20:55:16 -0700 Subject: [PATCH 25/34] [BRIDGE-NF]: Fix iptables redirect on bridge interface Here's a slightly altered patch, originally from Mark Glines who diagnosed and fixed the problem. Signed-off-by: Bart De Schuymer Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 2d52fee63a8c..d8e36b775125 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -214,9 +214,11 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) .tos = RT_TOS(iph->tos)} }, .proto = 0}; if (!ip_route_output_key(&rt, &fl)) { - /* Bridged-and-DNAT'ed traffic doesn't - * require ip_forwarding. */ - if (((struct dst_entry *)rt)->dev == dev) { + /* - Bridged-and-DNAT'ed traffic doesn't + * require ip_forwarding. + * - Deal with redirected traffic. */ + if (((struct dst_entry *)rt)->dev == dev || + rt->rt_type == RTN_LOCAL) { skb->dst = (struct dst_entry *)rt; goto bridged_dnat; } From f5e229db9cdb27f83594712ca4bb98d9377eb6ed Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Wed, 14 Sep 2005 21:04:23 -0700 Subject: [PATCH 26/34] [IPVS]: Really invalidate persistent templates Agostino di Salle noticed that persistent templates are not invalidated due to buggy optimization. Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- net/ipv4/ipvs/ip_vs_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index e11952ea17af..5994521fddc5 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -467,7 +467,7 @@ int ip_vs_check_template(struct ip_vs_conn *ct) /* * Invalidate the connection template */ - if (ct->cport) { + if (ct->vport != 65535) { if (ip_vs_conn_unhash(ct)) { ct->dport = 65535; ct->vport = 65535; From 87375ab47cd0ba04124c6d3fd80db5c368f5dcb6 Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Wed, 14 Sep 2005 21:08:51 -0700 Subject: [PATCH 27/34] [IPVS]: ip_vs_ftp breaks connections using persistence ip_vs_ftp when loaded can create NAT connections with unknown client port for passive FTP. For such expectations we lookup with cport=0 on incoming packet but it matches the format of the persistence templates causing packets to other persistent virtual servers to be forwarded to real server without creating connection. Later the reply packets are treated as foreign and not SNAT-ed. This patch changes the connection lookup for packets from clients: * introduce IP_VS_CONN_F_TEMPLATE connection flag to mark the connection as template * create new connection lookup function just for templates - ip_vs_ct_in_get * make sure ip_vs_conn_in_get hits only connections with IP_VS_CONN_F_NO_CPORT flag set when s_port is 0. By this way we avoid returning template when looking for cport=0 (ftp) Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- include/net/ip_vs.h | 3 +++ net/ipv4/ipvs/ip_vs_conn.c | 41 +++++++++++++++++++++++++++++++++++--- net/ipv4/ipvs/ip_vs_core.c | 16 +++++++-------- net/ipv4/ipvs/ip_vs_sync.c | 20 +++++++++++++------ 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index e426641c519f..06b4235aa016 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -84,6 +84,7 @@ #define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */ #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ +#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ /* Move it to better place one day, for now keep it unique */ #define NFC_IPVS_PROPERTY 0x10000 @@ -739,6 +740,8 @@ enum { extern struct ip_vs_conn *ip_vs_conn_in_get (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); +extern struct ip_vs_conn *ip_vs_ct_in_get +(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); extern struct ip_vs_conn *ip_vs_conn_out_get (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port); diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index 5994521fddc5..f828fa2eb7de 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -196,6 +196,7 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { if (s_addr==cp->caddr && s_port==cp->cport && d_port==cp->vport && d_addr==cp->vaddr && + ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && protocol==cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); @@ -227,6 +228,40 @@ struct ip_vs_conn *ip_vs_conn_in_get return cp; } +/* Get reference to connection template */ +struct ip_vs_conn *ip_vs_ct_in_get +(int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) +{ + unsigned hash; + struct ip_vs_conn *cp; + + hash = ip_vs_conn_hashkey(protocol, s_addr, s_port); + + ct_read_lock(hash); + + list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { + if (s_addr==cp->caddr && s_port==cp->cport && + d_port==cp->vport && d_addr==cp->vaddr && + cp->flags & IP_VS_CONN_F_TEMPLATE && + protocol==cp->protocol) { + /* HIT */ + atomic_inc(&cp->refcnt); + goto out; + } + } + cp = NULL; + + out: + ct_read_unlock(hash); + + IP_VS_DBG(7, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", + ip_vs_proto_name(protocol), + NIPQUAD(s_addr), ntohs(s_port), + NIPQUAD(d_addr), ntohs(d_port), + cp?"hit":"not hit"); + + return cp; +} /* * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. @@ -367,7 +402,7 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) atomic_read(&dest->refcnt)); /* Update the connection counters */ - if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) { + if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { /* It is a normal connection, so increase the inactive connection counter because it is in TCP SYNRECV state (inactive) or other protocol inacive state */ @@ -406,7 +441,7 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp) atomic_read(&dest->refcnt)); /* Update the connection counters */ - if (cp->cport || (cp->flags & IP_VS_CONN_F_NO_CPORT)) { + if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { /* It is a normal connection, so decrease the inactconns or activeconns counter */ if (cp->flags & IP_VS_CONN_F_INACTIVE) { @@ -776,7 +811,7 @@ void ip_vs_random_dropentry(void) ct_write_lock_bh(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (!cp->cport && !(cp->flags & IP_VS_CONN_F_NO_CPORT)) + if (cp->flags & IP_VS_CONN_F_TEMPLATE) /* connection template */ continue; diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 3ac7eeca04ac..981cc3244ef2 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c @@ -243,10 +243,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc, if (ports[1] == svc->port) { /* Check if a template already exists */ if (svc->port != FTPPORT) - ct = ip_vs_conn_in_get(iph->protocol, snet, 0, + ct = ip_vs_ct_in_get(iph->protocol, snet, 0, iph->daddr, ports[1]); else - ct = ip_vs_conn_in_get(iph->protocol, snet, 0, + ct = ip_vs_ct_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (!ct || !ip_vs_check_template(ct)) { @@ -272,14 +272,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, iph->daddr, ports[1], dest->addr, dest->port, - 0, + IP_VS_CONN_F_TEMPLATE, dest); else ct = ip_vs_conn_new(iph->protocol, snet, 0, iph->daddr, 0, dest->addr, 0, - 0, + IP_VS_CONN_F_TEMPLATE, dest); if (ct == NULL) return NULL; @@ -298,10 +298,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * port zero template: */ if (svc->fwmark) - ct = ip_vs_conn_in_get(IPPROTO_IP, snet, 0, + ct = ip_vs_ct_in_get(IPPROTO_IP, snet, 0, htonl(svc->fwmark), 0); else - ct = ip_vs_conn_in_get(iph->protocol, snet, 0, + ct = ip_vs_ct_in_get(iph->protocol, snet, 0, iph->daddr, 0); if (!ct || !ip_vs_check_template(ct)) { @@ -326,14 +326,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, snet, 0, htonl(svc->fwmark), 0, dest->addr, 0, - 0, + IP_VS_CONN_F_TEMPLATE, dest); else ct = ip_vs_conn_new(iph->protocol, snet, 0, iph->daddr, 0, dest->addr, 0, - 0, + IP_VS_CONN_F_TEMPLATE, dest); if (ct == NULL) return NULL; diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c index 574d1f509b46..2e5ced3d8062 100644 --- a/net/ipv4/ipvs/ip_vs_sync.c +++ b/net/ipv4/ipvs/ip_vs_sync.c @@ -297,16 +297,24 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) p = (char *)buffer + sizeof(struct ip_vs_sync_mesg); for (i=0; inr_conns; i++) { + unsigned flags; + s = (struct ip_vs_sync_conn *)p; - cp = ip_vs_conn_in_get(s->protocol, - s->caddr, s->cport, - s->vaddr, s->vport); + flags = ntohs(s->flags); + if (!(flags & IP_VS_CONN_F_TEMPLATE)) + cp = ip_vs_conn_in_get(s->protocol, + s->caddr, s->cport, + s->vaddr, s->vport); + else + cp = ip_vs_ct_in_get(s->protocol, + s->caddr, s->cport, + s->vaddr, s->vport); if (!cp) { cp = ip_vs_conn_new(s->protocol, s->caddr, s->cport, s->vaddr, s->vport, s->daddr, s->dport, - ntohs(s->flags), NULL); + flags, NULL); if (!cp) { IP_VS_ERR("ip_vs_conn_new failed\n"); return; @@ -315,11 +323,11 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } else if (!cp->dest) { /* it is an entry created by the synchronization */ cp->state = ntohs(s->state); - cp->flags = ntohs(s->flags) | IP_VS_CONN_F_HASHED; + cp->flags = flags | IP_VS_CONN_F_HASHED; } /* Note that we don't touch its state and flags if it is a normal entry. */ - if (ntohs(s->flags) & IP_VS_CONN_F_SEQ_MASK) { + if (flags & IP_VS_CONN_F_SEQ_MASK) { opt = (struct ip_vs_sync_conn_options *)&s[1]; memcpy(&cp->in_seq, opt, sizeof(*opt)); p += FULL_CONN_SIZE; From 40796c5e8f2a93008e9034b3110a7e7b1fa0fba0 Mon Sep 17 00:00:00 2001 From: David L Stevens Date: Wed, 14 Sep 2005 21:10:20 -0700 Subject: [PATCH 28/34] [IPV6]: Fix per-socket multicast filtering in sk_reuse case per-socket multicast filters were not being applied to all sockets in the case of an exact-match bound address, due to an over-exuberant "return" in the look-up code. Fix below. IPv4 does not have this problem. Thanks to Hoerdt Mickael for reporting the bug. Signed-off-by: David L Stevens Signed-off-by: David S. Miller --- net/ipv6/udp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 69b146843a20..2b9bf9bd177f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -405,9 +405,8 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, continue; if (!ipv6_addr_any(&np->rcv_saddr)) { - if (ipv6_addr_equal(&np->rcv_saddr, loc_addr)) - return s; - continue; + if (!ipv6_addr_equal(&np->rcv_saddr, loc_addr)) + continue; } if(!inet6_mc_check(s, loc_addr, rmt_addr)) continue; From 4a805e863d6b9466baf7084e1d6fdbe6e0628d8e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Sep 2005 21:40:00 -0700 Subject: [PATCH 29/34] [COMPAT]: Fixup compat_do_execve() Missing acct_update_integrals() and update_mem_hiwater() calls compared to it's native counterpart. Signed-off-by: David S. Miller --- fs/compat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/compat.c b/fs/compat.c index ac3fb9ed8eea..a719e158e002 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include /* siocdevprivate_ioctl */ @@ -1487,6 +1489,8 @@ int compat_do_execve(char * filename, /* execve success */ security_bprm_free(bprm); + acct_update_integrals(current); + update_mem_hiwater(current); kfree(bprm); return retval; } From 4db2ce0199f04b6e99999f22e28ef9a0ae5f0d2f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 14 Sep 2005 21:47:01 -0700 Subject: [PATCH 30/34] [LIB]: Consolidate _atomic_dec_and_lock() Several implementations were essentialy a common piece of C code using the cmpxchg() macro. Put the implementation in one spot that everyone can share, and convert sparc64 over to using this. Alpha is the lone arch-specific implementation, which codes up a special fast path for the common case in order to avoid GP reloading which a pure C version would require. Signed-off-by: David S. Miller --- arch/i386/Kconfig | 5 -- arch/i386/lib/Makefile | 1 - arch/i386/lib/dec_and_lock.c | 42 --------------- arch/ia64/Kconfig | 5 -- arch/ia64/lib/Makefile | 1 - arch/ia64/lib/dec_and_lock.c | 42 --------------- arch/m32r/Kconfig | 5 -- arch/mips/Kconfig | 4 -- arch/mips/lib/Makefile | 2 +- arch/mips/lib/dec_and_lock.c | 47 ----------------- arch/ppc/Kconfig | 4 -- arch/ppc/lib/Makefile | 2 +- arch/ppc/lib/dec_and_lock.c | 38 -------------- arch/ppc64/Kconfig | 4 -- arch/ppc64/lib/Makefile | 2 +- arch/ppc64/lib/dec_and_lock.c | 47 ----------------- arch/sparc64/Kconfig.debug | 8 --- arch/sparc64/kernel/sparc64_ksyms.c | 3 -- arch/sparc64/lib/Makefile | 2 - arch/sparc64/lib/dec_and_lock.S | 80 ----------------------------- arch/x86_64/Kconfig | 5 -- arch/x86_64/kernel/x8664_ksyms.c | 4 -- arch/x86_64/lib/Makefile | 2 - arch/x86_64/lib/dec_and_lock.c | 40 --------------- arch/xtensa/Kconfig | 4 -- lib/dec_and_lock.c | 35 +++++++++++++ 26 files changed, 38 insertions(+), 396 deletions(-) delete mode 100644 arch/i386/lib/dec_and_lock.c delete mode 100644 arch/ia64/lib/dec_and_lock.c delete mode 100644 arch/mips/lib/dec_and_lock.c delete mode 100644 arch/ppc/lib/dec_and_lock.c delete mode 100644 arch/ppc64/lib/dec_and_lock.c delete mode 100644 arch/sparc64/lib/dec_and_lock.S delete mode 100644 arch/x86_64/lib/dec_and_lock.c diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index b22f003eaa6d..d2703cda61ea 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -908,11 +908,6 @@ config IRQBALANCE The default yes will allow the kernel to do irq load balancing. Saying no will keep the kernel from doing irq load balancing. -config HAVE_DEC_LOCK - bool - depends on (SMP || PREEMPT) && X86_CMPXCHG - default y - # turning this on wastes a bunch of space. # Summit needs it only when NUMA is on config BOOT_IOREMAP diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 7b1932d20f96..914933e9ec3d 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -7,4 +7,3 @@ lib-y = checksum.o delay.o usercopy.o getuser.o putuser.o memcpy.o strstr.o \ bitops.o lib-$(CONFIG_X86_USE_3DNOW) += mmx.o -lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff --git a/arch/i386/lib/dec_and_lock.c b/arch/i386/lib/dec_and_lock.c deleted file mode 100644 index 8b81b2524fa6..000000000000 --- a/arch/i386/lib/dec_and_lock.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * x86 version of "atomic_dec_and_lock()" using - * the atomic "cmpxchg" instruction. - * - * (For CPU's lacking cmpxchg, we use the slow - * generic version, and this one never even gets - * compiled). - */ - -#include -#include -#include - -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - -repeat: - counter = atomic_read(atomic); - newcount = counter-1; - - if (!newcount) - goto slow_path; - - asm volatile("lock; cmpxchgl %1,%2" - :"=a" (newcount) - :"r" (newcount), "m" (atomic->counter), "0" (counter)); - - /* If the above failed, "eax" will have changed */ - if (newcount != counter) - goto repeat; - return 0; - -slow_path: - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} -EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index ed25d66c8d50..945c15a0722b 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -298,11 +298,6 @@ config PREEMPT source "mm/Kconfig" -config HAVE_DEC_LOCK - bool - depends on (SMP || PREEMPT) - default y - config IA32_SUPPORT bool "Support for Linux/x86 binaries" help diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 799407e7726f..cb1af597370b 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -15,7 +15,6 @@ lib-$(CONFIG_ITANIUM) += copy_page.o copy_user.o memcpy.o lib-$(CONFIG_MCKINLEY) += copy_page_mck.o memcpy_mck.o lib-$(CONFIG_PERFMON) += carta_random.o lib-$(CONFIG_MD_RAID5) += xor.o -lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o AFLAGS___divdi3.o = AFLAGS___udivdi3.o = -DUNSIGNED diff --git a/arch/ia64/lib/dec_and_lock.c b/arch/ia64/lib/dec_and_lock.c deleted file mode 100644 index c7ce92f968f1..000000000000 --- a/arch/ia64/lib/dec_and_lock.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2003 Jerome Marchand, Bull S.A. - * Cleaned up by David Mosberger-Tang - * - * This file is released under the GPLv2, or at your option any later version. - * - * ia64 version of "atomic_dec_and_lock()" using the atomic "cmpxchg" instruction. This - * code is an adaptation of the x86 version of "atomic_dec_and_lock()". - */ - -#include -#include -#include -#include - -/* - * Decrement REFCOUNT and if the count reaches zero, acquire the spinlock. Both of these - * operations have to be done atomically, so that the count doesn't drop to zero without - * acquiring the spinlock first. - */ -int -_atomic_dec_and_lock (atomic_t *refcount, spinlock_t *lock) -{ - int old, new; - - do { - old = atomic_read(refcount); - new = old - 1; - - if (unlikely (old == 1)) { - /* oops, we may be decrementing to zero, do it the slow way... */ - spin_lock(lock); - if (atomic_dec_and_test(refcount)) - return 1; - spin_unlock(lock); - return 0; - } - } while (cmpxchg(&refcount->counter, old, new) != old); - return 0; -} - -EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 1ef3987ebc6a..4d100f3886e1 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig @@ -220,11 +220,6 @@ config PREEMPT Say Y here if you are building a kernel for a desktop, embedded or real-time system. Say N if you are unsure. -config HAVE_DEC_LOCK - bool - depends on (SMP || PREEMPT) - default n - config SMP bool "Symmetric multi-processing support" ---help--- diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0eb71ac303af..4cd724c05700 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1009,10 +1009,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config HAVE_DEC_LOCK - bool - default y - # # Select some configuration options automatically based on user selections. # diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 21b92b9dd013..037303412909 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial_copy.o dec_and_lock.o memcpy.o promlib.o \ +lib-y += csum_partial_copy.o memcpy.o promlib.o \ strlen_user.o strncpy_user.o strnlen_user.o obj-y += iomap.o diff --git a/arch/mips/lib/dec_and_lock.c b/arch/mips/lib/dec_and_lock.c deleted file mode 100644 index fd82c84a93b7..000000000000 --- a/arch/mips/lib/dec_and_lock.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * MIPS version of atomic_dec_and_lock() using cmpxchg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -/* - * This is an implementation of the notion of "decrement a - * reference count, and return locked if it decremented to zero". - * - * This implementation can be used on any architecture that - * has a cmpxchg, and where atomic->value is an int holding - * the value of the atomic (i.e. the high bits aren't used - * for a lock or anything like that). - */ -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - - for (;;) { - counter = atomic_read(atomic); - newcount = counter - 1; - if (!newcount) - break; /* do it the slow way */ - - newcount = cmpxchg(&atomic->counter, counter, newcount); - if (newcount == counter) - return 0; - } - - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} - -EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 347ea284140b..776941c75672 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -26,10 +26,6 @@ config GENERIC_CALIBRATE_DELAY bool default y -config HAVE_DEC_LOCK - bool - default y - config PPC bool default y diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index f1e1fb4144f0..50358e4ea159 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc-specific library files.. # -obj-y := checksum.o string.o strcase.o dec_and_lock.o div64.o +obj-y := checksum.o string.o strcase.o div64.o obj-$(CONFIG_8xx) += rheap.o obj-$(CONFIG_CPM2) += rheap.o diff --git a/arch/ppc/lib/dec_and_lock.c b/arch/ppc/lib/dec_and_lock.c deleted file mode 100644 index b18f0d9a00fc..000000000000 --- a/arch/ppc/lib/dec_and_lock.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include -#include - -/* - * This is an implementation of the notion of "decrement a - * reference count, and return locked if it decremented to zero". - * - * This implementation can be used on any architecture that - * has a cmpxchg, and where atomic->value is an int holding - * the value of the atomic (i.e. the high bits aren't used - * for a lock or anything like that). - */ -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - - for (;;) { - counter = atomic_read(atomic); - newcount = counter - 1; - if (!newcount) - break; /* do it the slow way */ - - newcount = cmpxchg(&atomic->counter, counter, newcount); - if (newcount == counter) - return 0; - } - - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} - -EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index deca68ad644a..c658650af429 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -28,10 +28,6 @@ config GENERIC_ISA_DMA bool default y -config HAVE_DEC_LOCK - bool - default y - config EARLY_PRINTK bool default y diff --git a/arch/ppc64/lib/Makefile b/arch/ppc64/lib/Makefile index 76fbfa9f706f..0b6e967de948 100644 --- a/arch/ppc64/lib/Makefile +++ b/arch/ppc64/lib/Makefile @@ -2,7 +2,7 @@ # Makefile for ppc64-specific library files.. # -lib-y := checksum.o dec_and_lock.o string.o strcase.o +lib-y := checksum.o string.o strcase.o lib-y += copypage.o memcpy.o copyuser.o usercopy.o # Lock primitives are defined as no-ops in include/linux/spinlock.h diff --git a/arch/ppc64/lib/dec_and_lock.c b/arch/ppc64/lib/dec_and_lock.c deleted file mode 100644 index 7b9d4da5cf92..000000000000 --- a/arch/ppc64/lib/dec_and_lock.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ppc64 version of atomic_dec_and_lock() using cmpxchg - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include -#include -#include -#include - -/* - * This is an implementation of the notion of "decrement a - * reference count, and return locked if it decremented to zero". - * - * This implementation can be used on any architecture that - * has a cmpxchg, and where atomic->value is an int holding - * the value of the atomic (i.e. the high bits aren't used - * for a lock or anything like that). - */ -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - - for (;;) { - counter = atomic_read(atomic); - newcount = counter - 1; - if (!newcount) - break; /* do it the slow way */ - - newcount = cmpxchg(&atomic->counter, counter, newcount); - if (newcount == counter) - return 0; - } - - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} - -EXPORT_SYMBOL(_atomic_dec_and_lock); diff --git a/arch/sparc64/Kconfig.debug b/arch/sparc64/Kconfig.debug index cd8d39fb954d..af0e9411b83e 100644 --- a/arch/sparc64/Kconfig.debug +++ b/arch/sparc64/Kconfig.debug @@ -33,14 +33,6 @@ config DEBUG_BOOTMEM depends on DEBUG_KERNEL bool "Debug BOOTMEM initialization" -# We have a custom atomic_dec_and_lock() implementation but it's not -# compatible with spinlock debugging so we need to fall back on -# the generic version in that case. -config HAVE_DEC_LOCK - bool - depends on SMP && !DEBUG_SPINLOCK - default y - config MCOUNT bool depends on STACK_DEBUG diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index cbb5e59824e5..fb7a5370dbfc 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -163,9 +163,6 @@ EXPORT_SYMBOL(atomic64_add); EXPORT_SYMBOL(atomic64_add_ret); EXPORT_SYMBOL(atomic64_sub); EXPORT_SYMBOL(atomic64_sub_ret); -#ifdef CONFIG_SMP -EXPORT_SYMBOL(_atomic_dec_and_lock); -#endif /* Atomic bit operations. */ EXPORT_SYMBOL(test_and_set_bit); diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index d968aebe83b2..c295806500f7 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile @@ -14,6 +14,4 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \ copy_in_user.o user_fixup.o memmove.o \ mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o -lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o - obj-y += iomap.o diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S deleted file mode 100644 index 8ee288dd0afc..000000000000 --- a/arch/sparc64/lib/dec_and_lock.S +++ /dev/null @@ -1,80 +0,0 @@ -/* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $ - * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()" - * using cas and ldstub instructions. - * - * Copyright (C) 2000 David S. Miller (davem@redhat.com) - */ -#include -#include - - .text - .align 64 - - /* CAS basically works like this: - * - * void CAS(MEM, REG1, REG2) - * { - * START_ATOMIC(); - * if (*(MEM) == REG1) { - * TMP = *(MEM); - * *(MEM) = REG2; - * REG2 = TMP; - * } else - * REG2 = *(MEM); - * END_ATOMIC(); - * } - */ - - .globl _atomic_dec_and_lock -_atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */ -loop1: lduw [%o0], %g2 - subcc %g2, 1, %g7 - be,pn %icc, start_to_zero - nop -nzero: cas [%o0], %g2, %g7 - cmp %g2, %g7 - bne,pn %icc, loop1 - mov 0, %g1 - -out: - membar #StoreLoad | #StoreStore - retl - mov %g1, %o0 -start_to_zero: -#ifdef CONFIG_PREEMPT - ldsw [%g6 + TI_PRE_COUNT], %g3 - add %g3, 1, %g3 - stw %g3, [%g6 + TI_PRE_COUNT] -#endif -to_zero: - ldstub [%o1], %g3 - membar #StoreLoad | #StoreStore - brnz,pn %g3, spin_on_lock - nop -loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */ - cmp %g2, %g7 - - be,pt %icc, out - mov 1, %g1 - lduw [%o0], %g2 - subcc %g2, 1, %g7 - be,pn %icc, loop2 - nop - membar #StoreStore | #LoadStore - stb %g0, [%o1] -#ifdef CONFIG_PREEMPT - ldsw [%g6 + TI_PRE_COUNT], %g3 - sub %g3, 1, %g3 - stw %g3, [%g6 + TI_PRE_COUNT] -#endif - - b,pt %xcc, nzero - nop -spin_on_lock: - ldub [%o1], %g3 - membar #LoadLoad - brnz,pt %g3, spin_on_lock - nop - ba,pt %xcc, to_zero - nop - nop diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index e63323e03ea9..0969d570f3b5 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -277,11 +277,6 @@ source "mm/Kconfig" config HAVE_ARCH_EARLY_PFN_TO_NID def_bool y -config HAVE_DEC_LOCK - bool - depends on SMP - default y - config NR_CPUS int "Maximum number of CPUs (2-256)" range 2 256 diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 68ec03070e5a..fd99ddd009bc 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -178,10 +178,6 @@ EXPORT_SYMBOL(rwsem_down_write_failed_thunk); EXPORT_SYMBOL(empty_zero_page); -#ifdef CONFIG_HAVE_DEC_LOCK -EXPORT_SYMBOL(_atomic_dec_and_lock); -#endif - EXPORT_SYMBOL(die_chain); EXPORT_SYMBOL(register_die_notifier); diff --git a/arch/x86_64/lib/Makefile b/arch/x86_64/lib/Makefile index 6b26a1c1e9ff..bba5db6cebd6 100644 --- a/arch/x86_64/lib/Makefile +++ b/arch/x86_64/lib/Makefile @@ -10,5 +10,3 @@ lib-y := csum-partial.o csum-copy.o csum-wrappers.o delay.o \ usercopy.o getuser.o putuser.o \ thunk.o clear_page.o copy_page.o bitstr.o bitops.o lib-y += memcpy.o memmove.o memset.o copy_user.o - -lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o diff --git a/arch/x86_64/lib/dec_and_lock.c b/arch/x86_64/lib/dec_and_lock.c deleted file mode 100644 index ab43394dc775..000000000000 --- a/arch/x86_64/lib/dec_and_lock.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * x86 version of "atomic_dec_and_lock()" using - * the atomic "cmpxchg" instruction. - * - * (For CPU's lacking cmpxchg, we use the slow - * generic version, and this one never even gets - * compiled). - */ - -#include -#include - -int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) -{ - int counter; - int newcount; - -repeat: - counter = atomic_read(atomic); - newcount = counter-1; - - if (!newcount) - goto slow_path; - - asm volatile("lock; cmpxchgl %1,%2" - :"=a" (newcount) - :"r" (newcount), "m" (atomic->counter), "0" (counter)); - - /* If the above failed, "eax" will have changed */ - if (newcount != counter) - goto repeat; - return 0; - -slow_path: - spin_lock(lock); - if (atomic_dec_and_test(atomic)) - return 1; - spin_unlock(lock); - return 0; -} diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 2b6257bec4c3..7e841aa2a4aa 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -26,10 +26,6 @@ config RWSEM_XCHGADD_ALGORITHM bool default y -config HAVE_DEC_LOCK - bool - default y - config GENERIC_HARDIRQS bool default y diff --git a/lib/dec_and_lock.c b/lib/dec_and_lock.c index 2377af057d09..305a9663aee3 100644 --- a/lib/dec_and_lock.c +++ b/lib/dec_and_lock.c @@ -1,7 +1,41 @@ #include #include #include +#include +#ifdef __HAVE_ARCH_CMPXCHG +/* + * This is an implementation of the notion of "decrement a + * reference count, and return locked if it decremented to zero". + * + * This implementation can be used on any architecture that + * has a cmpxchg, and where atomic->value is an int holding + * the value of the atomic (i.e. the high bits aren't used + * for a lock or anything like that). + */ +int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) +{ + int counter; + int newcount; + + for (;;) { + counter = atomic_read(atomic); + newcount = counter - 1; + if (!newcount) + break; /* do it the slow way */ + + newcount = cmpxchg(&atomic->counter, counter, newcount); + if (newcount == counter) + return 0; + } + + spin_lock(lock); + if (atomic_dec_and_test(atomic)) + return 1; + spin_unlock(lock); + return 0; +} +#else /* * This is an architecture-neutral, but slow, * implementation of the notion of "decrement @@ -33,5 +67,6 @@ int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock) spin_unlock(lock); return 0; } +#endif EXPORT_SYMBOL(_atomic_dec_and_lock); From be201f7f4cd26b1bb994062803e0d87877e749ce Mon Sep 17 00:00:00 2001 From: Jimi Xenidis Date: Thu, 15 Sep 2005 08:42:19 -0400 Subject: [PATCH 31/34] [PATCH] ppc64: Fix recent regression As noted by Olof Johansson : "A recent patch changed the way the LPAR bit is checked during early boot. This resulted in a polarity change in a conditional branch without changing the branch, causing at least some legacy machines to not boot." This fixes it. Signed-off-by: Jimi Xenidis Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/head.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 58c314738c99..72c61041151a 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -1649,7 +1649,7 @@ _GLOBAL(__secondary_start) ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ - bne 98f + beq 98f /* branch if result is 0 */ mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ @@ -1813,7 +1813,7 @@ _STATIC(start_here_multiplatform) ld r3,0(r3) lwz r3,PLATFORM(r3) /* r3 = platform flags */ andi. r3,r3,PLATFORM_LPAR /* Test if bit 0 is set (LPAR bit) */ - bne 98f + beq 98f /* branch if result is 0 */ mfspr r3,PVR srwi r3,r3,16 cmpwi r3,0x37 /* SStar */ @@ -1834,7 +1834,7 @@ _STATIC(start_here_multiplatform) lwz r3,PLATFORM(r3) /* r3 = platform flags */ /* Test if bit 0 is set (LPAR bit) */ andi. r3,r3,PLATFORM_LPAR - bne 98f + bne 98f /* branch if result is !0 */ LOADADDR(r6,_SDR1) /* Only if NOT LPAR */ sub r6,r6,r26 ld r6,0(r6) /* get the value of _SDR1 */ From 7b6a186d65589901a73d460070504a5e02703c45 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Thu, 15 Sep 2005 20:58:57 +0800 Subject: [PATCH 32/34] [PATCH] savagefb: Fix load failure of the Twister chipset - The Twister chipsets are actually prosavages. Reclassify them as such and remove the S3_SAVAGE_TWISTER id. - Fix i2c code if fb_firmware_edid() returns NULL Signed-off-by: Antonino Daplas Signed-off-by: Linus Torvalds --- drivers/video/savage/savagefb-i2c.c | 11 +++++++---- drivers/video/savage/savagefb.h | 4 ---- drivers/video/savage/savagefb_driver.c | 11 +++++------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c index 959404ad68f4..3c98457783c4 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/savage/savagefb-i2c.c @@ -274,10 +274,13 @@ int savagefb_probe_i2c_connector(struct fb_info *info, u8 **out_edid) if (!edid) { /* try to get from firmware */ - edid = kmalloc(EDID_LENGTH, GFP_KERNEL); - if (edid) - memcpy(edid, fb_firmware_edid(info->device), - EDID_LENGTH); + const u8 *e = fb_firmware_edid(info->device); + + if (e) { + edid = kmalloc(EDID_LENGTH, GFP_KERNEL); + if (edid) + memcpy(edid, e, EDID_LENGTH); + } } if (out_edid) diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h index d6f94742c9f2..ea17f7e0482c 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/savage/savagefb.h @@ -60,8 +60,6 @@ #define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) -#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) || (chip == S3_PROSAVAGEDDR)) - /* Chip tags. These are used to group the adapters into * related families. */ @@ -74,8 +72,6 @@ typedef enum { S3_PROSAVAGE, S3_SUPERSAVAGE, S3_SAVAGE2000, - S3_PROSAVAGEDDR, - S3_TWISTER, S3_LAST } savage_chipset; diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index b5ca3ef8271f..7c285455c924 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -1773,8 +1773,7 @@ static int __devinit savage_init_hw (struct savagefb_par *par) } } - if (S3_SAVAGE_MOBILE_SERIES(par->chip) || - (S3_MOBILE_TWISTER_SERIES(par->chip) && !par->crtonly)) + if (S3_SAVAGE_MOBILE_SERIES(par->chip) && !par->crtonly) par->display_type = DISP_LCD; else if (dvi || (par->chip == S3_SAVAGE4 && par->dvi)) par->display_type = DISP_DFP; @@ -1783,7 +1782,7 @@ static int __devinit savage_init_hw (struct savagefb_par *par) /* Check LCD panel parrmation */ - if (par->chip == S3_SAVAGE_MX) { + if (par->display_type == DISP_LCD) { unsigned char cr6b = VGArCR( 0x6b ); int panelX = (VGArSEQ (0x61) + @@ -1922,15 +1921,15 @@ static int __devinit savage_init_fb_info (struct fb_info *info, snprintf (info->fix.id, 16, "ProSavageKM"); break; case FB_ACCEL_S3TWISTER_P: - par->chip = S3_TWISTER; + par->chip = S3_PROSAVAGE; snprintf (info->fix.id, 16, "TwisterP"); break; case FB_ACCEL_S3TWISTER_K: - par->chip = S3_TWISTER; + par->chip = S3_PROSAVAGE; snprintf (info->fix.id, 16, "TwisterK"); break; case FB_ACCEL_PROSAVAGE_DDR: - par->chip = S3_PROSAVAGEDDR; + par->chip = S3_PROSAVAGE; snprintf (info->fix.id, 16, "ProSavageDDR"); break; case FB_ACCEL_PROSAVAGE_DDRK: From 6d36ba629e0ef47a03d3703ee1d38143c25532a8 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Thu, 15 Sep 2005 21:14:56 +0800 Subject: [PATCH 33/34] [PATCH] vgacon: Fix sanity checking in vgacon_resize Reported by: walt "I routinely switch the console font during bootup to 8x8 so I can get 50 lines per screen. Until 09 Sept, just changing to the small font automatically gave me all 50 lines -- but now I'm only getting 25 lines even with the small font. The bottom half of the screen displays the text that already scrolled off the top." This bug is due to an erroneous check in the recently added hook, vgacon_resize(). It checks the new height against the original number of rows of the console. Because the original number of rows depends on both the scanline and the font height, check it instead against the scanline/fontheight. Signed-off-by: Antonino Daplas Signed-off-by: Linus Torvalds --- drivers/video/console/vgacon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 0705cd741411..6ef6f7760e47 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1020,7 +1020,9 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font) static int vgacon_resize(struct vc_data *c, unsigned int width, unsigned int height) { - if (width % 2 || width > ORIG_VIDEO_COLS || height > ORIG_VIDEO_LINES) + if (width % 2 || width > ORIG_VIDEO_COLS || + height > (ORIG_VIDEO_LINES * vga_default_font_height)/ + c->vc_font.height) return -EINVAL; if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */ From 065d9cac98a5406ecd5a1368f8fd38f55739dee9 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Thu, 15 Sep 2005 21:34:33 +0800 Subject: [PATCH 34/34] [PATCH] vc: Use correct size on buffer copy in vc_resize In the unlikely case of the new screen width much wider then the old, use (old_row_size * new_rows) instead of new_screen_size to prevent a buffer overrun during the copy. Signed-off-by: Antonino Daplas Signed-off-by: Linus Torvalds --- drivers/char/vt.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1e33cb032e07..e91268e86833 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -810,13 +810,14 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) * from the top and bottom of cursor position */ old_origin += (vc->vc_y - new_rows/2) * old_row_size; - end = old_origin + new_screen_size; + end = old_origin + (old_row_size * new_rows); } } else /* * Cursor near the top, copy contents from the top of buffer */ - end = (old_rows > new_rows) ? old_origin + new_screen_size : + end = (old_rows > new_rows) ? old_origin + + (old_row_size * new_rows) : vc->vc_scr_end; update_attr(vc);