diff options
| -rw-r--r-- | Documentation/filesystems/ubifs.txt | 2 | ||||
| -rw-r--r-- | Documentation/hwmon/ibmaem | 33 | ||||
| -rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 10 | ||||
| -rw-r--r-- | Documentation/vm/page_migration | 9 | ||||
| -rw-r--r-- | MAINTAINERS | 18 | ||||
| -rw-r--r-- | arch/alpha/include/asm/8253pit.h (renamed from include/asm-alpha/8253pit.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/Kbuild (renamed from include/asm-alpha/Kbuild) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/a.out-core.h (renamed from include/asm-alpha/a.out-core.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/a.out.h (renamed from include/asm-alpha/a.out.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/agp.h (renamed from include/asm-alpha/agp.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/agp_backend.h (renamed from include/asm-alpha/agp_backend.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/atomic.h (renamed from include/asm-alpha/atomic.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/auxvec.h (renamed from include/asm-alpha/auxvec.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/barrier.h (renamed from include/asm-alpha/barrier.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/bitops.h (renamed from include/asm-alpha/bitops.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/bug.h (renamed from include/asm-alpha/bug.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/bugs.h (renamed from include/asm-alpha/bugs.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/byteorder.h (renamed from include/asm-alpha/byteorder.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/cache.h (renamed from include/asm-alpha/cache.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/cacheflush.h (renamed from include/asm-alpha/cacheflush.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/checksum.h (renamed from include/asm-alpha/checksum.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/compiler.h (renamed from include/asm-alpha/compiler.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/console.h (renamed from include/asm-alpha/console.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_apecs.h (renamed from include/asm-alpha/core_apecs.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_cia.h (renamed from include/asm-alpha/core_cia.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_irongate.h (renamed from include/asm-alpha/core_irongate.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_lca.h (renamed from include/asm-alpha/core_lca.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_marvel.h (renamed from include/asm-alpha/core_marvel.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_mcpcia.h (renamed from include/asm-alpha/core_mcpcia.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_polaris.h (renamed from include/asm-alpha/core_polaris.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_t2.h (renamed from include/asm-alpha/core_t2.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_titan.h (renamed from include/asm-alpha/core_titan.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_tsunami.h (renamed from include/asm-alpha/core_tsunami.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/core_wildfire.h (renamed from include/asm-alpha/core_wildfire.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/cputime.h (renamed from include/asm-alpha/cputime.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/current.h (renamed from include/asm-alpha/current.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/delay.h (renamed from include/asm-alpha/delay.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/device.h (renamed from include/asm-alpha/device.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/div64.h (renamed from include/asm-alpha/div64.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/dma-mapping.h (renamed from include/asm-alpha/dma-mapping.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/dma.h (renamed from include/asm-alpha/dma.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/elf.h (renamed from include/asm-alpha/elf.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/emergency-restart.h (renamed from include/asm-alpha/emergency-restart.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/err_common.h (renamed from include/asm-alpha/err_common.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/err_ev6.h (renamed from include/asm-alpha/err_ev6.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/err_ev7.h (renamed from include/asm-alpha/err_ev7.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/errno.h (renamed from include/asm-alpha/errno.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/fb.h (renamed from include/asm-alpha/fb.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/fcntl.h (renamed from include/asm-alpha/fcntl.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/floppy.h (renamed from include/asm-alpha/floppy.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/fpu.h (renamed from include/asm-alpha/fpu.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/futex.h (renamed from include/asm-alpha/futex.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/gct.h (renamed from include/asm-alpha/gct.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/gentrap.h (renamed from include/asm-alpha/gentrap.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/hardirq.h (renamed from include/asm-alpha/hardirq.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/hw_irq.h (renamed from include/asm-alpha/hw_irq.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/hwrpb.h (renamed from include/asm-alpha/hwrpb.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/io.h (renamed from include/asm-alpha/io.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/io_trivial.h (renamed from include/asm-alpha/io_trivial.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/ioctl.h (renamed from include/asm-alpha/ioctl.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/ioctls.h (renamed from include/asm-alpha/ioctls.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/ipcbuf.h (renamed from include/asm-alpha/ipcbuf.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/irq.h (renamed from include/asm-alpha/irq.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/irq_regs.h (renamed from include/asm-alpha/irq_regs.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/jensen.h (renamed from include/asm-alpha/jensen.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/kdebug.h (renamed from include/asm-alpha/kdebug.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/kmap_types.h (renamed from include/asm-alpha/kmap_types.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/linkage.h (renamed from include/asm-alpha/linkage.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/local.h (renamed from include/asm-alpha/local.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/machvec.h (renamed from include/asm-alpha/machvec.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mc146818rtc.h (renamed from include/asm-alpha/mc146818rtc.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/md.h (renamed from include/asm-alpha/md.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mman.h (renamed from include/asm-alpha/mman.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mmu.h (renamed from include/asm-alpha/mmu.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mmu_context.h (renamed from include/asm-alpha/mmu_context.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mmzone.h (renamed from include/asm-alpha/mmzone.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/module.h (renamed from include/asm-alpha/module.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/msgbuf.h (renamed from include/asm-alpha/msgbuf.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/mutex.h (renamed from include/asm-alpha/mutex.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/page.h (renamed from include/asm-alpha/page.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/pal.h (renamed from include/asm-alpha/pal.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/param.h (renamed from include/asm-alpha/param.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/parport.h (renamed from include/asm-alpha/parport.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/pci.h (renamed from include/asm-alpha/pci.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/percpu.h (renamed from include/asm-alpha/percpu.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/pgalloc.h (renamed from include/asm-alpha/pgalloc.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/pgtable.h (renamed from include/asm-alpha/pgtable.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/poll.h (renamed from include/asm-alpha/poll.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/posix_types.h (renamed from include/asm-alpha/posix_types.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/processor.h (renamed from include/asm-alpha/processor.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/ptrace.h (renamed from include/asm-alpha/ptrace.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/reg.h (renamed from include/asm-alpha/reg.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/regdef.h (renamed from include/asm-alpha/regdef.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/resource.h (renamed from include/asm-alpha/resource.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/rtc.h (renamed from include/asm-alpha/rtc.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/rwsem.h (renamed from include/asm-alpha/rwsem.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/scatterlist.h (renamed from include/asm-alpha/scatterlist.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sections.h (renamed from include/asm-alpha/sections.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/segment.h (renamed from include/asm-alpha/segment.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sembuf.h (renamed from include/asm-alpha/sembuf.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/serial.h (renamed from include/asm-alpha/serial.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/setup.h (renamed from include/asm-alpha/setup.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sfp-machine.h (renamed from include/asm-alpha/sfp-machine.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/shmbuf.h (renamed from include/asm-alpha/shmbuf.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/shmparam.h (renamed from include/asm-alpha/shmparam.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sigcontext.h (renamed from include/asm-alpha/sigcontext.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/siginfo.h (renamed from include/asm-alpha/siginfo.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/signal.h (renamed from include/asm-alpha/signal.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/smp.h (renamed from include/asm-alpha/smp.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/socket.h (renamed from include/asm-alpha/socket.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sockios.h (renamed from include/asm-alpha/sockios.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/spinlock.h (renamed from include/asm-alpha/spinlock.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/spinlock_types.h (renamed from include/asm-alpha/spinlock_types.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/stat.h (renamed from include/asm-alpha/stat.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/statfs.h (renamed from include/asm-alpha/statfs.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/string.h (renamed from include/asm-alpha/string.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/suspend.h (renamed from include/asm-alpha/suspend.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/sysinfo.h (renamed from include/asm-alpha/sysinfo.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/system.h (renamed from include/asm-alpha/system.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/termbits.h (renamed from include/asm-alpha/termbits.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/termios.h (renamed from include/asm-alpha/termios.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/thread_info.h (renamed from include/asm-alpha/thread_info.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/timex.h (renamed from include/asm-alpha/timex.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/tlb.h (renamed from include/asm-alpha/tlb.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/tlbflush.h (renamed from include/asm-alpha/tlbflush.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/topology.h (renamed from include/asm-alpha/topology.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/types.h (renamed from include/asm-alpha/types.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/uaccess.h (renamed from include/asm-alpha/uaccess.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/ucontext.h (renamed from include/asm-alpha/ucontext.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/unaligned.h (renamed from include/asm-alpha/unaligned.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/unistd.h (renamed from include/asm-alpha/unistd.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/user.h (renamed from include/asm-alpha/user.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/vga.h (renamed from include/asm-alpha/vga.h) | 0 | ||||
| -rw-r--r-- | arch/alpha/include/asm/xor.h (renamed from include/asm-alpha/xor.h) | 0 | ||||
| -rw-r--r-- | arch/arm/include/asm/kexec.h | 2 | ||||
| -rw-r--r-- | arch/arm/kernel/machine_kexec.c | 2 | ||||
| -rw-r--r-- | arch/ia64/include/asm/kexec.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/include/asm/kexec.h | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/machine_kexec_32.c | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/kexec.h | 2 | ||||
| -rw-r--r-- | arch/sh/include/asm/kexec.h | 2 | ||||
| -rw-r--r-- | arch/x86/kernel/machine_kexec_32.c | 20 | ||||
| -rw-r--r-- | arch/x86/kernel/relocate_kernel_32.S | 10 | ||||
| -rw-r--r-- | arch/x86/kernel/vmlinux_32.lds.S | 8 | ||||
| -rw-r--r-- | drivers/char/tty_io.c | 72 | ||||
| -rw-r--r-- | drivers/char/vt.c | 82 | ||||
| -rw-r--r-- | drivers/char/vt_ioctl.c | 4 | ||||
| -rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 12 | ||||
| -rw-r--r-- | drivers/hwmon/Kconfig | 16 | ||||
| -rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
| -rw-r--r-- | drivers/hwmon/abituguru3.c | 134 | ||||
| -rw-r--r-- | drivers/hwmon/adcxx.c | 329 | ||||
| -rw-r--r-- | drivers/hwmon/applesmc.c | 20 | ||||
| -rw-r--r-- | drivers/hwmon/coretemp.c | 5 | ||||
| -rw-r--r-- | drivers/hwmon/hwmon-vid.c | 36 | ||||
| -rw-r--r-- | drivers/hwmon/i5k_amb.c | 28 | ||||
| -rw-r--r-- | drivers/hwmon/ibmaem.c | 27 | ||||
| -rw-r--r-- | drivers/hwmon/w83791d.c | 3 | ||||
| -rw-r--r-- | drivers/input/evdev.c | 63 | ||||
| -rw-r--r-- | drivers/input/joystick/xpad.c | 1 | ||||
| -rw-r--r-- | drivers/input/keyboard/gpio_keys.c | 3 | ||||
| -rw-r--r-- | drivers/input/mouse/Kconfig | 23 | ||||
| -rw-r--r-- | drivers/input/mouse/Makefile | 1 | ||||
| -rw-r--r-- | drivers/input/mouse/bcm5974.c | 681 | ||||
| -rw-r--r-- | drivers/input/serio/i8042-x86ia64io.h | 7 | ||||
| -rw-r--r-- | drivers/input/serio/xilinx_ps2.c | 4 | ||||
| -rw-r--r-- | drivers/input/touchscreen/Kconfig | 21 | ||||
| -rw-r--r-- | drivers/md/md.c | 33 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 9 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 32 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 40 | ||||
| -rw-r--r-- | drivers/video/fsl-diu-fb.c | 32 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 1 | ||||
| -rw-r--r-- | fs/inode.c | 1 | ||||
| -rw-r--r-- | fs/omfs/bitmap.c | 5 | ||||
| -rw-r--r-- | fs/omfs/file.c | 33 | ||||
| -rw-r--r-- | fs/omfs/inode.c | 3 | ||||
| -rw-r--r-- | fs/ubifs/budget.c | 33 | ||||
| -rw-r--r-- | fs/ubifs/commit.c | 3 | ||||
| -rw-r--r-- | fs/ubifs/debug.c | 27 | ||||
| -rw-r--r-- | fs/ubifs/debug.h | 143 | ||||
| -rw-r--r-- | fs/ubifs/dir.c | 24 | ||||
| -rw-r--r-- | fs/ubifs/file.c | 8 | ||||
| -rw-r--r-- | fs/ubifs/find.c | 9 | ||||
| -rw-r--r-- | fs/ubifs/io.c | 14 | ||||
| -rw-r--r-- | fs/ubifs/journal.c | 110 | ||||
| -rw-r--r-- | fs/ubifs/log.c | 4 | ||||
| -rw-r--r-- | fs/ubifs/misc.h | 16 | ||||
| -rw-r--r-- | fs/ubifs/orphan.c | 4 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 48 | ||||
| -rw-r--r-- | fs/ubifs/tnc_commit.c | 37 | ||||
| -rw-r--r-- | fs/ubifs/ubifs-media.h | 4 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.h | 33 | ||||
| -rw-r--r-- | fs/ubifs/xattr.c | 54 | ||||
| -rw-r--r-- | include/asm-mips/kexec.h | 2 | ||||
| -rw-r--r-- | include/asm-x86/kexec.h | 8 | ||||
| -rw-r--r-- | include/asm-x86/mman.h | 1 | ||||
| -rw-r--r-- | include/linux/completion.h | 46 | ||||
| -rw-r--r-- | include/linux/ftrace.h | 21 | ||||
| -rw-r--r-- | include/linux/kexec.h | 4 | ||||
| -rw-r--r-- | include/linux/reboot.h | 1 | ||||
| -rw-r--r-- | include/linux/suspend.h | 4 | ||||
| -rw-r--r-- | include/linux/tty.h | 2 | ||||
| -rw-r--r-- | include/linux/tty_driver.h | 14 | ||||
| -rw-r--r-- | include/linux/vt_kern.h | 1 | ||||
| -rw-r--r-- | kernel/kexec.c | 66 | ||||
| -rw-r--r-- | kernel/sched.c | 46 | ||||
| -rw-r--r-- | kernel/sys.c | 2 | ||||
| -rw-r--r-- | mm/bootmem.c | 2 | ||||
| -rw-r--r-- | sound/pci/Kconfig | 2 | ||||
| -rw-r--r-- | sound/pci/oxygen/virtuoso.c | 73 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8990.c | 10 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8990.h | 14 |
214 files changed, 2174 insertions, 604 deletions
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt index 540e9e7f59c5..6a0d70a22f05 100644 --- a/Documentation/filesystems/ubifs.txt +++ b/Documentation/filesystems/ubifs.txt | |||
| @@ -57,7 +57,7 @@ Similarly to JFFS2, UBIFS supports on-the-flight compression which makes | |||
| 57 | it possible to fit quite a lot of data to the flash. | 57 | it possible to fit quite a lot of data to the flash. |
| 58 | 58 | ||
| 59 | Similarly to JFFS2, UBIFS is tolerant of unclean reboots and power-cuts. | 59 | Similarly to JFFS2, UBIFS is tolerant of unclean reboots and power-cuts. |
| 60 | It does not need stuff like ckfs.ext2. UBIFS automatically replays its | 60 | It does not need stuff like fsck.ext2. UBIFS automatically replays its |
| 61 | journal and recovers from crashes, ensuring that the on-flash data | 61 | journal and recovers from crashes, ensuring that the on-flash data |
| 62 | structures are consistent. | 62 | structures are consistent. |
| 63 | 63 | ||
diff --git a/Documentation/hwmon/ibmaem b/Documentation/hwmon/ibmaem index 2fefaf582a43..e98bdfea3467 100644 --- a/Documentation/hwmon/ibmaem +++ b/Documentation/hwmon/ibmaem | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | Kernel driver ibmaem | 1 | Kernel driver ibmaem |
| 2 | ====================== | 2 | ====================== |
| 3 | 3 | ||
| 4 | This driver talks to the IBM Systems Director Active Energy Manager, known | ||
| 5 | henceforth as AEM. | ||
| 6 | |||
| 4 | Supported systems: | 7 | Supported systems: |
| 5 | * Any recent IBM System X server with Active Energy Manager support. | 8 | * Any recent IBM System X server with AEM support. |
| 6 | This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2, | 9 | This includes the x3350, x3550, x3650, x3655, x3755, x3850 M2, |
| 7 | x3950 M2, and certain HS2x/LS2x/QS2x blades. The IPMI host interface | 10 | x3950 M2, and certain HS2x/LS2x/QS2x blades. The IPMI host interface |
| 8 | driver ("ipmi-si") needs to be loaded for this driver to do anything. | 11 | driver ("ipmi-si") needs to be loaded for this driver to do anything. |
| @@ -14,24 +17,22 @@ Author: Darrick J. Wong | |||
| 14 | Description | 17 | Description |
| 15 | ----------- | 18 | ----------- |
| 16 | 19 | ||
| 17 | This driver implements sensor reading support for the energy and power | 20 | This driver implements sensor reading support for the energy and power meters |
| 18 | meters available on various IBM System X hardware through the BMC. All | 21 | available on various IBM System X hardware through the BMC. All sensor banks |
| 19 | sensor banks will be exported as platform devices; this driver can talk | 22 | will be exported as platform devices; this driver can talk to both v1 and v2 |
| 20 | to both v1 and v2 interfaces. This driver is completely separate from the | 23 | interfaces. This driver is completely separate from the older ibmpex driver. |
| 21 | older ibmpex driver. | ||
| 22 | 24 | ||
| 23 | The v1 AEM interface has a simple set of features to monitor energy use. | 25 | The v1 AEM interface has a simple set of features to monitor energy use. There |
| 24 | There is a register that displays an estimate of raw energy consumption | 26 | is a register that displays an estimate of raw energy consumption since the |
| 25 | since the last BMC reset, and a power sensor that returns average power | 27 | last BMC reset, and a power sensor that returns average power use over a |
| 26 | use over a configurable interval. | 28 | configurable interval. |
| 27 | 29 | ||
| 28 | The v2 AEM interface is a bit more sophisticated, being able to present | 30 | The v2 AEM interface is a bit more sophisticated, being able to present a wider |
| 29 | a wider range of energy and power use registers, the power cap as | 31 | range of energy and power use registers, the power cap as set by the AEM |
| 30 | set by the AEM software, and temperature sensors. | 32 | software, and temperature sensors. |
| 31 | 33 | ||
| 32 | Special Features | 34 | Special Features |
| 33 | ---------------- | 35 | ---------------- |
| 34 | 36 | ||
| 35 | The "power_cap" value displays the current system power cap, as set by | 37 | The "power_cap" value displays the current system power cap, as set by the AEM |
| 36 | the Active Energy Manager software. Setting the power cap from the host | 38 | software. Setting the power cap from the host is not currently supported. |
| 37 | is not currently supported. | ||
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 6f6d117ac7e2..b117e42a6166 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
| @@ -1144,8 +1144,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1144 | 1144 | ||
| 1145 | This module supports autoprobe and multiple cards. | 1145 | This module supports autoprobe and multiple cards. |
| 1146 | 1146 | ||
| 1147 | Power management is _not_ supported. | ||
| 1148 | |||
| 1149 | Module snd-ice1712 | 1147 | Module snd-ice1712 |
| 1150 | ------------------ | 1148 | ------------------ |
| 1151 | 1149 | ||
| @@ -1628,8 +1626,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 1628 | 1626 | ||
| 1629 | This module supports autoprobe and multiple cards. | 1627 | This module supports autoprobe and multiple cards. |
| 1630 | 1628 | ||
| 1631 | Power management is _not_ supported. | ||
| 1632 | |||
| 1633 | Module snd-pcsp | 1629 | Module snd-pcsp |
| 1634 | ----------------- | 1630 | ----------------- |
| 1635 | 1631 | ||
| @@ -2081,13 +2077,11 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 2081 | Module snd-virtuoso | 2077 | Module snd-virtuoso |
| 2082 | ------------------- | 2078 | ------------------- |
| 2083 | 2079 | ||
| 2084 | Module for sound cards based on the Asus AV200 chip, i.e., | 2080 | Module for sound cards based on the Asus AV100/AV200 chips, |
| 2085 | Xonar D2 and Xonar D2X. | 2081 | i.e., Xonar D1, DX, D2 and D2X. |
| 2086 | 2082 | ||
| 2087 | This module supports autoprobe and multiple cards. | 2083 | This module supports autoprobe and multiple cards. |
| 2088 | 2084 | ||
| 2089 | Power management is _not_ supported. | ||
| 2090 | |||
| 2091 | Module snd-vx222 | 2085 | Module snd-vx222 |
| 2092 | ---------------- | 2086 | ---------------- |
| 2093 | 2087 | ||
diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration index 99f89aa10169..d5fdfd34bbaf 100644 --- a/Documentation/vm/page_migration +++ b/Documentation/vm/page_migration | |||
| @@ -18,10 +18,11 @@ migrate_pages function call takes two sets of nodes and moves pages of a | |||
| 18 | process that are located on the from nodes to the destination nodes. | 18 | process that are located on the from nodes to the destination nodes. |
| 19 | Page migration functions are provided by the numactl package by Andi Kleen | 19 | Page migration functions are provided by the numactl package by Andi Kleen |
| 20 | (a version later than 0.9.3 is required. Get it from | 20 | (a version later than 0.9.3 is required. Get it from |
| 21 | ftp://ftp.suse.com/pub/people/ak). numactl provided libnuma which | 21 | ftp://oss.sgi.com/www/projects/libnuma/download/). numactl provides libnuma |
| 22 | provides an interface similar to other numa functionality for page migration. | 22 | which provides an interface similar to other numa functionality for page |
| 23 | cat /proc/<pid>/numa_maps allows an easy review of where the pages of | 23 | migration. cat /proc/<pid>/numa_maps allows an easy review of where the |
| 24 | a process are located. See also the numa_maps manpage in the numactl package. | 24 | pages of a process are located. See also the numa_maps documentation in the |
| 25 | proc(5) man page. | ||
| 25 | 26 | ||
| 26 | Manual migration is useful if for example the scheduler has relocated | 27 | Manual migration is useful if for example the scheduler has relocated |
| 27 | a process to a processor on a distant node. A batch scheduler or an | 28 | a process to a processor on a distant node. A batch scheduler or an |
diff --git a/MAINTAINERS b/MAINTAINERS index 4c5e9fe0f7db..663485b004fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -175,12 +175,18 @@ M: bcrl@kvack.org | |||
| 175 | L: linux-aio@kvack.org | 175 | L: linux-aio@kvack.org |
| 176 | S: Supported | 176 | S: Supported |
| 177 | 177 | ||
| 178 | ABIT UGURU HARDWARE MONITOR DRIVER | 178 | ABIT UGURU 1,2 HARDWARE MONITOR DRIVER |
| 179 | P: Hans de Goede | 179 | P: Hans de Goede |
| 180 | M: j.w.r.degoede@hhs.nl | 180 | M: j.w.r.degoede@hhs.nl |
| 181 | L: lm-sensors@lm-sensors.org | 181 | L: lm-sensors@lm-sensors.org |
| 182 | S: Maintained | 182 | S: Maintained |
| 183 | 183 | ||
| 184 | ABIT UGURU 3 HARDWARE MONITOR DRIVER | ||
| 185 | P: Alistair John Strachan | ||
| 186 | M: alistair@devzero.co.uk | ||
| 187 | L: lm-sensors@lm-sensors.org | ||
| 188 | S: Maintained | ||
| 189 | |||
| 184 | ACENIC DRIVER | 190 | ACENIC DRIVER |
| 185 | P: Jes Sorensen | 191 | P: Jes Sorensen |
| 186 | M: jes@trained-monkey.org | 192 | M: jes@trained-monkey.org |
| @@ -3748,6 +3754,16 @@ L: linux-visws-devel@lists.sf.net | |||
| 3748 | W: http://linux-visws.sf.net | 3754 | W: http://linux-visws.sf.net |
| 3749 | S: Maintained for 2.6. | 3755 | S: Maintained for 2.6. |
| 3750 | 3756 | ||
| 3757 | SGI GRU DRIVER | ||
| 3758 | P: Jack Steiner | ||
| 3759 | M: steiner@sgi.com | ||
| 3760 | S: Maintained | ||
| 3761 | |||
| 3762 | SGI XP/XPC/XPNET DRIVER | ||
| 3763 | P: Dean Nelson | ||
| 3764 | M: dcn@sgi.com | ||
| 3765 | S: Maintained | ||
| 3766 | |||
| 3751 | SIMTEC EB110ATX (Chalice CATS) | 3767 | SIMTEC EB110ATX (Chalice CATS) |
| 3752 | P: Ben Dooks | 3768 | P: Ben Dooks |
| 3753 | P: Vincent Sanders | 3769 | P: Vincent Sanders |
diff --git a/include/asm-alpha/8253pit.h b/arch/alpha/include/asm/8253pit.h index fef5c1450e47..fef5c1450e47 100644 --- a/include/asm-alpha/8253pit.h +++ b/arch/alpha/include/asm/8253pit.h | |||
diff --git a/include/asm-alpha/Kbuild b/arch/alpha/include/asm/Kbuild index b7c8f188b313..b7c8f188b313 100644 --- a/include/asm-alpha/Kbuild +++ b/arch/alpha/include/asm/Kbuild | |||
diff --git a/include/asm-alpha/a.out-core.h b/arch/alpha/include/asm/a.out-core.h index 9e33e92e524c..9e33e92e524c 100644 --- a/include/asm-alpha/a.out-core.h +++ b/arch/alpha/include/asm/a.out-core.h | |||
diff --git a/include/asm-alpha/a.out.h b/arch/alpha/include/asm/a.out.h index 02ce8473870a..02ce8473870a 100644 --- a/include/asm-alpha/a.out.h +++ b/arch/alpha/include/asm/a.out.h | |||
diff --git a/include/asm-alpha/agp.h b/arch/alpha/include/asm/agp.h index 26c179135293..26c179135293 100644 --- a/include/asm-alpha/agp.h +++ b/arch/alpha/include/asm/agp.h | |||
diff --git a/include/asm-alpha/agp_backend.h b/arch/alpha/include/asm/agp_backend.h index 55dd44a2cea7..55dd44a2cea7 100644 --- a/include/asm-alpha/agp_backend.h +++ b/arch/alpha/include/asm/agp_backend.h | |||
diff --git a/include/asm-alpha/atomic.h b/arch/alpha/include/asm/atomic.h index ca88e54dec93..ca88e54dec93 100644 --- a/include/asm-alpha/atomic.h +++ b/arch/alpha/include/asm/atomic.h | |||
diff --git a/include/asm-alpha/auxvec.h b/arch/alpha/include/asm/auxvec.h index e96fe880e310..e96fe880e310 100644 --- a/include/asm-alpha/auxvec.h +++ b/arch/alpha/include/asm/auxvec.h | |||
diff --git a/include/asm-alpha/barrier.h b/arch/alpha/include/asm/barrier.h index ac78eba909bc..ac78eba909bc 100644 --- a/include/asm-alpha/barrier.h +++ b/arch/alpha/include/asm/barrier.h | |||
diff --git a/include/asm-alpha/bitops.h b/arch/alpha/include/asm/bitops.h index 15f3ae25c511..15f3ae25c511 100644 --- a/include/asm-alpha/bitops.h +++ b/arch/alpha/include/asm/bitops.h | |||
diff --git a/include/asm-alpha/bug.h b/arch/alpha/include/asm/bug.h index 695a5ee4b5d3..695a5ee4b5d3 100644 --- a/include/asm-alpha/bug.h +++ b/arch/alpha/include/asm/bug.h | |||
diff --git a/include/asm-alpha/bugs.h b/arch/alpha/include/asm/bugs.h index 78030d1c7e7e..78030d1c7e7e 100644 --- a/include/asm-alpha/bugs.h +++ b/arch/alpha/include/asm/bugs.h | |||
diff --git a/include/asm-alpha/byteorder.h b/arch/alpha/include/asm/byteorder.h index 58e958fc7f1b..58e958fc7f1b 100644 --- a/include/asm-alpha/byteorder.h +++ b/arch/alpha/include/asm/byteorder.h | |||
diff --git a/include/asm-alpha/cache.h b/arch/alpha/include/asm/cache.h index f199e69a5d0b..f199e69a5d0b 100644 --- a/include/asm-alpha/cache.h +++ b/arch/alpha/include/asm/cache.h | |||
diff --git a/include/asm-alpha/cacheflush.h b/arch/alpha/include/asm/cacheflush.h index b686cc7fc44e..b686cc7fc44e 100644 --- a/include/asm-alpha/cacheflush.h +++ b/arch/alpha/include/asm/cacheflush.h | |||
diff --git a/include/asm-alpha/checksum.h b/arch/alpha/include/asm/checksum.h index d3854bbf0a9e..d3854bbf0a9e 100644 --- a/include/asm-alpha/checksum.h +++ b/arch/alpha/include/asm/checksum.h | |||
diff --git a/include/asm-alpha/compiler.h b/arch/alpha/include/asm/compiler.h index da6bb199839c..da6bb199839c 100644 --- a/include/asm-alpha/compiler.h +++ b/arch/alpha/include/asm/compiler.h | |||
diff --git a/include/asm-alpha/console.h b/arch/alpha/include/asm/console.h index a3ce4e62249b..a3ce4e62249b 100644 --- a/include/asm-alpha/console.h +++ b/arch/alpha/include/asm/console.h | |||
diff --git a/include/asm-alpha/core_apecs.h b/arch/alpha/include/asm/core_apecs.h index 6785ff7e02bc..6785ff7e02bc 100644 --- a/include/asm-alpha/core_apecs.h +++ b/arch/alpha/include/asm/core_apecs.h | |||
diff --git a/include/asm-alpha/core_cia.h b/arch/alpha/include/asm/core_cia.h index 9e0516c0ca27..9e0516c0ca27 100644 --- a/include/asm-alpha/core_cia.h +++ b/arch/alpha/include/asm/core_cia.h | |||
diff --git a/include/asm-alpha/core_irongate.h b/arch/alpha/include/asm/core_irongate.h index 24b2db541501..24b2db541501 100644 --- a/include/asm-alpha/core_irongate.h +++ b/arch/alpha/include/asm/core_irongate.h | |||
diff --git a/include/asm-alpha/core_lca.h b/arch/alpha/include/asm/core_lca.h index f7cb4b460954..f7cb4b460954 100644 --- a/include/asm-alpha/core_lca.h +++ b/arch/alpha/include/asm/core_lca.h | |||
diff --git a/include/asm-alpha/core_marvel.h b/arch/alpha/include/asm/core_marvel.h index 30d55fe7aaf6..30d55fe7aaf6 100644 --- a/include/asm-alpha/core_marvel.h +++ b/arch/alpha/include/asm/core_marvel.h | |||
diff --git a/include/asm-alpha/core_mcpcia.h b/arch/alpha/include/asm/core_mcpcia.h index acf55b483472..acf55b483472 100644 --- a/include/asm-alpha/core_mcpcia.h +++ b/arch/alpha/include/asm/core_mcpcia.h | |||
diff --git a/include/asm-alpha/core_polaris.h b/arch/alpha/include/asm/core_polaris.h index 2f966b64659d..2f966b64659d 100644 --- a/include/asm-alpha/core_polaris.h +++ b/arch/alpha/include/asm/core_polaris.h | |||
diff --git a/include/asm-alpha/core_t2.h b/arch/alpha/include/asm/core_t2.h index 46bfff58f670..46bfff58f670 100644 --- a/include/asm-alpha/core_t2.h +++ b/arch/alpha/include/asm/core_t2.h | |||
diff --git a/include/asm-alpha/core_titan.h b/arch/alpha/include/asm/core_titan.h index a17f6f33b68e..a17f6f33b68e 100644 --- a/include/asm-alpha/core_titan.h +++ b/arch/alpha/include/asm/core_titan.h | |||
diff --git a/include/asm-alpha/core_tsunami.h b/arch/alpha/include/asm/core_tsunami.h index 58d4fe48742c..58d4fe48742c 100644 --- a/include/asm-alpha/core_tsunami.h +++ b/arch/alpha/include/asm/core_tsunami.h | |||
diff --git a/include/asm-alpha/core_wildfire.h b/arch/alpha/include/asm/core_wildfire.h index cd562f544ba2..cd562f544ba2 100644 --- a/include/asm-alpha/core_wildfire.h +++ b/arch/alpha/include/asm/core_wildfire.h | |||
diff --git a/include/asm-alpha/cputime.h b/arch/alpha/include/asm/cputime.h index 19577fd93230..19577fd93230 100644 --- a/include/asm-alpha/cputime.h +++ b/arch/alpha/include/asm/cputime.h | |||
diff --git a/include/asm-alpha/current.h b/arch/alpha/include/asm/current.h index 094d285a1b34..094d285a1b34 100644 --- a/include/asm-alpha/current.h +++ b/arch/alpha/include/asm/current.h | |||
diff --git a/include/asm-alpha/delay.h b/arch/alpha/include/asm/delay.h index 2aa3f410f7e6..2aa3f410f7e6 100644 --- a/include/asm-alpha/delay.h +++ b/arch/alpha/include/asm/delay.h | |||
diff --git a/include/asm-alpha/device.h b/arch/alpha/include/asm/device.h index d8f9872b0e2d..d8f9872b0e2d 100644 --- a/include/asm-alpha/device.h +++ b/arch/alpha/include/asm/device.h | |||
diff --git a/include/asm-alpha/div64.h b/arch/alpha/include/asm/div64.h index 6cd978cefb28..6cd978cefb28 100644 --- a/include/asm-alpha/div64.h +++ b/arch/alpha/include/asm/div64.h | |||
diff --git a/include/asm-alpha/dma-mapping.h b/arch/alpha/include/asm/dma-mapping.h index a5801ae02e4b..a5801ae02e4b 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/arch/alpha/include/asm/dma-mapping.h | |||
diff --git a/include/asm-alpha/dma.h b/arch/alpha/include/asm/dma.h index 87cfdbdf08fc..87cfdbdf08fc 100644 --- a/include/asm-alpha/dma.h +++ b/arch/alpha/include/asm/dma.h | |||
diff --git a/include/asm-alpha/elf.h b/arch/alpha/include/asm/elf.h index fc1002ea1e0c..fc1002ea1e0c 100644 --- a/include/asm-alpha/elf.h +++ b/arch/alpha/include/asm/elf.h | |||
diff --git a/include/asm-alpha/emergency-restart.h b/arch/alpha/include/asm/emergency-restart.h index 108d8c48e42e..108d8c48e42e 100644 --- a/include/asm-alpha/emergency-restart.h +++ b/arch/alpha/include/asm/emergency-restart.h | |||
diff --git a/include/asm-alpha/err_common.h b/arch/alpha/include/asm/err_common.h index c25095942107..c25095942107 100644 --- a/include/asm-alpha/err_common.h +++ b/arch/alpha/include/asm/err_common.h | |||
diff --git a/include/asm-alpha/err_ev6.h b/arch/alpha/include/asm/err_ev6.h index ea637791e4a9..ea637791e4a9 100644 --- a/include/asm-alpha/err_ev6.h +++ b/arch/alpha/include/asm/err_ev6.h | |||
diff --git a/include/asm-alpha/err_ev7.h b/arch/alpha/include/asm/err_ev7.h index 87f99777c2e4..87f99777c2e4 100644 --- a/include/asm-alpha/err_ev7.h +++ b/arch/alpha/include/asm/err_ev7.h | |||
diff --git a/include/asm-alpha/errno.h b/arch/alpha/include/asm/errno.h index 69e2655249d2..69e2655249d2 100644 --- a/include/asm-alpha/errno.h +++ b/arch/alpha/include/asm/errno.h | |||
diff --git a/include/asm-alpha/fb.h b/arch/alpha/include/asm/fb.h index fa9bbb96b2b3..fa9bbb96b2b3 100644 --- a/include/asm-alpha/fb.h +++ b/arch/alpha/include/asm/fb.h | |||
diff --git a/include/asm-alpha/fcntl.h b/arch/alpha/include/asm/fcntl.h index 25da0017ec87..25da0017ec87 100644 --- a/include/asm-alpha/fcntl.h +++ b/arch/alpha/include/asm/fcntl.h | |||
diff --git a/include/asm-alpha/floppy.h b/arch/alpha/include/asm/floppy.h index 0be50413b2b5..0be50413b2b5 100644 --- a/include/asm-alpha/floppy.h +++ b/arch/alpha/include/asm/floppy.h | |||
diff --git a/include/asm-alpha/fpu.h b/arch/alpha/include/asm/fpu.h index ecb17a72acc3..ecb17a72acc3 100644 --- a/include/asm-alpha/fpu.h +++ b/arch/alpha/include/asm/fpu.h | |||
diff --git a/include/asm-alpha/futex.h b/arch/alpha/include/asm/futex.h index 6a332a9f099c..6a332a9f099c 100644 --- a/include/asm-alpha/futex.h +++ b/arch/alpha/include/asm/futex.h | |||
diff --git a/include/asm-alpha/gct.h b/arch/alpha/include/asm/gct.h index 3504c704927c..3504c704927c 100644 --- a/include/asm-alpha/gct.h +++ b/arch/alpha/include/asm/gct.h | |||
diff --git a/include/asm-alpha/gentrap.h b/arch/alpha/include/asm/gentrap.h index ae50cc3192c7..ae50cc3192c7 100644 --- a/include/asm-alpha/gentrap.h +++ b/arch/alpha/include/asm/gentrap.h | |||
diff --git a/include/asm-alpha/hardirq.h b/arch/alpha/include/asm/hardirq.h index d953e234daa8..d953e234daa8 100644 --- a/include/asm-alpha/hardirq.h +++ b/arch/alpha/include/asm/hardirq.h | |||
diff --git a/include/asm-alpha/hw_irq.h b/arch/alpha/include/asm/hw_irq.h index a37db0f95092..a37db0f95092 100644 --- a/include/asm-alpha/hw_irq.h +++ b/arch/alpha/include/asm/hw_irq.h | |||
diff --git a/include/asm-alpha/hwrpb.h b/arch/alpha/include/asm/hwrpb.h index 8e8f871af7cf..8e8f871af7cf 100644 --- a/include/asm-alpha/hwrpb.h +++ b/arch/alpha/include/asm/hwrpb.h | |||
diff --git a/include/asm-alpha/io.h b/arch/alpha/include/asm/io.h index e971ab000f95..e971ab000f95 100644 --- a/include/asm-alpha/io.h +++ b/arch/alpha/include/asm/io.h | |||
diff --git a/include/asm-alpha/io_trivial.h b/arch/alpha/include/asm/io_trivial.h index 1c77f10b4b36..1c77f10b4b36 100644 --- a/include/asm-alpha/io_trivial.h +++ b/arch/alpha/include/asm/io_trivial.h | |||
diff --git a/include/asm-alpha/ioctl.h b/arch/alpha/include/asm/ioctl.h index fc63727f4178..fc63727f4178 100644 --- a/include/asm-alpha/ioctl.h +++ b/arch/alpha/include/asm/ioctl.h | |||
diff --git a/include/asm-alpha/ioctls.h b/arch/alpha/include/asm/ioctls.h index 67bb9f6fdbe4..67bb9f6fdbe4 100644 --- a/include/asm-alpha/ioctls.h +++ b/arch/alpha/include/asm/ioctls.h | |||
diff --git a/include/asm-alpha/ipcbuf.h b/arch/alpha/include/asm/ipcbuf.h index d9c0e1a50702..d9c0e1a50702 100644 --- a/include/asm-alpha/ipcbuf.h +++ b/arch/alpha/include/asm/ipcbuf.h | |||
diff --git a/include/asm-alpha/irq.h b/arch/alpha/include/asm/irq.h index 06377400dc09..06377400dc09 100644 --- a/include/asm-alpha/irq.h +++ b/arch/alpha/include/asm/irq.h | |||
diff --git a/include/asm-alpha/irq_regs.h b/arch/alpha/include/asm/irq_regs.h index 3dd9c0b70270..3dd9c0b70270 100644 --- a/include/asm-alpha/irq_regs.h +++ b/arch/alpha/include/asm/irq_regs.h | |||
diff --git a/include/asm-alpha/jensen.h b/arch/alpha/include/asm/jensen.h index 964b06ead43b..964b06ead43b 100644 --- a/include/asm-alpha/jensen.h +++ b/arch/alpha/include/asm/jensen.h | |||
diff --git a/include/asm-alpha/kdebug.h b/arch/alpha/include/asm/kdebug.h index 6ece1b037665..6ece1b037665 100644 --- a/include/asm-alpha/kdebug.h +++ b/arch/alpha/include/asm/kdebug.h | |||
diff --git a/include/asm-alpha/kmap_types.h b/arch/alpha/include/asm/kmap_types.h index 3e6735a34c57..3e6735a34c57 100644 --- a/include/asm-alpha/kmap_types.h +++ b/arch/alpha/include/asm/kmap_types.h | |||
diff --git a/include/asm-alpha/linkage.h b/arch/alpha/include/asm/linkage.h index 291c2d01c44f..291c2d01c44f 100644 --- a/include/asm-alpha/linkage.h +++ b/arch/alpha/include/asm/linkage.h | |||
diff --git a/include/asm-alpha/local.h b/arch/alpha/include/asm/local.h index 6ad3ea696421..6ad3ea696421 100644 --- a/include/asm-alpha/local.h +++ b/arch/alpha/include/asm/local.h | |||
diff --git a/include/asm-alpha/machvec.h b/arch/alpha/include/asm/machvec.h index a86c083cdf7f..a86c083cdf7f 100644 --- a/include/asm-alpha/machvec.h +++ b/arch/alpha/include/asm/machvec.h | |||
diff --git a/include/asm-alpha/mc146818rtc.h b/arch/alpha/include/asm/mc146818rtc.h index 097703f1c8cb..097703f1c8cb 100644 --- a/include/asm-alpha/mc146818rtc.h +++ b/arch/alpha/include/asm/mc146818rtc.h | |||
diff --git a/include/asm-alpha/md.h b/arch/alpha/include/asm/md.h index 6c9b8222a4f2..6c9b8222a4f2 100644 --- a/include/asm-alpha/md.h +++ b/arch/alpha/include/asm/md.h | |||
diff --git a/include/asm-alpha/mman.h b/arch/alpha/include/asm/mman.h index 90d7c35d2867..90d7c35d2867 100644 --- a/include/asm-alpha/mman.h +++ b/arch/alpha/include/asm/mman.h | |||
diff --git a/include/asm-alpha/mmu.h b/arch/alpha/include/asm/mmu.h index 3dc127779329..3dc127779329 100644 --- a/include/asm-alpha/mmu.h +++ b/arch/alpha/include/asm/mmu.h | |||
diff --git a/include/asm-alpha/mmu_context.h b/arch/alpha/include/asm/mmu_context.h index 86c08a02d239..86c08a02d239 100644 --- a/include/asm-alpha/mmu_context.h +++ b/arch/alpha/include/asm/mmu_context.h | |||
diff --git a/include/asm-alpha/mmzone.h b/arch/alpha/include/asm/mmzone.h index 8af56ce346ad..8af56ce346ad 100644 --- a/include/asm-alpha/mmzone.h +++ b/arch/alpha/include/asm/mmzone.h | |||
diff --git a/include/asm-alpha/module.h b/arch/alpha/include/asm/module.h index 7b63743c534a..7b63743c534a 100644 --- a/include/asm-alpha/module.h +++ b/arch/alpha/include/asm/module.h | |||
diff --git a/include/asm-alpha/msgbuf.h b/arch/alpha/include/asm/msgbuf.h index 98496501a2bb..98496501a2bb 100644 --- a/include/asm-alpha/msgbuf.h +++ b/arch/alpha/include/asm/msgbuf.h | |||
diff --git a/include/asm-alpha/mutex.h b/arch/alpha/include/asm/mutex.h index 458c1f7fbc18..458c1f7fbc18 100644 --- a/include/asm-alpha/mutex.h +++ b/arch/alpha/include/asm/mutex.h | |||
diff --git a/include/asm-alpha/page.h b/arch/alpha/include/asm/page.h index 0995f9d13417..0995f9d13417 100644 --- a/include/asm-alpha/page.h +++ b/arch/alpha/include/asm/page.h | |||
diff --git a/include/asm-alpha/pal.h b/arch/alpha/include/asm/pal.h index 9b4ba0d6f00b..9b4ba0d6f00b 100644 --- a/include/asm-alpha/pal.h +++ b/arch/alpha/include/asm/pal.h | |||
diff --git a/include/asm-alpha/param.h b/arch/alpha/include/asm/param.h index e691ecfedb2c..e691ecfedb2c 100644 --- a/include/asm-alpha/param.h +++ b/arch/alpha/include/asm/param.h | |||
diff --git a/include/asm-alpha/parport.h b/arch/alpha/include/asm/parport.h index c5ee7cbb2fcd..c5ee7cbb2fcd 100644 --- a/include/asm-alpha/parport.h +++ b/arch/alpha/include/asm/parport.h | |||
diff --git a/include/asm-alpha/pci.h b/arch/alpha/include/asm/pci.h index 2a14302c17a3..2a14302c17a3 100644 --- a/include/asm-alpha/pci.h +++ b/arch/alpha/include/asm/pci.h | |||
diff --git a/include/asm-alpha/percpu.h b/arch/alpha/include/asm/percpu.h index 3495e8e00d70..3495e8e00d70 100644 --- a/include/asm-alpha/percpu.h +++ b/arch/alpha/include/asm/percpu.h | |||
diff --git a/include/asm-alpha/pgalloc.h b/arch/alpha/include/asm/pgalloc.h index fd090155dccd..fd090155dccd 100644 --- a/include/asm-alpha/pgalloc.h +++ b/arch/alpha/include/asm/pgalloc.h | |||
diff --git a/include/asm-alpha/pgtable.h b/arch/alpha/include/asm/pgtable.h index 3f0c59f6d8aa..3f0c59f6d8aa 100644 --- a/include/asm-alpha/pgtable.h +++ b/arch/alpha/include/asm/pgtable.h | |||
diff --git a/include/asm-alpha/poll.h b/arch/alpha/include/asm/poll.h index c98509d3149e..c98509d3149e 100644 --- a/include/asm-alpha/poll.h +++ b/arch/alpha/include/asm/poll.h | |||
diff --git a/include/asm-alpha/posix_types.h b/arch/alpha/include/asm/posix_types.h index db167413300b..db167413300b 100644 --- a/include/asm-alpha/posix_types.h +++ b/arch/alpha/include/asm/posix_types.h | |||
diff --git a/include/asm-alpha/processor.h b/arch/alpha/include/asm/processor.h index 94afe5859301..94afe5859301 100644 --- a/include/asm-alpha/processor.h +++ b/arch/alpha/include/asm/processor.h | |||
diff --git a/include/asm-alpha/ptrace.h b/arch/alpha/include/asm/ptrace.h index 32c7a5cddd59..32c7a5cddd59 100644 --- a/include/asm-alpha/ptrace.h +++ b/arch/alpha/include/asm/ptrace.h | |||
diff --git a/include/asm-alpha/reg.h b/arch/alpha/include/asm/reg.h index 86ff916fb069..86ff916fb069 100644 --- a/include/asm-alpha/reg.h +++ b/arch/alpha/include/asm/reg.h | |||
diff --git a/include/asm-alpha/regdef.h b/arch/alpha/include/asm/regdef.h index 142df9c4f8b8..142df9c4f8b8 100644 --- a/include/asm-alpha/regdef.h +++ b/arch/alpha/include/asm/regdef.h | |||
diff --git a/include/asm-alpha/resource.h b/arch/alpha/include/asm/resource.h index c10874ff5973..c10874ff5973 100644 --- a/include/asm-alpha/resource.h +++ b/arch/alpha/include/asm/resource.h | |||
diff --git a/include/asm-alpha/rtc.h b/arch/alpha/include/asm/rtc.h index 4e854b1333eb..4e854b1333eb 100644 --- a/include/asm-alpha/rtc.h +++ b/arch/alpha/include/asm/rtc.h | |||
diff --git a/include/asm-alpha/rwsem.h b/arch/alpha/include/asm/rwsem.h index 1570c0b54336..1570c0b54336 100644 --- a/include/asm-alpha/rwsem.h +++ b/arch/alpha/include/asm/rwsem.h | |||
diff --git a/include/asm-alpha/scatterlist.h b/arch/alpha/include/asm/scatterlist.h index 440747ca6349..440747ca6349 100644 --- a/include/asm-alpha/scatterlist.h +++ b/arch/alpha/include/asm/scatterlist.h | |||
diff --git a/include/asm-alpha/sections.h b/arch/alpha/include/asm/sections.h index 43b40edd6e44..43b40edd6e44 100644 --- a/include/asm-alpha/sections.h +++ b/arch/alpha/include/asm/sections.h | |||
diff --git a/include/asm-alpha/segment.h b/arch/alpha/include/asm/segment.h index 0453d97daae7..0453d97daae7 100644 --- a/include/asm-alpha/segment.h +++ b/arch/alpha/include/asm/segment.h | |||
diff --git a/include/asm-alpha/sembuf.h b/arch/alpha/include/asm/sembuf.h index 7b38b1534784..7b38b1534784 100644 --- a/include/asm-alpha/sembuf.h +++ b/arch/alpha/include/asm/sembuf.h | |||
diff --git a/include/asm-alpha/serial.h b/arch/alpha/include/asm/serial.h index 9d263e8d8ccc..9d263e8d8ccc 100644 --- a/include/asm-alpha/serial.h +++ b/arch/alpha/include/asm/serial.h | |||
diff --git a/include/asm-alpha/setup.h b/arch/alpha/include/asm/setup.h index 2e023a4aa317..2e023a4aa317 100644 --- a/include/asm-alpha/setup.h +++ b/arch/alpha/include/asm/setup.h | |||
diff --git a/include/asm-alpha/sfp-machine.h b/arch/alpha/include/asm/sfp-machine.h index 5fe63afbd474..5fe63afbd474 100644 --- a/include/asm-alpha/sfp-machine.h +++ b/arch/alpha/include/asm/sfp-machine.h | |||
diff --git a/include/asm-alpha/shmbuf.h b/arch/alpha/include/asm/shmbuf.h index 37ee84f05085..37ee84f05085 100644 --- a/include/asm-alpha/shmbuf.h +++ b/arch/alpha/include/asm/shmbuf.h | |||
diff --git a/include/asm-alpha/shmparam.h b/arch/alpha/include/asm/shmparam.h index cc901d58aebb..cc901d58aebb 100644 --- a/include/asm-alpha/shmparam.h +++ b/arch/alpha/include/asm/shmparam.h | |||
diff --git a/include/asm-alpha/sigcontext.h b/arch/alpha/include/asm/sigcontext.h index 323cdb026198..323cdb026198 100644 --- a/include/asm-alpha/sigcontext.h +++ b/arch/alpha/include/asm/sigcontext.h | |||
diff --git a/include/asm-alpha/siginfo.h b/arch/alpha/include/asm/siginfo.h index 9822362a8424..9822362a8424 100644 --- a/include/asm-alpha/siginfo.h +++ b/arch/alpha/include/asm/siginfo.h | |||
diff --git a/include/asm-alpha/signal.h b/arch/alpha/include/asm/signal.h index 13c2305d35ef..13c2305d35ef 100644 --- a/include/asm-alpha/signal.h +++ b/arch/alpha/include/asm/signal.h | |||
diff --git a/include/asm-alpha/smp.h b/arch/alpha/include/asm/smp.h index 544c69af8168..544c69af8168 100644 --- a/include/asm-alpha/smp.h +++ b/arch/alpha/include/asm/smp.h | |||
diff --git a/include/asm-alpha/socket.h b/arch/alpha/include/asm/socket.h index a1057c2d95e7..a1057c2d95e7 100644 --- a/include/asm-alpha/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
diff --git a/include/asm-alpha/sockios.h b/arch/alpha/include/asm/sockios.h index 7932c7ab4a4d..7932c7ab4a4d 100644 --- a/include/asm-alpha/sockios.h +++ b/arch/alpha/include/asm/sockios.h | |||
diff --git a/include/asm-alpha/spinlock.h b/arch/alpha/include/asm/spinlock.h index aeeb125f6851..aeeb125f6851 100644 --- a/include/asm-alpha/spinlock.h +++ b/arch/alpha/include/asm/spinlock.h | |||
diff --git a/include/asm-alpha/spinlock_types.h b/arch/alpha/include/asm/spinlock_types.h index 8141eb5ebf0d..8141eb5ebf0d 100644 --- a/include/asm-alpha/spinlock_types.h +++ b/arch/alpha/include/asm/spinlock_types.h | |||
diff --git a/include/asm-alpha/stat.h b/arch/alpha/include/asm/stat.h index 07ad3e6b3f3e..07ad3e6b3f3e 100644 --- a/include/asm-alpha/stat.h +++ b/arch/alpha/include/asm/stat.h | |||
diff --git a/include/asm-alpha/statfs.h b/arch/alpha/include/asm/statfs.h index ad15830baefe..ad15830baefe 100644 --- a/include/asm-alpha/statfs.h +++ b/arch/alpha/include/asm/statfs.h | |||
diff --git a/include/asm-alpha/string.h b/arch/alpha/include/asm/string.h index b02b8a282940..b02b8a282940 100644 --- a/include/asm-alpha/string.h +++ b/arch/alpha/include/asm/string.h | |||
diff --git a/include/asm-alpha/suspend.h b/arch/alpha/include/asm/suspend.h index c7042d575851..c7042d575851 100644 --- a/include/asm-alpha/suspend.h +++ b/arch/alpha/include/asm/suspend.h | |||
diff --git a/include/asm-alpha/sysinfo.h b/arch/alpha/include/asm/sysinfo.h index 086aba284df2..086aba284df2 100644 --- a/include/asm-alpha/sysinfo.h +++ b/arch/alpha/include/asm/sysinfo.h | |||
diff --git a/include/asm-alpha/system.h b/arch/alpha/include/asm/system.h index afe20fa58c99..afe20fa58c99 100644 --- a/include/asm-alpha/system.h +++ b/arch/alpha/include/asm/system.h | |||
diff --git a/include/asm-alpha/termbits.h b/arch/alpha/include/asm/termbits.h index ad854a4a3af6..ad854a4a3af6 100644 --- a/include/asm-alpha/termbits.h +++ b/arch/alpha/include/asm/termbits.h | |||
diff --git a/include/asm-alpha/termios.h b/arch/alpha/include/asm/termios.h index fa13716a11c3..fa13716a11c3 100644 --- a/include/asm-alpha/termios.h +++ b/arch/alpha/include/asm/termios.h | |||
diff --git a/include/asm-alpha/thread_info.h b/arch/alpha/include/asm/thread_info.h index 15fda4344424..15fda4344424 100644 --- a/include/asm-alpha/thread_info.h +++ b/arch/alpha/include/asm/thread_info.h | |||
diff --git a/include/asm-alpha/timex.h b/arch/alpha/include/asm/timex.h index afa0c45e3e98..afa0c45e3e98 100644 --- a/include/asm-alpha/timex.h +++ b/arch/alpha/include/asm/timex.h | |||
diff --git a/include/asm-alpha/tlb.h b/arch/alpha/include/asm/tlb.h index c13636575fba..c13636575fba 100644 --- a/include/asm-alpha/tlb.h +++ b/arch/alpha/include/asm/tlb.h | |||
diff --git a/include/asm-alpha/tlbflush.h b/arch/alpha/include/asm/tlbflush.h index 9d87aaa08c0d..9d87aaa08c0d 100644 --- a/include/asm-alpha/tlbflush.h +++ b/arch/alpha/include/asm/tlbflush.h | |||
diff --git a/include/asm-alpha/topology.h b/arch/alpha/include/asm/topology.h index 149532e162c4..149532e162c4 100644 --- a/include/asm-alpha/topology.h +++ b/arch/alpha/include/asm/topology.h | |||
diff --git a/include/asm-alpha/types.h b/arch/alpha/include/asm/types.h index c1541353ccef..c1541353ccef 100644 --- a/include/asm-alpha/types.h +++ b/arch/alpha/include/asm/types.h | |||
diff --git a/include/asm-alpha/uaccess.h b/arch/alpha/include/asm/uaccess.h index 22de3b434a22..22de3b434a22 100644 --- a/include/asm-alpha/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h | |||
diff --git a/include/asm-alpha/ucontext.h b/arch/alpha/include/asm/ucontext.h index 47578ab42152..47578ab42152 100644 --- a/include/asm-alpha/ucontext.h +++ b/arch/alpha/include/asm/ucontext.h | |||
diff --git a/include/asm-alpha/unaligned.h b/arch/alpha/include/asm/unaligned.h index 3787c60aed3f..3787c60aed3f 100644 --- a/include/asm-alpha/unaligned.h +++ b/arch/alpha/include/asm/unaligned.h | |||
diff --git a/include/asm-alpha/unistd.h b/arch/alpha/include/asm/unistd.h index 5b5c17485942..5b5c17485942 100644 --- a/include/asm-alpha/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
diff --git a/include/asm-alpha/user.h b/arch/alpha/include/asm/user.h index a4eb6a4ca8d1..a4eb6a4ca8d1 100644 --- a/include/asm-alpha/user.h +++ b/arch/alpha/include/asm/user.h | |||
diff --git a/include/asm-alpha/vga.h b/arch/alpha/include/asm/vga.h index c00106bac521..c00106bac521 100644 --- a/include/asm-alpha/vga.h +++ b/arch/alpha/include/asm/vga.h | |||
diff --git a/include/asm-alpha/xor.h b/arch/alpha/include/asm/xor.h index 5ee1c2bc0499..5ee1c2bc0499 100644 --- a/include/asm-alpha/xor.h +++ b/arch/alpha/include/asm/xor.h | |||
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h index c8986bb99ed5..df15a0dc228e 100644 --- a/arch/arm/include/asm/kexec.h +++ b/arch/arm/include/asm/kexec.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | /* Maximum address we can use for the control code buffer */ | 10 | /* Maximum address we can use for the control code buffer */ |
| 11 | #define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) | 11 | #define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) |
| 12 | 12 | ||
| 13 | #define KEXEC_CONTROL_CODE_SIZE 4096 | 13 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 14 | 14 | ||
| 15 | #define KEXEC_ARCH KEXEC_ARCH_ARM | 15 | #define KEXEC_ARCH KEXEC_ARCH_ARM |
| 16 | 16 | ||
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index db8f54a3451f..fae5beb3c3d6 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c | |||
| @@ -71,7 +71,7 @@ void machine_kexec(struct kimage *image) | |||
| 71 | 71 | ||
| 72 | 72 | ||
| 73 | flush_icache_range((unsigned long) reboot_code_buffer, | 73 | flush_icache_range((unsigned long) reboot_code_buffer, |
| 74 | (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); | 74 | (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); |
| 75 | printk(KERN_INFO "Bye!\n"); | 75 | printk(KERN_INFO "Bye!\n"); |
| 76 | 76 | ||
| 77 | cpu_proc_fin(); | 77 | cpu_proc_fin(); |
diff --git a/arch/ia64/include/asm/kexec.h b/arch/ia64/include/asm/kexec.h index 541be835fc5a..e1d58f819d78 100644 --- a/arch/ia64/include/asm/kexec.h +++ b/arch/ia64/include/asm/kexec.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | /* Maximum address we can use for the control code buffer */ | 9 | /* Maximum address we can use for the control code buffer */ |
| 10 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | 10 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
| 11 | 11 | ||
| 12 | #define KEXEC_CONTROL_CODE_SIZE (8192 + 8192 + 4096) | 12 | #define KEXEC_CONTROL_PAGE_SIZE (8192 + 8192 + 4096) |
| 13 | 13 | ||
| 14 | /* The native architecture */ | 14 | /* The native architecture */ |
| 15 | #define KEXEC_ARCH KEXEC_ARCH_IA_64 | 15 | #define KEXEC_ARCH KEXEC_ARCH_IA_64 |
diff --git a/arch/powerpc/include/asm/kexec.h b/arch/powerpc/include/asm/kexec.h index acdcdc66f1b6..3736d9b33289 100644 --- a/arch/powerpc/include/asm/kexec.h +++ b/arch/powerpc/include/asm/kexec.h | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | 22 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
| 23 | #endif | 23 | #endif |
| 24 | 24 | ||
| 25 | #define KEXEC_CONTROL_CODE_SIZE 4096 | 25 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 26 | 26 | ||
| 27 | /* The native architecture */ | 27 | /* The native architecture */ |
| 28 | #ifdef __powerpc64__ | 28 | #ifdef __powerpc64__ |
diff --git a/arch/powerpc/kernel/machine_kexec_32.c b/arch/powerpc/kernel/machine_kexec_32.c index cbaa34196797..ae63a964b858 100644 --- a/arch/powerpc/kernel/machine_kexec_32.c +++ b/arch/powerpc/kernel/machine_kexec_32.c | |||
| @@ -51,7 +51,7 @@ void default_machine_kexec(struct kimage *image) | |||
| 51 | relocate_new_kernel_size); | 51 | relocate_new_kernel_size); |
| 52 | 52 | ||
| 53 | flush_icache_range(reboot_code_buffer, | 53 | flush_icache_range(reboot_code_buffer, |
| 54 | reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); | 54 | reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); |
| 55 | printk(KERN_INFO "Bye!\n"); | 55 | printk(KERN_INFO "Bye!\n"); |
| 56 | 56 | ||
| 57 | /* now call it */ | 57 | /* now call it */ |
diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h index f219c6411e0b..bb729b84a21e 100644 --- a/arch/s390/include/asm/kexec.h +++ b/arch/s390/include/asm/kexec.h | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31) | 31 | #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31) |
| 32 | 32 | ||
| 33 | /* Allocate one page for the pdp and the second for the code */ | 33 | /* Allocate one page for the pdp and the second for the code */ |
| 34 | #define KEXEC_CONTROL_CODE_SIZE 4096 | 34 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 35 | 35 | ||
| 36 | /* The native architecture */ | 36 | /* The native architecture */ |
| 37 | #define KEXEC_ARCH KEXEC_ARCH_S390 | 37 | #define KEXEC_ARCH KEXEC_ARCH_S390 |
diff --git a/arch/sh/include/asm/kexec.h b/arch/sh/include/asm/kexec.h index 00f4260ef09b..765a5e1660fc 100644 --- a/arch/sh/include/asm/kexec.h +++ b/arch/sh/include/asm/kexec.h | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | /* Maximum address we can use for the control code buffer */ | 21 | /* Maximum address we can use for the control code buffer */ |
| 22 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | 22 | #define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
| 23 | 23 | ||
| 24 | #define KEXEC_CONTROL_CODE_SIZE 4096 | 24 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 25 | 25 | ||
| 26 | /* The native architecture */ | 26 | /* The native architecture */ |
| 27 | #define KEXEC_ARCH KEXEC_ARCH_SH | 27 | #define KEXEC_ARCH KEXEC_ARCH_SH |
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 9fe478d98406..0732adba05ca 100644 --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/numa.h> | 13 | #include <linux/numa.h> |
| 14 | #include <linux/ftrace.h> | 14 | #include <linux/ftrace.h> |
| 15 | #include <linux/suspend.h> | ||
| 15 | 16 | ||
| 16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
| 17 | #include <asm/pgalloc.h> | 18 | #include <asm/pgalloc.h> |
| @@ -78,7 +79,7 @@ static void load_segments(void) | |||
| 78 | /* | 79 | /* |
| 79 | * A architecture hook called to validate the | 80 | * A architecture hook called to validate the |
| 80 | * proposed image and prepare the control pages | 81 | * proposed image and prepare the control pages |
| 81 | * as needed. The pages for KEXEC_CONTROL_CODE_SIZE | 82 | * as needed. The pages for KEXEC_CONTROL_PAGE_SIZE |
| 82 | * have been allocated, but the segments have yet | 83 | * have been allocated, but the segments have yet |
| 83 | * been copied into the kernel. | 84 | * been copied into the kernel. |
| 84 | * | 85 | * |
| @@ -113,6 +114,7 @@ void machine_kexec(struct kimage *image) | |||
| 113 | { | 114 | { |
| 114 | unsigned long page_list[PAGES_NR]; | 115 | unsigned long page_list[PAGES_NR]; |
| 115 | void *control_page; | 116 | void *control_page; |
| 117 | int save_ftrace_enabled; | ||
| 116 | asmlinkage unsigned long | 118 | asmlinkage unsigned long |
| 117 | (*relocate_kernel_ptr)(unsigned long indirection_page, | 119 | (*relocate_kernel_ptr)(unsigned long indirection_page, |
| 118 | unsigned long control_page, | 120 | unsigned long control_page, |
| @@ -120,7 +122,12 @@ void machine_kexec(struct kimage *image) | |||
| 120 | unsigned int has_pae, | 122 | unsigned int has_pae, |
| 121 | unsigned int preserve_context); | 123 | unsigned int preserve_context); |
| 122 | 124 | ||
| 123 | tracer_disable(); | 125 | #ifdef CONFIG_KEXEC_JUMP |
| 126 | if (kexec_image->preserve_context) | ||
| 127 | save_processor_state(); | ||
| 128 | #endif | ||
| 129 | |||
| 130 | save_ftrace_enabled = __ftrace_enabled_save(); | ||
| 124 | 131 | ||
| 125 | /* Interrupts aren't acceptable while we reboot */ | 132 | /* Interrupts aren't acceptable while we reboot */ |
| 126 | local_irq_disable(); | 133 | local_irq_disable(); |
| @@ -138,7 +145,7 @@ void machine_kexec(struct kimage *image) | |||
| 138 | } | 145 | } |
| 139 | 146 | ||
| 140 | control_page = page_address(image->control_code_page); | 147 | control_page = page_address(image->control_code_page); |
| 141 | memcpy(control_page, relocate_kernel, PAGE_SIZE/2); | 148 | memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); |
| 142 | 149 | ||
| 143 | relocate_kernel_ptr = control_page; | 150 | relocate_kernel_ptr = control_page; |
| 144 | page_list[PA_CONTROL_PAGE] = __pa(control_page); | 151 | page_list[PA_CONTROL_PAGE] = __pa(control_page); |
| @@ -178,6 +185,13 @@ void machine_kexec(struct kimage *image) | |||
| 178 | (unsigned long)page_list, | 185 | (unsigned long)page_list, |
| 179 | image->start, cpu_has_pae, | 186 | image->start, cpu_has_pae, |
| 180 | image->preserve_context); | 187 | image->preserve_context); |
| 188 | |||
| 189 | #ifdef CONFIG_KEXEC_JUMP | ||
| 190 | if (kexec_image->preserve_context) | ||
| 191 | restore_processor_state(); | ||
| 192 | #endif | ||
| 193 | |||
| 194 | __ftrace_enabled_restore(save_ftrace_enabled); | ||
| 181 | } | 195 | } |
| 182 | 196 | ||
| 183 | void arch_crash_save_vmcoreinfo(void) | 197 | void arch_crash_save_vmcoreinfo(void) |
diff --git a/arch/x86/kernel/relocate_kernel_32.S b/arch/x86/kernel/relocate_kernel_32.S index 703310a99023..6f50664b2ba5 100644 --- a/arch/x86/kernel/relocate_kernel_32.S +++ b/arch/x86/kernel/relocate_kernel_32.S | |||
| @@ -20,10 +20,11 @@ | |||
| 20 | #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) | 20 | #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) |
| 21 | #define PAE_PGD_ATTR (_PAGE_PRESENT) | 21 | #define PAE_PGD_ATTR (_PAGE_PRESENT) |
| 22 | 22 | ||
| 23 | /* control_page + PAGE_SIZE/2 ~ control_page + PAGE_SIZE * 3/4 are | 23 | /* control_page + KEXEC_CONTROL_CODE_MAX_SIZE |
| 24 | * used to save some data for jumping back | 24 | * ~ control_page + PAGE_SIZE are used as data storage and stack for |
| 25 | * jumping back | ||
| 25 | */ | 26 | */ |
| 26 | #define DATA(offset) (PAGE_SIZE/2+(offset)) | 27 | #define DATA(offset) (KEXEC_CONTROL_CODE_MAX_SIZE+(offset)) |
| 27 | 28 | ||
| 28 | /* Minimal CPU state */ | 29 | /* Minimal CPU state */ |
| 29 | #define ESP DATA(0x0) | 30 | #define ESP DATA(0x0) |
| @@ -376,3 +377,6 @@ swap_pages: | |||
| 376 | popl %ebx | 377 | popl %ebx |
| 377 | popl %ebp | 378 | popl %ebp |
| 378 | ret | 379 | ret |
| 380 | |||
| 381 | .globl kexec_control_code_size | ||
| 382 | .set kexec_control_code_size, . - relocate_kernel | ||
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S index cdb2363697d2..af5bdad84604 100644 --- a/arch/x86/kernel/vmlinux_32.lds.S +++ b/arch/x86/kernel/vmlinux_32.lds.S | |||
| @@ -209,3 +209,11 @@ SECTIONS | |||
| 209 | 209 | ||
| 210 | DWARF_DEBUG | 210 | DWARF_DEBUG |
| 211 | } | 211 | } |
| 212 | |||
| 213 | #ifdef CONFIG_KEXEC | ||
| 214 | /* Link time checks */ | ||
| 215 | #include <asm/kexec.h> | ||
| 216 | |||
| 217 | ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, | ||
| 218 | "kexec control code size is too big") | ||
| 219 | #endif | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0e6866fe0f96..a27160ba21d7 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -2496,45 +2496,25 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg) | |||
| 2496 | } | 2496 | } |
| 2497 | 2497 | ||
| 2498 | /** | 2498 | /** |
| 2499 | * tiocswinsz - implement window size set ioctl | 2499 | * tty_do_resize - resize event |
| 2500 | * @tty; tty | 2500 | * @tty: tty being resized |
| 2501 | * @arg: user buffer for result | 2501 | * @real_tty: real tty (if using a pty/tty pair) |
| 2502 | * @rows: rows (character) | ||
| 2503 | * @cols: cols (character) | ||
| 2502 | * | 2504 | * |
| 2503 | * Copies the user idea of the window size to the kernel. Traditionally | 2505 | * Update the termios variables and send the neccessary signals to |
| 2504 | * this is just advisory information but for the Linux console it | 2506 | * peform a terminal resize correctly |
| 2505 | * actually has driver level meaning and triggers a VC resize. | ||
| 2506 | * | ||
| 2507 | * Locking: | ||
| 2508 | * Called function use the console_sem is used to ensure we do | ||
| 2509 | * not try and resize the console twice at once. | ||
| 2510 | * The tty->termios_mutex is used to ensure we don't double | ||
| 2511 | * resize and get confused. Lock order - tty->termios_mutex before | ||
| 2512 | * console sem | ||
| 2513 | */ | 2507 | */ |
| 2514 | 2508 | ||
| 2515 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | 2509 | int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, |
| 2516 | struct winsize __user *arg) | 2510 | struct winsize *ws) |
| 2517 | { | 2511 | { |
| 2518 | struct winsize tmp_ws; | ||
| 2519 | struct pid *pgrp, *rpgrp; | 2512 | struct pid *pgrp, *rpgrp; |
| 2520 | unsigned long flags; | 2513 | unsigned long flags; |
| 2521 | 2514 | ||
| 2522 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | ||
| 2523 | return -EFAULT; | ||
| 2524 | |||
| 2525 | mutex_lock(&tty->termios_mutex); | 2515 | mutex_lock(&tty->termios_mutex); |
| 2526 | if (!memcmp(&tmp_ws, &tty->winsize, sizeof(*arg))) | 2516 | if (!memcmp(ws, &tty->winsize, sizeof(*ws))) |
| 2527 | goto done; | 2517 | goto done; |
| 2528 | |||
| 2529 | #ifdef CONFIG_VT | ||
| 2530 | if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) { | ||
| 2531 | if (vc_lock_resize(tty->driver_data, tmp_ws.ws_col, | ||
| 2532 | tmp_ws.ws_row)) { | ||
| 2533 | mutex_unlock(&tty->termios_mutex); | ||
| 2534 | return -ENXIO; | ||
| 2535 | } | ||
| 2536 | } | ||
| 2537 | #endif | ||
| 2538 | /* Get the PID values and reference them so we can | 2518 | /* Get the PID values and reference them so we can |
| 2539 | avoid holding the tty ctrl lock while sending signals */ | 2519 | avoid holding the tty ctrl lock while sending signals */ |
| 2540 | spin_lock_irqsave(&tty->ctrl_lock, flags); | 2520 | spin_lock_irqsave(&tty->ctrl_lock, flags); |
| @@ -2550,14 +2530,42 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
| 2550 | put_pid(pgrp); | 2530 | put_pid(pgrp); |
| 2551 | put_pid(rpgrp); | 2531 | put_pid(rpgrp); |
| 2552 | 2532 | ||
| 2553 | tty->winsize = tmp_ws; | 2533 | tty->winsize = *ws; |
| 2554 | real_tty->winsize = tmp_ws; | 2534 | real_tty->winsize = *ws; |
| 2555 | done: | 2535 | done: |
| 2556 | mutex_unlock(&tty->termios_mutex); | 2536 | mutex_unlock(&tty->termios_mutex); |
| 2557 | return 0; | 2537 | return 0; |
| 2558 | } | 2538 | } |
| 2559 | 2539 | ||
| 2560 | /** | 2540 | /** |
| 2541 | * tiocswinsz - implement window size set ioctl | ||
| 2542 | * @tty; tty | ||
| 2543 | * @arg: user buffer for result | ||
| 2544 | * | ||
| 2545 | * Copies the user idea of the window size to the kernel. Traditionally | ||
| 2546 | * this is just advisory information but for the Linux console it | ||
| 2547 | * actually has driver level meaning and triggers a VC resize. | ||
| 2548 | * | ||
| 2549 | * Locking: | ||
| 2550 | * Driver dependant. The default do_resize method takes the | ||
| 2551 | * tty termios mutex and ctrl_lock. The console takes its own lock | ||
| 2552 | * then calls into the default method. | ||
| 2553 | */ | ||
| 2554 | |||
| 2555 | static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 2556 | struct winsize __user *arg) | ||
| 2557 | { | ||
| 2558 | struct winsize tmp_ws; | ||
| 2559 | if (copy_from_user(&tmp_ws, arg, sizeof(*arg))) | ||
| 2560 | return -EFAULT; | ||
| 2561 | |||
| 2562 | if (tty->ops->resize) | ||
| 2563 | return tty->ops->resize(tty, real_tty, &tmp_ws); | ||
| 2564 | else | ||
| 2565 | return tty_do_resize(tty, real_tty, &tmp_ws); | ||
| 2566 | } | ||
| 2567 | |||
| 2568 | /** | ||
| 2561 | * tioccons - allow admin to move logical console | 2569 | * tioccons - allow admin to move logical console |
| 2562 | * @file: the file to become console | 2570 | * @file: the file to become console |
| 2563 | * | 2571 | * |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 1bc00c9d860d..60359c360912 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
| @@ -803,7 +803,25 @@ static inline int resize_screen(struct vc_data *vc, int width, int height, | |||
| 803 | */ | 803 | */ |
| 804 | #define VC_RESIZE_MAXCOL (32767) | 804 | #define VC_RESIZE_MAXCOL (32767) |
| 805 | #define VC_RESIZE_MAXROW (32767) | 805 | #define VC_RESIZE_MAXROW (32767) |
| 806 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | 806 | |
| 807 | /** | ||
| 808 | * vc_do_resize - resizing method for the tty | ||
| 809 | * @tty: tty being resized | ||
| 810 | * @real_tty: real tty (different to tty if a pty/tty pair) | ||
| 811 | * @vc: virtual console private data | ||
| 812 | * @cols: columns | ||
| 813 | * @lines: lines | ||
| 814 | * | ||
| 815 | * Resize a virtual console, clipping according to the actual constraints. | ||
| 816 | * If the caller passes a tty structure then update the termios winsize | ||
| 817 | * information and perform any neccessary signal handling. | ||
| 818 | * | ||
| 819 | * Caller must hold the console semaphore. Takes the termios mutex and | ||
| 820 | * ctrl_lock of the tty IFF a tty is passed. | ||
| 821 | */ | ||
| 822 | |||
| 823 | static int vc_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 824 | struct vc_data *vc, unsigned int cols, unsigned int lines) | ||
| 807 | { | 825 | { |
| 808 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; | 826 | unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; |
| 809 | unsigned int old_cols, old_rows, old_row_size, old_screen_size; | 827 | unsigned int old_cols, old_rows, old_row_size, old_screen_size; |
| @@ -907,24 +925,15 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
| 907 | gotoxy(vc, vc->vc_x, vc->vc_y); | 925 | gotoxy(vc, vc->vc_x, vc->vc_y); |
| 908 | save_cur(vc); | 926 | save_cur(vc); |
| 909 | 927 | ||
| 910 | if (vc->vc_tty) { | 928 | if (tty) { |
| 911 | struct winsize ws, *cws = &vc->vc_tty->winsize; | 929 | /* Rewrite the requested winsize data with the actual |
| 912 | struct pid *pgrp = NULL; | 930 | resulting sizes */ |
| 913 | 931 | struct winsize ws; | |
| 914 | memset(&ws, 0, sizeof(ws)); | 932 | memset(&ws, 0, sizeof(ws)); |
| 915 | ws.ws_row = vc->vc_rows; | 933 | ws.ws_row = vc->vc_rows; |
| 916 | ws.ws_col = vc->vc_cols; | 934 | ws.ws_col = vc->vc_cols; |
| 917 | ws.ws_ypixel = vc->vc_scan_lines; | 935 | ws.ws_ypixel = vc->vc_scan_lines; |
| 918 | 936 | tty_do_resize(tty, real_tty, &ws); | |
| 919 | spin_lock_irq(&vc->vc_tty->ctrl_lock); | ||
| 920 | if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) | ||
| 921 | pgrp = get_pid(vc->vc_tty->pgrp); | ||
| 922 | spin_unlock_irq(&vc->vc_tty->ctrl_lock); | ||
| 923 | if (pgrp) { | ||
| 924 | kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); | ||
| 925 | put_pid(pgrp); | ||
| 926 | } | ||
| 927 | *cws = ws; | ||
| 928 | } | 937 | } |
| 929 | 938 | ||
| 930 | if (CON_IS_VISIBLE(vc)) | 939 | if (CON_IS_VISIBLE(vc)) |
| @@ -932,14 +941,47 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | |||
| 932 | return err; | 941 | return err; |
| 933 | } | 942 | } |
| 934 | 943 | ||
| 935 | int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) | 944 | /** |
| 945 | * vc_resize - resize a VT | ||
| 946 | * @vc: virtual console | ||
| 947 | * @cols: columns | ||
| 948 | * @rows: rows | ||
| 949 | * | ||
| 950 | * Resize a virtual console as seen from the console end of things. We | ||
| 951 | * use the common vc_do_resize methods to update the structures. The | ||
| 952 | * caller must hold the console sem to protect console internals and | ||
| 953 | * vc->vc_tty | ||
| 954 | */ | ||
| 955 | |||
| 956 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) | ||
| 957 | { | ||
| 958 | return vc_do_resize(vc->vc_tty, vc->vc_tty, vc, cols, rows); | ||
| 959 | } | ||
| 960 | |||
| 961 | /** | ||
| 962 | * vt_resize - resize a VT | ||
| 963 | * @tty: tty to resize | ||
| 964 | * @real_tty: tty if a pty/tty pair | ||
| 965 | * @ws: winsize attributes | ||
| 966 | * | ||
| 967 | * Resize a virtual terminal. This is called by the tty layer as we | ||
| 968 | * register our own handler for resizing. The mutual helper does all | ||
| 969 | * the actual work. | ||
| 970 | * | ||
| 971 | * Takes the console sem and the called methods then take the tty | ||
| 972 | * termios_mutex and the tty ctrl_lock in that order. | ||
| 973 | */ | ||
| 974 | |||
| 975 | int vt_resize(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 976 | struct winsize *ws) | ||
| 936 | { | 977 | { |
| 937 | int rc; | 978 | struct vc_data *vc = tty->driver_data; |
| 979 | int ret; | ||
| 938 | 980 | ||
| 939 | acquire_console_sem(); | 981 | acquire_console_sem(); |
| 940 | rc = vc_resize(vc, cols, lines); | 982 | ret = vc_do_resize(tty, real_tty, vc, ws->ws_col, ws->ws_row); |
| 941 | release_console_sem(); | 983 | release_console_sem(); |
| 942 | return rc; | 984 | return ret; |
| 943 | } | 985 | } |
| 944 | 986 | ||
| 945 | void vc_deallocate(unsigned int currcons) | 987 | void vc_deallocate(unsigned int currcons) |
| @@ -2907,6 +2949,7 @@ static const struct tty_operations con_ops = { | |||
| 2907 | .start = con_start, | 2949 | .start = con_start, |
| 2908 | .throttle = con_throttle, | 2950 | .throttle = con_throttle, |
| 2909 | .unthrottle = con_unthrottle, | 2951 | .unthrottle = con_unthrottle, |
| 2952 | .resize = vt_resize, | ||
| 2910 | }; | 2953 | }; |
| 2911 | 2954 | ||
| 2912 | int __init vty_init(void) | 2955 | int __init vty_init(void) |
| @@ -4061,7 +4104,6 @@ EXPORT_SYMBOL(default_blu); | |||
| 4061 | EXPORT_SYMBOL(update_region); | 4104 | EXPORT_SYMBOL(update_region); |
| 4062 | EXPORT_SYMBOL(redraw_screen); | 4105 | EXPORT_SYMBOL(redraw_screen); |
| 4063 | EXPORT_SYMBOL(vc_resize); | 4106 | EXPORT_SYMBOL(vc_resize); |
| 4064 | EXPORT_SYMBOL(vc_lock_resize); | ||
| 4065 | EXPORT_SYMBOL(fg_console); | 4107 | EXPORT_SYMBOL(fg_console); |
| 4066 | EXPORT_SYMBOL(console_blank_hook); | 4108 | EXPORT_SYMBOL(console_blank_hook); |
| 4067 | EXPORT_SYMBOL(console_blanked); | 4109 | EXPORT_SYMBOL(console_blanked); |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 3211afd9d57e..c904e9ad4a71 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
| @@ -947,14 +947,16 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, | |||
| 947 | get_user(cc, &vtsizes->v_cols)) | 947 | get_user(cc, &vtsizes->v_cols)) |
| 948 | ret = -EFAULT; | 948 | ret = -EFAULT; |
| 949 | else { | 949 | else { |
| 950 | acquire_console_sem(); | ||
| 950 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 951 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
| 951 | vc = vc_cons[i].d; | 952 | vc = vc_cons[i].d; |
| 952 | 953 | ||
| 953 | if (vc) { | 954 | if (vc) { |
| 954 | vc->vc_resize_user = 1; | 955 | vc->vc_resize_user = 1; |
| 955 | vc_lock_resize(vc_cons[i].d, cc, ll); | 956 | vc_resize(vc_cons[i].d, cc, ll); |
| 956 | } | 957 | } |
| 957 | } | 958 | } |
| 959 | release_console_sem(); | ||
| 958 | } | 960 | } |
| 959 | break; | 961 | break; |
| 960 | } | 962 | } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 61e78a4369b9..b15f88249639 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
| @@ -654,12 +654,12 @@ static const struct hid_blacklist { | |||
| 654 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, | 654 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
| 655 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 655 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
| 656 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, | 656 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN }, |
| 657 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN }, | 657 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
| 658 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 658 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE}, |
| 659 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN }, | 659 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE}, |
| 660 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN }, | 660 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE}, |
| 661 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, | 661 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE }, |
| 662 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN }, | 662 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
| 663 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 663 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
| 664 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 664 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
| 665 | 665 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index bf4ebfb86fa5..d402e8d813ce 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -77,6 +77,22 @@ config SENSORS_AD7418 | |||
| 77 | This driver can also be built as a module. If so, the module | 77 | This driver can also be built as a module. If so, the module |
| 78 | will be called ad7418. | 78 | will be called ad7418. |
| 79 | 79 | ||
| 80 | config SENSORS_ADCXX | ||
| 81 | tristate "National Semiconductor ADCxxxSxxx" | ||
| 82 | depends on SPI_MASTER && EXPERIMENTAL | ||
| 83 | help | ||
| 84 | If you say yes here you get support for the National Semiconductor | ||
| 85 | ADC<bb><c>S<sss> chip family, where | ||
| 86 | * bb is the resolution in number of bits (8, 10, 12) | ||
| 87 | * c is the number of channels (1, 2, 4, 8) | ||
| 88 | * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500 | ||
| 89 | kSPS and 101 for 1 MSPS) | ||
| 90 | |||
| 91 | Examples : ADC081S101, ADC124S501, ... | ||
| 92 | |||
| 93 | This driver can also be built as a module. If so, the module | ||
| 94 | will be called adcxx. | ||
| 95 | |||
| 80 | config SENSORS_ADM1021 | 96 | config SENSORS_ADM1021 |
| 81 | tristate "Analog Devices ADM1021 and compatibles" | 97 | tristate "Analog Devices ADM1021 and compatibles" |
| 82 | depends on I2C | 98 | depends on I2C |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 7943e5cefb06..950134ab8426 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -17,6 +17,7 @@ obj-$(CONFIG_SENSORS_ABITUGURU) += abituguru.o | |||
| 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o | 17 | obj-$(CONFIG_SENSORS_ABITUGURU3)+= abituguru3.o |
| 18 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o | 18 | obj-$(CONFIG_SENSORS_AD7414) += ad7414.o |
| 19 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o | 19 | obj-$(CONFIG_SENSORS_AD7418) += ad7418.o |
| 20 | obj-$(CONFIG_SENSORS_ADCXX) += adcxx.o | ||
| 20 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o | 21 | obj-$(CONFIG_SENSORS_ADM1021) += adm1021.o |
| 21 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o | 22 | obj-$(CONFIG_SENSORS_ADM1025) += adm1025.o |
| 22 | obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o | 23 | obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index f00f497b9ca9..d568c65c1370 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | abituguru3.c Copyright (c) 2006 Hans de Goede <j.w.r.degoede@hhs.nl> | 2 | abituguru3.c |
| 3 | |||
| 4 | Copyright (c) 2006-2008 Hans de Goede <j.w.r.degoede@hhs.nl> | ||
| 5 | Copyright (c) 2008 Alistair John Strachan <alistair@devzero.co.uk> | ||
| 3 | 6 | ||
| 4 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 8 | it under the terms of the GNU General Public License as published by |
| @@ -116,7 +119,7 @@ struct abituguru3_sensor_info { | |||
| 116 | 119 | ||
| 117 | struct abituguru3_motherboard_info { | 120 | struct abituguru3_motherboard_info { |
| 118 | u16 id; | 121 | u16 id; |
| 119 | const char *name; | 122 | const char *dmi_name; |
| 120 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ | 123 | /* + 1 -> end of sensors indicated by a sensor with name == NULL */ |
| 121 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; | 124 | struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1]; |
| 122 | }; | 125 | }; |
| @@ -161,7 +164,7 @@ struct abituguru3_data { | |||
| 161 | 164 | ||
| 162 | /* Constants */ | 165 | /* Constants */ |
| 163 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | 166 | static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { |
| 164 | { 0x000C, "unknown", { | 167 | { 0x000C, NULL /* Unknown, need DMI string */, { |
| 165 | { "CPU Core", 0, 0, 10, 1, 0 }, | 168 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 166 | { "DDR", 1, 0, 10, 1, 0 }, | 169 | { "DDR", 1, 0, 10, 1, 0 }, |
| 167 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 170 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -183,7 +186,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 183 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, | 186 | { "AUX1 Fan", 35, 2, 60, 1, 0 }, |
| 184 | { NULL, 0, 0, 0, 0, 0 } } | 187 | { NULL, 0, 0, 0, 0, 0 } } |
| 185 | }, | 188 | }, |
| 186 | { 0x000D, "Abit AW8", { | 189 | { 0x000D, NULL /* Abit AW8, need DMI string */, { |
| 187 | { "CPU Core", 0, 0, 10, 1, 0 }, | 190 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 188 | { "DDR", 1, 0, 10, 1, 0 }, | 191 | { "DDR", 1, 0, 10, 1, 0 }, |
| 189 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 192 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -212,7 +215,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 212 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 215 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
| 213 | { NULL, 0, 0, 0, 0, 0 } } | 216 | { NULL, 0, 0, 0, 0, 0 } } |
| 214 | }, | 217 | }, |
| 215 | { 0x000E, "AL-8", { | 218 | { 0x000E, NULL /* AL-8, need DMI string */, { |
| 216 | { "CPU Core", 0, 0, 10, 1, 0 }, | 219 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 217 | { "DDR", 1, 0, 10, 1, 0 }, | 220 | { "DDR", 1, 0, 10, 1, 0 }, |
| 218 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 221 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -233,7 +236,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 233 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 236 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
| 234 | { NULL, 0, 0, 0, 0, 0 } } | 237 | { NULL, 0, 0, 0, 0, 0 } } |
| 235 | }, | 238 | }, |
| 236 | { 0x000F, "unknown", { | 239 | { 0x000F, NULL /* Unknown, need DMI string */, { |
| 237 | { "CPU Core", 0, 0, 10, 1, 0 }, | 240 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 238 | { "DDR", 1, 0, 10, 1, 0 }, | 241 | { "DDR", 1, 0, 10, 1, 0 }, |
| 239 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 242 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -254,7 +257,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 254 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 257 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
| 255 | { NULL, 0, 0, 0, 0, 0 } } | 258 | { NULL, 0, 0, 0, 0, 0 } } |
| 256 | }, | 259 | }, |
| 257 | { 0x0010, "Abit NI8 SLI GR", { | 260 | { 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, { |
| 258 | { "CPU Core", 0, 0, 10, 1, 0 }, | 261 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 259 | { "DDR", 1, 0, 10, 1, 0 }, | 262 | { "DDR", 1, 0, 10, 1, 0 }, |
| 260 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 263 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -276,7 +279,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 276 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, | 279 | { "OTES1 Fan", 36, 2, 60, 1, 0 }, |
| 277 | { NULL, 0, 0, 0, 0, 0 } } | 280 | { NULL, 0, 0, 0, 0, 0 } } |
| 278 | }, | 281 | }, |
| 279 | { 0x0011, "Abit AT8 32X", { | 282 | { 0x0011, NULL /* Abit AT8 32X, need DMI string */, { |
| 280 | { "CPU Core", 0, 0, 10, 1, 0 }, | 283 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 281 | { "DDR", 1, 0, 20, 1, 0 }, | 284 | { "DDR", 1, 0, 20, 1, 0 }, |
| 282 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 285 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -302,7 +305,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 302 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, | 305 | { "AUX2 Fan", 36, 2, 60, 1, 0 }, |
| 303 | { NULL, 0, 0, 0, 0, 0 } } | 306 | { NULL, 0, 0, 0, 0, 0 } } |
| 304 | }, | 307 | }, |
| 305 | { 0x0012, "Abit AN8 32X", { | 308 | { 0x0012, NULL /* Abit AN8 32X, need DMI string */, { |
| 306 | { "CPU Core", 0, 0, 10, 1, 0 }, | 309 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 307 | { "DDR", 1, 0, 20, 1, 0 }, | 310 | { "DDR", 1, 0, 20, 1, 0 }, |
| 308 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 311 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -324,7 +327,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 324 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, | 327 | { "AUX1 Fan", 36, 2, 60, 1, 0 }, |
| 325 | { NULL, 0, 0, 0, 0, 0 } } | 328 | { NULL, 0, 0, 0, 0, 0 } } |
| 326 | }, | 329 | }, |
| 327 | { 0x0013, "Abit AW8D", { | 330 | { 0x0013, NULL /* Abit AW8D, need DMI string */, { |
| 328 | { "CPU Core", 0, 0, 10, 1, 0 }, | 331 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 329 | { "DDR", 1, 0, 10, 1, 0 }, | 332 | { "DDR", 1, 0, 10, 1, 0 }, |
| 330 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 333 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -353,7 +356,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 353 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, | 356 | { "AUX5 Fan", 39, 2, 60, 1, 0 }, |
| 354 | { NULL, 0, 0, 0, 0, 0 } } | 357 | { NULL, 0, 0, 0, 0, 0 } } |
| 355 | }, | 358 | }, |
| 356 | { 0x0014, "Abit AB9 Pro", { | 359 | { 0x0014, NULL /* Abit AB9 Pro, need DMI string */, { |
| 357 | { "CPU Core", 0, 0, 10, 1, 0 }, | 360 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 358 | { "DDR", 1, 0, 10, 1, 0 }, | 361 | { "DDR", 1, 0, 10, 1, 0 }, |
| 359 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 362 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -374,7 +377,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 374 | { "SYS Fan", 34, 2, 60, 1, 0 }, | 377 | { "SYS Fan", 34, 2, 60, 1, 0 }, |
| 375 | { NULL, 0, 0, 0, 0, 0 } } | 378 | { NULL, 0, 0, 0, 0, 0 } } |
| 376 | }, | 379 | }, |
| 377 | { 0x0015, "unknown", { | 380 | { 0x0015, NULL /* Unknown, need DMI string */, { |
| 378 | { "CPU Core", 0, 0, 10, 1, 0 }, | 381 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 379 | { "DDR", 1, 0, 20, 1, 0 }, | 382 | { "DDR", 1, 0, 20, 1, 0 }, |
| 380 | { "DDR VTT", 2, 0, 10, 1, 0 }, | 383 | { "DDR VTT", 2, 0, 10, 1, 0 }, |
| @@ -398,7 +401,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 398 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 401 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
| 399 | { NULL, 0, 0, 0, 0, 0 } } | 402 | { NULL, 0, 0, 0, 0, 0 } } |
| 400 | }, | 403 | }, |
| 401 | { 0x0016, "AW9D-MAX", { | 404 | { 0x0016, NULL /* AW9D-MAX, need DMI string */, { |
| 402 | { "CPU Core", 0, 0, 10, 1, 0 }, | 405 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 403 | { "DDR2", 1, 0, 20, 1, 0 }, | 406 | { "DDR2", 1, 0, 20, 1, 0 }, |
| 404 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 407 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
| @@ -426,7 +429,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 426 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, | 429 | { "OTES1 Fan", 38, 2, 60, 1, 0 }, |
| 427 | { NULL, 0, 0, 0, 0, 0 } } | 430 | { NULL, 0, 0, 0, 0, 0 } } |
| 428 | }, | 431 | }, |
| 429 | { 0x0017, "unknown", { | 432 | { 0x0017, NULL /* Unknown, need DMI string */, { |
| 430 | { "CPU Core", 0, 0, 10, 1, 0 }, | 433 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 431 | { "DDR2", 1, 0, 20, 1, 0 }, | 434 | { "DDR2", 1, 0, 20, 1, 0 }, |
| 432 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 435 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
| @@ -451,7 +454,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 451 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, | 454 | { "AUX3 FAN", 37, 2, 60, 1, 0 }, |
| 452 | { NULL, 0, 0, 0, 0, 0 } } | 455 | { NULL, 0, 0, 0, 0, 0 } } |
| 453 | }, | 456 | }, |
| 454 | { 0x0018, "unknown", { | 457 | { 0x0018, NULL /* Unknown, need DMI string */, { |
| 455 | { "CPU Core", 0, 0, 10, 1, 0 }, | 458 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 456 | { "DDR2", 1, 0, 20, 1, 0 }, | 459 | { "DDR2", 1, 0, 20, 1, 0 }, |
| 457 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 460 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
| @@ -478,7 +481,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 478 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 481 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
| 479 | { NULL, 0, 0, 0, 0, 0 } } | 482 | { NULL, 0, 0, 0, 0, 0 } } |
| 480 | }, | 483 | }, |
| 481 | { 0x0019, "unknown", { | 484 | { 0x0019, NULL /* Unknown, need DMI string */, { |
| 482 | { "CPU Core", 7, 0, 10, 1, 0 }, | 485 | { "CPU Core", 7, 0, 10, 1, 0 }, |
| 483 | { "DDR2", 13, 0, 20, 1, 0 }, | 486 | { "DDR2", 13, 0, 20, 1, 0 }, |
| 484 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, | 487 | { "DDR2 VTT", 14, 0, 10, 1, 0 }, |
| @@ -505,7 +508,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 505 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | 508 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, |
| 506 | { NULL, 0, 0, 0, 0, 0 } } | 509 | { NULL, 0, 0, 0, 0, 0 } } |
| 507 | }, | 510 | }, |
| 508 | { 0x001A, "Abit IP35 Pro", { | 511 | { 0x001A, "IP35 Pro(Intel P35-ICH9R)", { |
| 509 | { "CPU Core", 0, 0, 10, 1, 0 }, | 512 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 510 | { "DDR2", 1, 0, 20, 1, 0 }, | 513 | { "DDR2", 1, 0, 20, 1, 0 }, |
| 511 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 514 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
| @@ -533,7 +536,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 533 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, | 536 | { "AUX4 Fan", 37, 2, 60, 1, 0 }, |
| 534 | { NULL, 0, 0, 0, 0, 0 } } | 537 | { NULL, 0, 0, 0, 0, 0 } } |
| 535 | }, | 538 | }, |
| 536 | { 0x001B, "unknown", { | 539 | { 0x001B, NULL /* Unknown, need DMI string */, { |
| 537 | { "CPU Core", 0, 0, 10, 1, 0 }, | 540 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 538 | { "DDR3", 1, 0, 20, 1, 0 }, | 541 | { "DDR3", 1, 0, 20, 1, 0 }, |
| 539 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, | 542 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, |
| @@ -560,7 +563,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
| 560 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 563 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
| 561 | { NULL, 0, 0, 0, 0, 0 } } | 564 | { NULL, 0, 0, 0, 0, 0 } } |
| 562 | }, | 565 | }, |
| 563 | { 0x001C, "unknown", { | 566 | { 0x001C, NULL /* Unknown, need DMI string */, { |
| 564 | { "CPU Core", 0, 0, 10, 1, 0 }, | 567 | { "CPU Core", 0, 0, 10, 1, 0 }, |
| 565 | { "DDR2", 1, 0, 20, 1, 0 }, | 568 | { "DDR2", 1, 0, 20, 1, 0 }, |
| 566 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 569 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
| @@ -935,9 +938,18 @@ static int __devinit abituguru3_probe(struct platform_device *pdev) | |||
| 935 | goto abituguru3_probe_error; | 938 | goto abituguru3_probe_error; |
| 936 | } | 939 | } |
| 937 | data->sensors = abituguru3_motherboards[i].sensors; | 940 | data->sensors = abituguru3_motherboards[i].sensors; |
| 941 | |||
| 938 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " | 942 | printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard " |
| 939 | "ID: %04X (%s)\n", (unsigned int)id, | 943 | "ID: %04X\n", (unsigned int)id); |
| 940 | abituguru3_motherboards[i].name); | 944 | |
| 945 | #ifdef CONFIG_DMI | ||
| 946 | if (!abituguru3_motherboards[i].dmi_name) { | ||
| 947 | printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was " | ||
| 948 | "not detected using DMI. Please send the output of " | ||
| 949 | "\"dmidecode\" to the abituguru3 maintainer" | ||
| 950 | "(see MAINTAINERS)\n"); | ||
| 951 | } | ||
| 952 | #endif | ||
| 941 | 953 | ||
| 942 | /* Fill the sysfs attr array */ | 954 | /* Fill the sysfs attr array */ |
| 943 | sysfs_attr_i = 0; | 955 | sysfs_attr_i = 0; |
| @@ -1109,6 +1121,46 @@ static struct platform_driver abituguru3_driver = { | |||
| 1109 | .resume = abituguru3_resume | 1121 | .resume = abituguru3_resume |
| 1110 | }; | 1122 | }; |
| 1111 | 1123 | ||
| 1124 | #ifdef CONFIG_DMI | ||
| 1125 | |||
| 1126 | static int __init abituguru3_dmi_detect(void) | ||
| 1127 | { | ||
| 1128 | const char *board_vendor, *board_name; | ||
| 1129 | int i, err = (force) ? 1 : -ENODEV; | ||
| 1130 | |||
| 1131 | board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | ||
| 1132 | if (!board_vendor || strcmp(board_vendor, "http://www.abit.com.tw/")) | ||
| 1133 | return err; | ||
| 1134 | |||
| 1135 | board_name = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 1136 | if (!board_name) | ||
| 1137 | return err; | ||
| 1138 | |||
| 1139 | for (i = 0; abituguru3_motherboards[i].id; i++) { | ||
| 1140 | const char *dmi_name = abituguru3_motherboards[i].dmi_name; | ||
| 1141 | if (dmi_name && !strcmp(dmi_name, board_name)) | ||
| 1142 | break; | ||
| 1143 | } | ||
| 1144 | |||
| 1145 | if (!abituguru3_motherboards[i].id) | ||
| 1146 | return 1; | ||
| 1147 | |||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | #else /* !CONFIG_DMI */ | ||
| 1152 | |||
| 1153 | static inline int abituguru3_dmi_detect(void) | ||
| 1154 | { | ||
| 1155 | return -ENODEV; | ||
| 1156 | } | ||
| 1157 | |||
| 1158 | #endif /* CONFIG_DMI */ | ||
| 1159 | |||
| 1160 | /* FIXME: Manual detection should die eventually; we need to collect stable | ||
| 1161 | * DMI model names first before we can rely entirely on CONFIG_DMI. | ||
| 1162 | */ | ||
| 1163 | |||
| 1112 | static int __init abituguru3_detect(void) | 1164 | static int __init abituguru3_detect(void) |
| 1113 | { | 1165 | { |
| 1114 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or | 1166 | /* See if there is an uguru3 there. An idle uGuru3 will hold 0x00 or |
| @@ -1119,7 +1171,7 @@ static int __init abituguru3_detect(void) | |||
| 1119 | if (((data_val == 0x00) || (data_val == 0x08)) && | 1171 | if (((data_val == 0x00) || (data_val == 0x08)) && |
| 1120 | ((cmd_val == 0xAC) || (cmd_val == 0x05) || | 1172 | ((cmd_val == 0xAC) || (cmd_val == 0x05) || |
| 1121 | (cmd_val == 0x55))) | 1173 | (cmd_val == 0x55))) |
| 1122 | return ABIT_UGURU3_BASE; | 1174 | return 0; |
| 1123 | 1175 | ||
| 1124 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " | 1176 | ABIT_UGURU3_DEBUG("no Abit uGuru3 found, data = 0x%02X, cmd = " |
| 1125 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); | 1177 | "0x%02X\n", (unsigned int)data_val, (unsigned int)cmd_val); |
| @@ -1127,7 +1179,7 @@ static int __init abituguru3_detect(void) | |||
| 1127 | if (force) { | 1179 | if (force) { |
| 1128 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " | 1180 | printk(KERN_INFO ABIT_UGURU3_NAME ": Assuming Abit uGuru3 is " |
| 1129 | "present because of \"force\" parameter\n"); | 1181 | "present because of \"force\" parameter\n"); |
| 1130 | return ABIT_UGURU3_BASE; | 1182 | return 0; |
| 1131 | } | 1183 | } |
| 1132 | 1184 | ||
| 1133 | /* No uGuru3 found */ | 1185 | /* No uGuru3 found */ |
| @@ -1138,27 +1190,29 @@ static struct platform_device *abituguru3_pdev; | |||
| 1138 | 1190 | ||
| 1139 | static int __init abituguru3_init(void) | 1191 | static int __init abituguru3_init(void) |
| 1140 | { | 1192 | { |
| 1141 | int address, err; | ||
| 1142 | struct resource res = { .flags = IORESOURCE_IO }; | 1193 | struct resource res = { .flags = IORESOURCE_IO }; |
| 1143 | 1194 | int err; | |
| 1144 | #ifdef CONFIG_DMI | 1195 | |
| 1145 | const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); | 1196 | /* Attempt DMI detection first */ |
| 1146 | 1197 | err = abituguru3_dmi_detect(); | |
| 1147 | /* safety check, refuse to load on non Abit motherboards */ | 1198 | if (err < 0) |
| 1148 | if (!force && (!board_vendor || | 1199 | return err; |
| 1149 | strcmp(board_vendor, "http://www.abit.com.tw/"))) | 1200 | |
| 1150 | return -ENODEV; | 1201 | /* Fall back to manual detection if there was no exact |
| 1151 | #endif | 1202 | * board name match, or force was specified. |
| 1152 | 1203 | */ | |
| 1153 | address = abituguru3_detect(); | 1204 | if (err > 0) { |
| 1154 | if (address < 0) | 1205 | err = abituguru3_detect(); |
| 1155 | return address; | 1206 | if (err) |
| 1207 | return err; | ||
| 1208 | } | ||
| 1156 | 1209 | ||
| 1157 | err = platform_driver_register(&abituguru3_driver); | 1210 | err = platform_driver_register(&abituguru3_driver); |
| 1158 | if (err) | 1211 | if (err) |
| 1159 | goto exit; | 1212 | goto exit; |
| 1160 | 1213 | ||
| 1161 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, address); | 1214 | abituguru3_pdev = platform_device_alloc(ABIT_UGURU3_NAME, |
| 1215 | ABIT_UGURU3_BASE); | ||
| 1162 | if (!abituguru3_pdev) { | 1216 | if (!abituguru3_pdev) { |
| 1163 | printk(KERN_ERR ABIT_UGURU3_NAME | 1217 | printk(KERN_ERR ABIT_UGURU3_NAME |
| 1164 | ": Device allocation failed\n"); | 1218 | ": Device allocation failed\n"); |
| @@ -1166,8 +1220,8 @@ static int __init abituguru3_init(void) | |||
| 1166 | goto exit_driver_unregister; | 1220 | goto exit_driver_unregister; |
| 1167 | } | 1221 | } |
| 1168 | 1222 | ||
| 1169 | res.start = address; | 1223 | res.start = ABIT_UGURU3_BASE; |
| 1170 | res.end = address + ABIT_UGURU3_REGION_LENGTH - 1; | 1224 | res.end = ABIT_UGURU3_BASE + ABIT_UGURU3_REGION_LENGTH - 1; |
| 1171 | res.name = ABIT_UGURU3_NAME; | 1225 | res.name = ABIT_UGURU3_NAME; |
| 1172 | 1226 | ||
| 1173 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); | 1227 | err = platform_device_add_resources(abituguru3_pdev, &res, 1); |
diff --git a/drivers/hwmon/adcxx.c b/drivers/hwmon/adcxx.c new file mode 100644 index 000000000000..242294db3db6 --- /dev/null +++ b/drivers/hwmon/adcxx.c | |||
| @@ -0,0 +1,329 @@ | |||
| 1 | /* | ||
| 2 | * adcxx.c | ||
| 3 | * | ||
| 4 | * The adcxx4s is an AD converter family from National Semiconductor (NS). | ||
| 5 | * | ||
| 6 | * Copyright (c) 2008 Marc Pignat <marc.pignat@hevs.ch> | ||
| 7 | * | ||
| 8 | * The adcxx4s communicates with a host processor via an SPI/Microwire Bus | ||
| 9 | * interface. This driver supports the whole family of devices with name | ||
| 10 | * ADC<bb><c>S<sss>, where | ||
| 11 | * * bb is the resolution in number of bits (8, 10, 12) | ||
| 12 | * * c is the number of channels (1, 2, 4, 8) | ||
| 13 | * * sss is the maximum conversion speed (021 for 200 kSPS, 051 for 500 kSPS | ||
| 14 | * and 101 for 1 MSPS) | ||
| 15 | * | ||
| 16 | * Complete datasheets are available at National's website here: | ||
| 17 | * http://www.national.com/ds/DC/ADC<bb><c>S<sss>.pdf | ||
| 18 | * | ||
| 19 | * Handling of 8, 10 and 12 bits converters are the same, the | ||
| 20 | * unavailable bits are 0 :) | ||
| 21 | * | ||
| 22 | * This program is free software; you can redistribute it and/or modify | ||
| 23 | * it under the terms of the GNU General Public License as published by | ||
| 24 | * the Free Software Foundation; either version 2 of the License, or | ||
| 25 | * (at your option) any later version. | ||
| 26 | * | ||
| 27 | * This program is distributed in the hope that it will be useful, | ||
| 28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 30 | * GNU General Public License for more details. | ||
| 31 | * | ||
| 32 | * You should have received a copy of the GNU General Public License | ||
| 33 | * along with this program; if not, write to the Free Software | ||
| 34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 35 | */ | ||
| 36 | |||
| 37 | #include <linux/init.h> | ||
| 38 | #include <linux/module.h> | ||
| 39 | #include <linux/kernel.h> | ||
| 40 | #include <linux/device.h> | ||
| 41 | #include <linux/err.h> | ||
| 42 | #include <linux/sysfs.h> | ||
| 43 | #include <linux/hwmon.h> | ||
| 44 | #include <linux/hwmon-sysfs.h> | ||
| 45 | #include <linux/mutex.h> | ||
| 46 | #include <linux/spi/spi.h> | ||
| 47 | |||
| 48 | #define DRVNAME "adcxx" | ||
| 49 | |||
| 50 | struct adcxx { | ||
| 51 | struct device *hwmon_dev; | ||
| 52 | struct mutex lock; | ||
| 53 | u32 channels; | ||
| 54 | u32 reference; /* in millivolts */ | ||
| 55 | }; | ||
| 56 | |||
| 57 | /* sysfs hook function */ | ||
| 58 | static ssize_t adcxx_read(struct device *dev, | ||
| 59 | struct device_attribute *devattr, char *buf) | ||
| 60 | { | ||
| 61 | struct spi_device *spi = to_spi_device(dev); | ||
| 62 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 63 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
| 64 | u8 tx_buf[2] = { attr->index << 3 }; /* other bits are don't care */ | ||
| 65 | u8 rx_buf[2]; | ||
| 66 | int status; | ||
| 67 | int value; | ||
| 68 | |||
| 69 | if (mutex_lock_interruptible(&adc->lock)) | ||
| 70 | return -ERESTARTSYS; | ||
| 71 | |||
| 72 | status = spi_write_then_read(spi, tx_buf, sizeof(tx_buf), | ||
| 73 | rx_buf, sizeof(rx_buf)); | ||
| 74 | if (status < 0) { | ||
| 75 | dev_warn(dev, "spi_write_then_read failed with status %d\n", | ||
| 76 | status); | ||
| 77 | goto out; | ||
| 78 | } | ||
| 79 | |||
| 80 | value = (rx_buf[0] << 8) + rx_buf[1]; | ||
| 81 | dev_dbg(dev, "raw value = 0x%x\n", value); | ||
| 82 | |||
| 83 | value = value * adc->reference >> 12; | ||
| 84 | status = sprintf(buf, "%d\n", value); | ||
| 85 | out: | ||
| 86 | mutex_unlock(&adc->lock); | ||
| 87 | return status; | ||
| 88 | } | ||
| 89 | |||
| 90 | static ssize_t adcxx_show_min(struct device *dev, | ||
| 91 | struct device_attribute *devattr, char *buf) | ||
| 92 | { | ||
| 93 | /* The minimum reference is 0 for this chip family */ | ||
| 94 | return sprintf(buf, "0\n"); | ||
| 95 | } | ||
| 96 | |||
| 97 | static ssize_t adcxx_show_max(struct device *dev, | ||
| 98 | struct device_attribute *devattr, char *buf) | ||
| 99 | { | ||
| 100 | struct spi_device *spi = to_spi_device(dev); | ||
| 101 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
| 102 | u32 reference; | ||
| 103 | |||
| 104 | if (mutex_lock_interruptible(&adc->lock)) | ||
| 105 | return -ERESTARTSYS; | ||
| 106 | |||
| 107 | reference = adc->reference; | ||
| 108 | |||
| 109 | mutex_unlock(&adc->lock); | ||
| 110 | |||
| 111 | return sprintf(buf, "%d\n", reference); | ||
| 112 | } | ||
| 113 | |||
| 114 | static ssize_t adcxx_set_max(struct device *dev, | ||
| 115 | struct device_attribute *devattr, const char *buf, size_t count) | ||
| 116 | { | ||
| 117 | struct spi_device *spi = to_spi_device(dev); | ||
| 118 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
| 119 | unsigned long value; | ||
| 120 | |||
| 121 | if (strict_strtoul(buf, 10, &value)) | ||
| 122 | return -EINVAL; | ||
| 123 | |||
| 124 | if (mutex_lock_interruptible(&adc->lock)) | ||
| 125 | return -ERESTARTSYS; | ||
| 126 | |||
| 127 | adc->reference = value; | ||
| 128 | |||
| 129 | mutex_unlock(&adc->lock); | ||
| 130 | |||
| 131 | return count; | ||
| 132 | } | ||
| 133 | |||
| 134 | static ssize_t adcxx_show_name(struct device *dev, struct device_attribute | ||
| 135 | *devattr, char *buf) | ||
| 136 | { | ||
| 137 | struct spi_device *spi = to_spi_device(dev); | ||
| 138 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
| 139 | |||
| 140 | return sprintf(buf, "adcxx%ds\n", adc->channels); | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct sensor_device_attribute ad_input[] = { | ||
| 144 | SENSOR_ATTR(name, S_IRUGO, adcxx_show_name, NULL, 0), | ||
| 145 | SENSOR_ATTR(in_min, S_IRUGO, adcxx_show_min, NULL, 0), | ||
| 146 | SENSOR_ATTR(in_max, S_IWUSR | S_IRUGO, adcxx_show_max, | ||
| 147 | adcxx_set_max, 0), | ||
| 148 | SENSOR_ATTR(in0_input, S_IRUGO, adcxx_read, NULL, 0), | ||
| 149 | SENSOR_ATTR(in1_input, S_IRUGO, adcxx_read, NULL, 1), | ||
| 150 | SENSOR_ATTR(in2_input, S_IRUGO, adcxx_read, NULL, 2), | ||
| 151 | SENSOR_ATTR(in3_input, S_IRUGO, adcxx_read, NULL, 3), | ||
| 152 | SENSOR_ATTR(in4_input, S_IRUGO, adcxx_read, NULL, 4), | ||
| 153 | SENSOR_ATTR(in5_input, S_IRUGO, adcxx_read, NULL, 5), | ||
| 154 | SENSOR_ATTR(in6_input, S_IRUGO, adcxx_read, NULL, 6), | ||
| 155 | SENSOR_ATTR(in7_input, S_IRUGO, adcxx_read, NULL, 7), | ||
| 156 | }; | ||
| 157 | |||
| 158 | /*----------------------------------------------------------------------*/ | ||
| 159 | |||
| 160 | static int __devinit adcxx_probe(struct spi_device *spi, int channels) | ||
| 161 | { | ||
| 162 | struct adcxx *adc; | ||
| 163 | int status; | ||
| 164 | int i; | ||
| 165 | |||
| 166 | adc = kzalloc(sizeof *adc, GFP_KERNEL); | ||
| 167 | if (!adc) | ||
| 168 | return -ENOMEM; | ||
| 169 | |||
| 170 | /* set a default value for the reference */ | ||
| 171 | adc->reference = 3300; | ||
| 172 | adc->channels = channels; | ||
| 173 | mutex_init(&adc->lock); | ||
| 174 | |||
| 175 | mutex_lock(&adc->lock); | ||
| 176 | |||
| 177 | dev_set_drvdata(&spi->dev, adc); | ||
| 178 | |||
| 179 | for (i = 0; i < 3 + adc->channels; i++) { | ||
| 180 | status = device_create_file(&spi->dev, &ad_input[i].dev_attr); | ||
| 181 | if (status) { | ||
| 182 | dev_err(&spi->dev, "device_create_file failed.\n"); | ||
| 183 | goto out_err; | ||
| 184 | } | ||
| 185 | } | ||
| 186 | |||
| 187 | adc->hwmon_dev = hwmon_device_register(&spi->dev); | ||
| 188 | if (IS_ERR(adc->hwmon_dev)) { | ||
| 189 | dev_err(&spi->dev, "hwmon_device_register failed.\n"); | ||
| 190 | status = PTR_ERR(adc->hwmon_dev); | ||
| 191 | goto out_err; | ||
| 192 | } | ||
| 193 | |||
| 194 | mutex_unlock(&adc->lock); | ||
| 195 | return 0; | ||
| 196 | |||
| 197 | out_err: | ||
| 198 | for (i--; i >= 0; i--) | ||
| 199 | device_remove_file(&spi->dev, &ad_input[i].dev_attr); | ||
| 200 | |||
| 201 | dev_set_drvdata(&spi->dev, NULL); | ||
| 202 | mutex_unlock(&adc->lock); | ||
| 203 | kfree(adc); | ||
| 204 | return status; | ||
| 205 | } | ||
| 206 | |||
| 207 | static int __devinit adcxx1s_probe(struct spi_device *spi) | ||
| 208 | { | ||
| 209 | return adcxx_probe(spi, 1); | ||
| 210 | } | ||
| 211 | |||
| 212 | static int __devinit adcxx2s_probe(struct spi_device *spi) | ||
| 213 | { | ||
| 214 | return adcxx_probe(spi, 2); | ||
| 215 | } | ||
| 216 | |||
| 217 | static int __devinit adcxx4s_probe(struct spi_device *spi) | ||
| 218 | { | ||
| 219 | return adcxx_probe(spi, 4); | ||
| 220 | } | ||
| 221 | |||
| 222 | static int __devinit adcxx8s_probe(struct spi_device *spi) | ||
| 223 | { | ||
| 224 | return adcxx_probe(spi, 8); | ||
| 225 | } | ||
| 226 | |||
| 227 | static int __devexit adcxx_remove(struct spi_device *spi) | ||
| 228 | { | ||
| 229 | struct adcxx *adc = dev_get_drvdata(&spi->dev); | ||
| 230 | int i; | ||
| 231 | |||
| 232 | mutex_lock(&adc->lock); | ||
| 233 | hwmon_device_unregister(adc->hwmon_dev); | ||
| 234 | for (i = 0; i < 3 + adc->channels; i++) | ||
| 235 | device_remove_file(&spi->dev, &ad_input[i].dev_attr); | ||
| 236 | |||
| 237 | dev_set_drvdata(&spi->dev, NULL); | ||
| 238 | mutex_unlock(&adc->lock); | ||
| 239 | kfree(adc); | ||
| 240 | |||
| 241 | return 0; | ||
| 242 | } | ||
| 243 | |||
| 244 | static struct spi_driver adcxx1s_driver = { | ||
| 245 | .driver = { | ||
| 246 | .name = "adcxx1s", | ||
| 247 | .owner = THIS_MODULE, | ||
| 248 | }, | ||
| 249 | .probe = adcxx1s_probe, | ||
| 250 | .remove = __devexit_p(adcxx_remove), | ||
| 251 | }; | ||
| 252 | |||
| 253 | static struct spi_driver adcxx2s_driver = { | ||
| 254 | .driver = { | ||
| 255 | .name = "adcxx2s", | ||
| 256 | .owner = THIS_MODULE, | ||
| 257 | }, | ||
| 258 | .probe = adcxx2s_probe, | ||
| 259 | .remove = __devexit_p(adcxx_remove), | ||
| 260 | }; | ||
| 261 | |||
| 262 | static struct spi_driver adcxx4s_driver = { | ||
| 263 | .driver = { | ||
| 264 | .name = "adcxx4s", | ||
| 265 | .owner = THIS_MODULE, | ||
| 266 | }, | ||
| 267 | .probe = adcxx4s_probe, | ||
| 268 | .remove = __devexit_p(adcxx_remove), | ||
| 269 | }; | ||
| 270 | |||
| 271 | static struct spi_driver adcxx8s_driver = { | ||
| 272 | .driver = { | ||
| 273 | .name = "adcxx8s", | ||
| 274 | .owner = THIS_MODULE, | ||
| 275 | }, | ||
| 276 | .probe = adcxx8s_probe, | ||
| 277 | .remove = __devexit_p(adcxx_remove), | ||
| 278 | }; | ||
| 279 | |||
| 280 | static int __init init_adcxx(void) | ||
| 281 | { | ||
| 282 | int status; | ||
| 283 | status = spi_register_driver(&adcxx1s_driver); | ||
| 284 | if (status) | ||
| 285 | goto reg_1_failed; | ||
| 286 | |||
| 287 | status = spi_register_driver(&adcxx2s_driver); | ||
| 288 | if (status) | ||
| 289 | goto reg_2_failed; | ||
| 290 | |||
| 291 | status = spi_register_driver(&adcxx4s_driver); | ||
| 292 | if (status) | ||
| 293 | goto reg_4_failed; | ||
| 294 | |||
| 295 | status = spi_register_driver(&adcxx8s_driver); | ||
| 296 | if (status) | ||
| 297 | goto reg_8_failed; | ||
| 298 | |||
| 299 | return status; | ||
| 300 | |||
| 301 | reg_8_failed: | ||
| 302 | spi_unregister_driver(&adcxx4s_driver); | ||
| 303 | reg_4_failed: | ||
| 304 | spi_unregister_driver(&adcxx2s_driver); | ||
| 305 | reg_2_failed: | ||
| 306 | spi_unregister_driver(&adcxx1s_driver); | ||
| 307 | reg_1_failed: | ||
| 308 | return status; | ||
| 309 | } | ||
| 310 | |||
| 311 | static void __exit exit_adcxx(void) | ||
| 312 | { | ||
| 313 | spi_unregister_driver(&adcxx1s_driver); | ||
| 314 | spi_unregister_driver(&adcxx2s_driver); | ||
| 315 | spi_unregister_driver(&adcxx4s_driver); | ||
| 316 | spi_unregister_driver(&adcxx8s_driver); | ||
| 317 | } | ||
| 318 | |||
| 319 | module_init(init_adcxx); | ||
| 320 | module_exit(exit_adcxx); | ||
| 321 | |||
| 322 | MODULE_AUTHOR("Marc Pignat"); | ||
| 323 | MODULE_DESCRIPTION("National Semiconductor adcxx8sxxx Linux driver"); | ||
| 324 | MODULE_LICENSE("GPL"); | ||
| 325 | |||
| 326 | MODULE_ALIAS("adcxx1s"); | ||
| 327 | MODULE_ALIAS("adcxx2s"); | ||
| 328 | MODULE_ALIAS("adcxx4s"); | ||
| 329 | MODULE_ALIAS("adcxx8s"); | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index aacc0c4b809c..b06b8e090a27 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
| @@ -98,6 +98,12 @@ static const char* temperature_sensors_sets[][36] = { | |||
| 98 | "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", | 98 | "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", |
| 99 | "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", | 99 | "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", |
| 100 | "TM9S", "TN0H", "TS0C", NULL }, | 100 | "TM9S", "TN0H", "TS0C", NULL }, |
| 101 | /* Set 5: iMac */ | ||
| 102 | { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P", | ||
| 103 | "Tp0C", NULL }, | ||
| 104 | /* Set 6: Macbook3 set */ | ||
| 105 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H", | ||
| 106 | "Th0S", "Th1H", NULL }, | ||
| 101 | }; | 107 | }; |
| 102 | 108 | ||
| 103 | /* List of keys used to read/write fan speeds */ | 109 | /* List of keys used to read/write fan speeds */ |
| @@ -1223,6 +1229,10 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
| 1223 | { .accelerometer = 0, .light = 0, .temperature_set = 3 }, | 1229 | { .accelerometer = 0, .light = 0, .temperature_set = 3 }, |
| 1224 | /* MacPro: temperature set 4 */ | 1230 | /* MacPro: temperature set 4 */ |
| 1225 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, | 1231 | { .accelerometer = 0, .light = 0, .temperature_set = 4 }, |
| 1232 | /* iMac: temperature set 5 */ | ||
| 1233 | { .accelerometer = 0, .light = 0, .temperature_set = 5 }, | ||
| 1234 | /* MacBook3: accelerometer and temperature set 6 */ | ||
| 1235 | { .accelerometer = 1, .light = 0, .temperature_set = 6 }, | ||
| 1226 | }; | 1236 | }; |
| 1227 | 1237 | ||
| 1228 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1238 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
| @@ -1232,10 +1242,14 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
| 1232 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1242 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1233 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, | 1243 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") }, |
| 1234 | (void*)&applesmc_dmi_data[0]}, | 1244 | (void*)&applesmc_dmi_data[0]}, |
| 1235 | { applesmc_dmi_match, "Apple MacBook", { | 1245 | { applesmc_dmi_match, "Apple MacBook (v2)", { |
| 1236 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1246 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1237 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, | 1247 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") }, |
| 1238 | (void*)&applesmc_dmi_data[1]}, | 1248 | (void*)&applesmc_dmi_data[1]}, |
| 1249 | { applesmc_dmi_match, "Apple MacBook (v3)", { | ||
| 1250 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
| 1251 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") }, | ||
| 1252 | (void*)&applesmc_dmi_data[6]}, | ||
| 1239 | { applesmc_dmi_match, "Apple MacBook", { | 1253 | { applesmc_dmi_match, "Apple MacBook", { |
| 1240 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1254 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1241 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, | 1255 | DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") }, |
| @@ -1248,6 +1262,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
| 1248 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1262 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
| 1249 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | 1263 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, |
| 1250 | (void*)&applesmc_dmi_data[4]}, | 1264 | (void*)&applesmc_dmi_data[4]}, |
| 1265 | { applesmc_dmi_match, "Apple iMac", { | ||
| 1266 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
| 1267 | DMI_MATCH(DMI_PRODUCT_NAME,"iMac") }, | ||
| 1268 | (void*)&applesmc_dmi_data[5]}, | ||
| 1251 | { .ident = NULL } | 1269 | { .ident = NULL } |
| 1252 | }; | 1270 | }; |
| 1253 | 1271 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 70239acecc8e..93c17223b527 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
| @@ -413,10 +413,11 @@ static int __init coretemp_init(void) | |||
| 413 | for_each_online_cpu(i) { | 413 | for_each_online_cpu(i) { |
| 414 | struct cpuinfo_x86 *c = &cpu_data(i); | 414 | struct cpuinfo_x86 *c = &cpu_data(i); |
| 415 | 415 | ||
| 416 | /* check if family 6, models 0xe, 0xf, 0x16, 0x17 */ | 416 | /* check if family 6, models 0xe, 0xf, 0x16, 0x17, 0x1A */ |
| 417 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || | 417 | if ((c->cpuid_level < 0) || (c->x86 != 0x6) || |
| 418 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || | 418 | !((c->x86_model == 0xe) || (c->x86_model == 0xf) || |
| 419 | (c->x86_model == 0x16) || (c->x86_model == 0x17))) { | 419 | (c->x86_model == 0x16) || (c->x86_model == 0x17) || |
| 420 | (c->x86_model == 0x1A))) { | ||
| 420 | 421 | ||
| 421 | /* supported CPU not found, but report the unknown | 422 | /* supported CPU not found, but report the unknown |
| 422 | family 6 CPU */ | 423 | family 6 CPU */ |
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 7b0a32c4dcfb..c54eff92be4a 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c | |||
| @@ -37,13 +37,21 @@ | |||
| 37 | * For VRD 10.0 and up, "VRD x.y Design Guide", | 37 | * For VRD 10.0 and up, "VRD x.y Design Guide", |
| 38 | * available at http://developer.intel.com/. | 38 | * available at http://developer.intel.com/. |
| 39 | * | 39 | * |
| 40 | * AMD NPT 0Fh (Athlon64 & Opteron), AMD Publication 32559, | 40 | * AMD Athlon 64 and AMD Opteron Processors, AMD Publication 26094, |
| 41 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/26094.PDF | ||
| 42 | * Table 74. VID Code Voltages | ||
| 43 | * This corresponds to an arbitrary VRM code of 24 in the functions below. | ||
| 44 | * These CPU models (K8 revision <= E) have 5 VID pins. See also: | ||
| 45 | * Revision Guide for AMD Athlon 64 and AMD Opteron Processors, AMD Publication 25759, | ||
| 46 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf | ||
| 47 | * | ||
| 48 | * AMD NPT Family 0Fh Processors, AMD Publication 32559, | ||
| 41 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf | 49 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf |
| 42 | * Table 71. VID Code Voltages | 50 | * Table 71. VID Code Voltages |
| 43 | * AMD Opteron processors don't follow the Intel specifications. | 51 | * This corresponds to an arbitrary VRM code of 25 in the functions below. |
| 44 | * I'm going to "make up" 2.4 as the spec number for the Opterons. | 52 | * These CPU models (K8 revision >= F) have 6 VID pins. See also: |
| 45 | * No good reason just a mnemonic for the 24x Opteron processor | 53 | * Revision Guide for AMD NPT Family 0Fh Processors, AMD Publication 33610, |
| 46 | * series. | 54 | * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf |
| 47 | * | 55 | * |
| 48 | * The 17 specification is in fact Intel Mobile Voltage Positioning - | 56 | * The 17 specification is in fact Intel Mobile Voltage Positioning - |
| 49 | * (IMVP-II). You can find more information in the datasheet of Max1718 | 57 | * (IMVP-II). You can find more information in the datasheet of Max1718 |
| @@ -95,7 +103,12 @@ int vid_from_reg(int val, u8 vrm) | |||
| 95 | return 0; | 103 | return 0; |
| 96 | return((1600000 - (val - 2) * 6250 + 500) / 1000); | 104 | return((1600000 - (val - 2) * 6250 + 500) / 1000); |
| 97 | 105 | ||
| 98 | case 24: /* AMD NPT 0Fh (Athlon64 & Opteron) */ | 106 | case 24: /* Athlon64 & Opteron */ |
| 107 | val &= 0x1f; | ||
| 108 | if (val == 0x1f) | ||
| 109 | return 0; | ||
| 110 | /* fall through */ | ||
| 111 | case 25: /* AMD NPT 0Fh */ | ||
| 99 | val &= 0x3f; | 112 | val &= 0x3f; |
| 100 | return (val < 32) ? 1550 - 25 * val | 113 | return (val < 32) ? 1550 - 25 * val |
| 101 | : 775 - (25 * (val - 31)) / 2; | 114 | : 775 - (25 * (val - 31)) / 2; |
| @@ -157,11 +170,16 @@ struct vrm_model { | |||
| 157 | 170 | ||
| 158 | #ifdef CONFIG_X86 | 171 | #ifdef CONFIG_X86 |
| 159 | 172 | ||
| 160 | /* the stepping parameter is highest acceptable stepping for current line */ | 173 | /* |
| 174 | * The stepping parameter is highest acceptable stepping for current line. | ||
| 175 | * The model match must be exact for 4-bit values. For model values 0x10 | ||
| 176 | * and above (extended model), all models below the parameter will match. | ||
| 177 | */ | ||
| 161 | 178 | ||
| 162 | static struct vrm_model vrm_models[] = { | 179 | static struct vrm_model vrm_models[] = { |
| 163 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ | 180 | {X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */ |
| 164 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */ | 181 | {X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24}, /* Athlon 64, Opteron */ |
| 182 | {X86_VENDOR_AMD, 0xF, ANY, ANY, 25}, /* NPT family 0Fh */ | ||
| 165 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ | 183 | {X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */ |
| 166 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ | 184 | {X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */ |
| 167 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ | 185 | {X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */ |
| @@ -189,6 +207,8 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor) | |||
| 189 | if (vrm_models[i].vendor==vendor) | 207 | if (vrm_models[i].vendor==vendor) |
| 190 | if ((vrm_models[i].eff_family==eff_family) | 208 | if ((vrm_models[i].eff_family==eff_family) |
| 191 | && ((vrm_models[i].eff_model==eff_model) || | 209 | && ((vrm_models[i].eff_model==eff_model) || |
| 210 | (vrm_models[i].eff_model >= 0x10 && | ||
| 211 | eff_model <= vrm_models[i].eff_model) || | ||
| 192 | (vrm_models[i].eff_model==ANY)) && | 212 | (vrm_models[i].eff_model==ANY)) && |
| 193 | (eff_stepping <= vrm_models[i].eff_stepping)) | 213 | (eff_stepping <= vrm_models[i].eff_stepping)) |
| 194 | return vrm_models[i].vrm_type; | 214 | return vrm_models[i].vrm_type; |
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index f9e2ed621f7b..2ede9388096b 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c | |||
| @@ -81,6 +81,8 @@ static unsigned long amb_reg_temp(unsigned int amb) | |||
| 81 | #define MAX_AMBS_PER_CHANNEL 16 | 81 | #define MAX_AMBS_PER_CHANNEL 16 |
| 82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ | 82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ |
| 83 | MAX_AMBS_PER_CHANNEL) | 83 | MAX_AMBS_PER_CHANNEL) |
| 84 | #define CHANNEL_SHIFT 4 | ||
| 85 | #define DIMM_MASK 0xF | ||
| 84 | /* | 86 | /* |
| 85 | * Ugly hack: For some reason the highest bit is set if there | 87 | * Ugly hack: For some reason the highest bit is set if there |
| 86 | * are _any_ DIMMs in the channel. Attempting to read from | 88 | * are _any_ DIMMs in the channel. Attempting to read from |
| @@ -89,7 +91,7 @@ static unsigned long amb_reg_temp(unsigned int amb) | |||
| 89 | * might prevent us from seeing the 16th DIMM in the channel. | 91 | * might prevent us from seeing the 16th DIMM in the channel. |
| 90 | */ | 92 | */ |
| 91 | #define REAL_MAX_AMBS_PER_CHANNEL 15 | 93 | #define REAL_MAX_AMBS_PER_CHANNEL 15 |
| 92 | #define KNOBS_PER_AMB 5 | 94 | #define KNOBS_PER_AMB 6 |
| 93 | 95 | ||
| 94 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) | 96 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) |
| 95 | { | 97 | { |
| @@ -238,6 +240,16 @@ static ssize_t show_amb_temp(struct device *dev, | |||
| 238 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); | 240 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 243 | static ssize_t show_label(struct device *dev, | ||
| 244 | struct device_attribute *devattr, | ||
| 245 | char *buf) | ||
| 246 | { | ||
| 247 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 248 | |||
| 249 | return sprintf(buf, "Ch. %d DIMM %d\n", attr->index >> CHANNEL_SHIFT, | ||
| 250 | attr->index & DIMM_MASK); | ||
| 251 | } | ||
| 252 | |||
| 241 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | 253 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) |
| 242 | { | 254 | { |
| 243 | int i, j, k, d = 0; | 255 | int i, j, k, d = 0; |
| @@ -268,6 +280,20 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | |||
| 268 | continue; | 280 | continue; |
| 269 | d++; | 281 | d++; |
| 270 | 282 | ||
| 283 | /* sysfs label */ | ||
| 284 | iattr = data->attrs + data->num_attrs; | ||
| 285 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
| 286 | "temp%d_label", d); | ||
| 287 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
| 288 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | ||
| 289 | iattr->s_attr.dev_attr.show = show_label; | ||
| 290 | iattr->s_attr.index = k; | ||
| 291 | res = device_create_file(&pdev->dev, | ||
| 292 | &iattr->s_attr.dev_attr); | ||
| 293 | if (res) | ||
| 294 | goto exit_remove; | ||
| 295 | data->num_attrs++; | ||
| 296 | |||
| 271 | /* Temperature sysfs knob */ | 297 | /* Temperature sysfs knob */ |
| 272 | iattr = data->attrs + data->num_attrs; | 298 | iattr = data->attrs + data->num_attrs; |
| 273 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 299 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c9416e657487..0f70dc204105 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * A hwmon driver for the IBM Active Energy Manager temperature/power sensors | 2 | * A hwmon driver for the IBM System Director Active Energy Manager (AEM) |
| 3 | * and capping functionality. | 3 | * temperature/power/energy sensors and capping functionality. |
| 4 | * Copyright (C) 2008 IBM | 4 | * Copyright (C) 2008 IBM |
| 5 | * | 5 | * |
| 6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | 6 | * Author: Darrick J. Wong <djwong@us.ibm.com> |
| @@ -463,12 +463,18 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | |||
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | /* Update AEM energy registers */ | 465 | /* Update AEM energy registers */ |
| 466 | static void update_aem_energy_one(struct aem_data *data, int which) | ||
| 467 | { | ||
| 468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, which, | ||
| 469 | &data->energy[which], 8); | ||
| 470 | } | ||
| 471 | |||
| 466 | static void update_aem_energy(struct aem_data *data) | 472 | static void update_aem_energy(struct aem_data *data) |
| 467 | { | 473 | { |
| 468 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 0, &data->energy[0], 8); | 474 | update_aem_energy_one(data, 0); |
| 469 | if (data->ver_major < 2) | 475 | if (data->ver_major < 2) |
| 470 | return; | 476 | return; |
| 471 | aem_read_sensor(data, AEM_ENERGY_ELEMENT, 1, &data->energy[1], 8); | 477 | update_aem_energy_one(data, 1); |
| 472 | } | 478 | } |
| 473 | 479 | ||
| 474 | /* Update all AEM1 sensors */ | 480 | /* Update all AEM1 sensors */ |
| @@ -676,7 +682,8 @@ static int aem_find_aem2(struct aem_ipmi_data *data, | |||
| 676 | return -ETIMEDOUT; | 682 | return -ETIMEDOUT; |
| 677 | 683 | ||
| 678 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || | 684 | if (data->rx_result || data->rx_msg_len != sizeof(*fi_resp) || |
| 679 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id))) | 685 | memcmp(&fi_resp->id, &system_x_id, sizeof(system_x_id)) || |
| 686 | fi_resp->num_instances <= instance_num) | ||
| 680 | return -ENOENT; | 687 | return -ENOENT; |
| 681 | 688 | ||
| 682 | return 0; | 689 | return 0; |
| @@ -849,7 +856,7 @@ static ssize_t aem_show_power(struct device *dev, | |||
| 849 | struct timespec b, a; | 856 | struct timespec b, a; |
| 850 | 857 | ||
| 851 | mutex_lock(&data->lock); | 858 | mutex_lock(&data->lock); |
| 852 | update_aem_energy(data); | 859 | update_aem_energy_one(data, attr->index); |
| 853 | getnstimeofday(&b); | 860 | getnstimeofday(&b); |
| 854 | before = data->energy[attr->index]; | 861 | before = data->energy[attr->index]; |
| 855 | 862 | ||
| @@ -861,7 +868,7 @@ static ssize_t aem_show_power(struct device *dev, | |||
| 861 | return 0; | 868 | return 0; |
| 862 | } | 869 | } |
| 863 | 870 | ||
| 864 | update_aem_energy(data); | 871 | update_aem_energy_one(data, attr->index); |
| 865 | getnstimeofday(&a); | 872 | getnstimeofday(&a); |
| 866 | after = data->energy[attr->index]; | 873 | after = data->energy[attr->index]; |
| 867 | mutex_unlock(&data->lock); | 874 | mutex_unlock(&data->lock); |
| @@ -880,7 +887,9 @@ static ssize_t aem_show_energy(struct device *dev, | |||
| 880 | { | 887 | { |
| 881 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 888 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
| 882 | struct aem_data *a = dev_get_drvdata(dev); | 889 | struct aem_data *a = dev_get_drvdata(dev); |
| 883 | a->update(a); | 890 | mutex_lock(&a->lock); |
| 891 | update_aem_energy_one(a, attr->index); | ||
| 892 | mutex_unlock(&a->lock); | ||
| 884 | 893 | ||
| 885 | return sprintf(buf, "%llu\n", | 894 | return sprintf(buf, "%llu\n", |
| 886 | (unsigned long long)a->energy[attr->index] * 1000); | 895 | (unsigned long long)a->energy[attr->index] * 1000); |
| @@ -1104,7 +1113,7 @@ static void __exit aem_exit(void) | |||
| 1104 | } | 1113 | } |
| 1105 | 1114 | ||
| 1106 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | 1115 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); |
| 1107 | MODULE_DESCRIPTION("IBM Active Energy Manager power/temp sensor driver"); | 1116 | MODULE_DESCRIPTION("IBM AEM power/temp/energy sensor driver"); |
| 1108 | MODULE_LICENSE("GPL"); | 1117 | MODULE_LICENSE("GPL"); |
| 1109 | 1118 | ||
| 1110 | module_init(aem_init); | 1119 | module_init(aem_init); |
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c index daa7d121483b..de21142d106c 100644 --- a/drivers/hwmon/w83791d.c +++ b/drivers/hwmon/w83791d.c | |||
| @@ -1055,9 +1055,10 @@ static int w83791d_probe(struct i2c_client *client, | |||
| 1055 | { | 1055 | { |
| 1056 | struct w83791d_data *data; | 1056 | struct w83791d_data *data; |
| 1057 | struct device *dev = &client->dev; | 1057 | struct device *dev = &client->dev; |
| 1058 | int i, val1, err; | 1058 | int i, err; |
| 1059 | 1059 | ||
| 1060 | #ifdef DEBUG | 1060 | #ifdef DEBUG |
| 1061 | int val1; | ||
| 1061 | val1 = w83791d_read(client, W83791D_REG_DID_VID4); | 1062 | val1 = w83791d_read(client, W83791D_REG_DID_VID4); |
| 1062 | dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", | 1063 | dev_dbg(dev, "Device ID version: %d.%d (0x%02x)\n", |
| 1063 | (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); | 1064 | (val1 >> 5) & 0x07, (val1 >> 1) & 0x0f, val1); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 2d65411f6763..a92d81567559 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -647,6 +647,47 @@ static int str_to_user(const char *str, unsigned int maxlen, void __user *p) | |||
| 647 | return copy_to_user(p, str, len) ? -EFAULT : len; | 647 | return copy_to_user(p, str, len) ? -EFAULT : len; |
| 648 | } | 648 | } |
| 649 | 649 | ||
| 650 | #define OLD_KEY_MAX 0x1ff | ||
| 651 | static int handle_eviocgbit(struct input_dev *dev, unsigned int cmd, void __user *p, int compat_mode) | ||
| 652 | { | ||
| 653 | static unsigned long keymax_warn_time; | ||
| 654 | unsigned long *bits; | ||
| 655 | int len; | ||
| 656 | |||
| 657 | switch (_IOC_NR(cmd) & EV_MAX) { | ||
| 658 | |||
| 659 | case 0: bits = dev->evbit; len = EV_MAX; break; | ||
| 660 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | ||
| 661 | case EV_REL: bits = dev->relbit; len = REL_MAX; break; | ||
| 662 | case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; | ||
| 663 | case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; | ||
| 664 | case EV_LED: bits = dev->ledbit; len = LED_MAX; break; | ||
| 665 | case EV_SND: bits = dev->sndbit; len = SND_MAX; break; | ||
| 666 | case EV_FF: bits = dev->ffbit; len = FF_MAX; break; | ||
| 667 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; | ||
| 668 | default: return -EINVAL; | ||
| 669 | } | ||
| 670 | |||
| 671 | /* | ||
| 672 | * Work around bugs in userspace programs that like to do | ||
| 673 | * EVIOCGBIT(EV_KEY, KEY_MAX) and not realize that 'len' | ||
| 674 | * should be in bytes, not in bits. | ||
| 675 | */ | ||
| 676 | if ((_IOC_NR(cmd) & EV_MAX) == EV_KEY && _IOC_SIZE(cmd) == OLD_KEY_MAX) { | ||
| 677 | len = OLD_KEY_MAX; | ||
| 678 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | ||
| 679 | printk(KERN_WARNING | ||
| 680 | "evdev.c(EVIOCGBIT): Suspicious buffer size %d, " | ||
| 681 | "limiting output to %d bytes. See " | ||
| 682 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", | ||
| 683 | OLD_KEY_MAX, | ||
| 684 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | ||
| 685 | } | ||
| 686 | |||
| 687 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | ||
| 688 | } | ||
| 689 | #undef OLD_KEY_MAX | ||
| 690 | |||
| 650 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, | 691 | static long evdev_do_ioctl(struct file *file, unsigned int cmd, |
| 651 | void __user *p, int compat_mode) | 692 | void __user *p, int compat_mode) |
| 652 | { | 693 | { |
| @@ -733,26 +774,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 733 | 774 | ||
| 734 | if (_IOC_DIR(cmd) == _IOC_READ) { | 775 | if (_IOC_DIR(cmd) == _IOC_READ) { |
| 735 | 776 | ||
| 736 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) { | 777 | if ((_IOC_NR(cmd) & ~EV_MAX) == _IOC_NR(EVIOCGBIT(0, 0))) |
| 737 | 778 | return handle_eviocgbit(dev, cmd, p, compat_mode); | |
| 738 | unsigned long *bits; | ||
| 739 | int len; | ||
| 740 | |||
| 741 | switch (_IOC_NR(cmd) & EV_MAX) { | ||
| 742 | |||
| 743 | case 0: bits = dev->evbit; len = EV_MAX; break; | ||
| 744 | case EV_KEY: bits = dev->keybit; len = KEY_MAX; break; | ||
| 745 | case EV_REL: bits = dev->relbit; len = REL_MAX; break; | ||
| 746 | case EV_ABS: bits = dev->absbit; len = ABS_MAX; break; | ||
| 747 | case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break; | ||
| 748 | case EV_LED: bits = dev->ledbit; len = LED_MAX; break; | ||
| 749 | case EV_SND: bits = dev->sndbit; len = SND_MAX; break; | ||
| 750 | case EV_FF: bits = dev->ffbit; len = FF_MAX; break; | ||
| 751 | case EV_SW: bits = dev->swbit; len = SW_MAX; break; | ||
| 752 | default: return -EINVAL; | ||
| 753 | } | ||
| 754 | return bits_to_user(bits, len, _IOC_SIZE(cmd), p, compat_mode); | ||
| 755 | } | ||
| 756 | 779 | ||
| 757 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) | 780 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGKEY(0))) |
| 758 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), | 781 | return bits_to_user(dev->key, KEY_MAX, _IOC_SIZE(cmd), |
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 87d3e7eabffd..6791be81eb29 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c | |||
| @@ -127,6 +127,7 @@ static const struct xpad_device { | |||
| 127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, | 127 | { 0x0738, 0x4716, "Mad Catz Wired Xbox 360 Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX360 }, |
| 128 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 128 | { 0x0738, 0x6040, "Mad Catz Beat Pad Pro", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 129 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 129 | { 0x0c12, 0x8802, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
| 130 | { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | ||
| 130 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 131 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
| 131 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 132 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
| 132 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, | 133 | { 0x0e4c, 0x1097, "Radica Gamester Controller", MAP_DPAD_TO_AXES, XTYPE_XBOX }, |
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index be58730e636a..3f48279f2195 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -118,6 +118,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 118 | unsigned int type = button->type ?: EV_KEY; | 118 | unsigned int type = button->type ?: EV_KEY; |
| 119 | 119 | ||
| 120 | bdata->input = input; | 120 | bdata->input = input; |
| 121 | bdata->button = button; | ||
| 121 | setup_timer(&bdata->timer, | 122 | setup_timer(&bdata->timer, |
| 122 | gpio_check_button, (unsigned long)bdata); | 123 | gpio_check_button, (unsigned long)bdata); |
| 123 | 124 | ||
| @@ -256,7 +257,7 @@ static int gpio_keys_resume(struct platform_device *pdev) | |||
| 256 | #define gpio_keys_resume NULL | 257 | #define gpio_keys_resume NULL |
| 257 | #endif | 258 | #endif |
| 258 | 259 | ||
| 259 | struct platform_driver gpio_keys_device_driver = { | 260 | static struct platform_driver gpio_keys_device_driver = { |
| 260 | .probe = gpio_keys_probe, | 261 | .probe = gpio_keys_probe, |
| 261 | .remove = __devexit_p(gpio_keys_remove), | 262 | .remove = __devexit_p(gpio_keys_remove), |
| 262 | .suspend = gpio_keys_suspend, | 263 | .suspend = gpio_keys_suspend, |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 7bbea097cda2..f996546fc443 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
| @@ -130,6 +130,29 @@ config MOUSE_APPLETOUCH | |||
| 130 | To compile this driver as a module, choose M here: the | 130 | To compile this driver as a module, choose M here: the |
| 131 | module will be called appletouch. | 131 | module will be called appletouch. |
| 132 | 132 | ||
| 133 | config MOUSE_BCM5974 | ||
| 134 | tristate "Apple USB BCM5974 Multitouch trackpad support" | ||
| 135 | depends on USB_ARCH_HAS_HCD | ||
| 136 | select USB | ||
| 137 | help | ||
| 138 | Say Y here if you have an Apple USB BCM5974 Multitouch | ||
| 139 | trackpad. | ||
| 140 | |||
| 141 | The BCM5974 is the multitouch trackpad found in the Macbook | ||
| 142 | Air (JAN2008) and Macbook Pro Penryn (FEB2008) laptops. | ||
| 143 | |||
| 144 | It is also found in the IPhone (2007) and Ipod Touch (2008). | ||
| 145 | |||
| 146 | This driver provides multitouch functionality together with | ||
| 147 | the synaptics X11 driver. | ||
| 148 | |||
| 149 | The interface is currently identical to the appletouch interface, | ||
| 150 | for further information, see | ||
| 151 | <file:Documentation/input/appletouch.txt>. | ||
| 152 | |||
| 153 | To compile this driver as a module, choose M here: the | ||
| 154 | module will be called bcm5974. | ||
| 155 | |||
| 133 | config MOUSE_INPORT | 156 | config MOUSE_INPORT |
| 134 | tristate "InPort/MS/ATIXL busmouse" | 157 | tristate "InPort/MS/ATIXL busmouse" |
| 135 | depends on ISA | 158 | depends on ISA |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 9e6e36330820..d4d202516090 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o | 7 | obj-$(CONFIG_MOUSE_AMIGA) += amimouse.o |
| 8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o | 8 | obj-$(CONFIG_MOUSE_APPLETOUCH) += appletouch.o |
| 9 | obj-$(CONFIG_MOUSE_BCM5974) += bcm5974.o | ||
| 9 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o | 10 | obj-$(CONFIG_MOUSE_ATARI) += atarimouse.o |
| 10 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | 11 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o |
| 11 | obj-$(CONFIG_MOUSE_INPORT) += inport.o | 12 | obj-$(CONFIG_MOUSE_INPORT) += inport.o |
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c new file mode 100644 index 000000000000..2ec921bf3c60 --- /dev/null +++ b/drivers/input/mouse/bcm5974.c | |||
| @@ -0,0 +1,681 @@ | |||
| 1 | /* | ||
| 2 | * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) | ||
| 5 | * | ||
| 6 | * The USB initialization and package decoding was made by | ||
| 7 | * Scott Shawcroft as part of the touchd user-space driver project: | ||
| 8 | * Copyright (C) 2008 Scott Shawcroft (scott.shawcroft@gmail.com) | ||
| 9 | * | ||
| 10 | * The BCM5974 driver is based on the appletouch driver: | ||
| 11 | * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) | ||
| 12 | * Copyright (C) 2005 Johannes Berg (johannes@sipsolutions.net) | ||
| 13 | * Copyright (C) 2005 Stelian Pop (stelian@popies.net) | ||
| 14 | * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de) | ||
| 15 | * Copyright (C) 2005 Peter Osterlund (petero2@telia.com) | ||
| 16 | * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch) | ||
| 17 | * Copyright (C) 2006 Nicolas Boichat (nicolas@boichat.ch) | ||
| 18 | * | ||
| 19 | * This program is free software; you can redistribute it and/or modify | ||
| 20 | * it under the terms of the GNU General Public License as published by | ||
| 21 | * the Free Software Foundation; either version 2 of the License, or | ||
| 22 | * (at your option) any later version. | ||
| 23 | * | ||
| 24 | * This program is distributed in the hope that it will be useful, | ||
| 25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 27 | * GNU General Public License for more details. | ||
| 28 | * | ||
| 29 | * You should have received a copy of the GNU General Public License | ||
| 30 | * along with this program; if not, write to the Free Software | ||
| 31 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 32 | * | ||
| 33 | */ | ||
| 34 | |||
| 35 | #include <linux/kernel.h> | ||
| 36 | #include <linux/errno.h> | ||
| 37 | #include <linux/init.h> | ||
| 38 | #include <linux/slab.h> | ||
| 39 | #include <linux/module.h> | ||
| 40 | #include <linux/usb/input.h> | ||
| 41 | #include <linux/hid.h> | ||
| 42 | #include <linux/mutex.h> | ||
| 43 | |||
| 44 | #define USB_VENDOR_ID_APPLE 0x05ac | ||
| 45 | |||
| 46 | /* MacbookAir, aka wellspring */ | ||
| 47 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223 | ||
| 48 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224 | ||
| 49 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225 | ||
| 50 | /* MacbookProPenryn, aka wellspring2 */ | ||
| 51 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230 | ||
| 52 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231 | ||
| 53 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232 | ||
| 54 | |||
| 55 | #define BCM5974_DEVICE(prod) { \ | ||
| 56 | .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ | ||
| 57 | USB_DEVICE_ID_MATCH_INT_CLASS | \ | ||
| 58 | USB_DEVICE_ID_MATCH_INT_PROTOCOL), \ | ||
| 59 | .idVendor = USB_VENDOR_ID_APPLE, \ | ||
| 60 | .idProduct = (prod), \ | ||
| 61 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | ||
| 62 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE \ | ||
| 63 | } | ||
| 64 | |||
| 65 | /* table of devices that work with this driver */ | ||
| 66 | static const struct usb_device_id bcm5974_table [] = { | ||
| 67 | /* MacbookAir1.1 */ | ||
| 68 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), | ||
| 69 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_ISO), | ||
| 70 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING_JIS), | ||
| 71 | /* MacbookProPenryn */ | ||
| 72 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI), | ||
| 73 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_ISO), | ||
| 74 | BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING2_JIS), | ||
| 75 | /* Terminating entry */ | ||
| 76 | {} | ||
| 77 | }; | ||
| 78 | MODULE_DEVICE_TABLE(usb, bcm5974_table); | ||
| 79 | |||
| 80 | MODULE_AUTHOR("Henrik Rydberg"); | ||
| 81 | MODULE_DESCRIPTION("Apple USB BCM5974 multitouch driver"); | ||
| 82 | MODULE_LICENSE("GPL"); | ||
| 83 | |||
| 84 | #define dprintk(level, format, a...)\ | ||
| 85 | { if (debug >= level) printk(KERN_DEBUG format, ##a); } | ||
| 86 | |||
| 87 | static int debug = 1; | ||
| 88 | module_param(debug, int, 0644); | ||
| 89 | MODULE_PARM_DESC(debug, "Activate debugging output"); | ||
| 90 | |||
| 91 | /* button data structure */ | ||
| 92 | struct bt_data { | ||
| 93 | u8 unknown1; /* constant */ | ||
| 94 | u8 button; /* left button */ | ||
| 95 | u8 rel_x; /* relative x coordinate */ | ||
| 96 | u8 rel_y; /* relative y coordinate */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* trackpad header structure */ | ||
| 100 | struct tp_header { | ||
| 101 | u8 unknown1[16]; /* constants, timers, etc */ | ||
| 102 | u8 fingers; /* number of fingers on trackpad */ | ||
| 103 | u8 unknown2[9]; /* constants, timers, etc */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | /* trackpad finger structure */ | ||
| 107 | struct tp_finger { | ||
| 108 | __le16 origin; /* left/right origin? */ | ||
| 109 | __le16 abs_x; /* absolute x coodinate */ | ||
| 110 | __le16 abs_y; /* absolute y coodinate */ | ||
| 111 | __le16 rel_x; /* relative x coodinate */ | ||
| 112 | __le16 rel_y; /* relative y coodinate */ | ||
| 113 | __le16 size_major; /* finger size, major axis? */ | ||
| 114 | __le16 size_minor; /* finger size, minor axis? */ | ||
| 115 | __le16 orientation; /* 16384 when point, else 15 bit angle */ | ||
| 116 | __le16 force_major; /* trackpad force, major axis? */ | ||
| 117 | __le16 force_minor; /* trackpad force, minor axis? */ | ||
| 118 | __le16 unused[3]; /* zeros */ | ||
| 119 | __le16 multi; /* one finger: varies, more fingers: constant */ | ||
| 120 | }; | ||
| 121 | |||
| 122 | /* trackpad data structure, empirically at least ten fingers */ | ||
| 123 | struct tp_data { | ||
| 124 | struct tp_header header; | ||
| 125 | struct tp_finger finger[16]; | ||
| 126 | }; | ||
| 127 | |||
| 128 | /* device-specific parameters */ | ||
| 129 | struct bcm5974_param { | ||
| 130 | int dim; /* logical dimension */ | ||
| 131 | int fuzz; /* logical noise value */ | ||
| 132 | int devmin; /* device minimum reading */ | ||
| 133 | int devmax; /* device maximum reading */ | ||
| 134 | }; | ||
| 135 | |||
| 136 | /* device-specific configuration */ | ||
| 137 | struct bcm5974_config { | ||
| 138 | int ansi, iso, jis; /* the product id of this device */ | ||
| 139 | int bt_ep; /* the endpoint of the button interface */ | ||
| 140 | int bt_datalen; /* data length of the button interface */ | ||
| 141 | int tp_ep; /* the endpoint of the trackpad interface */ | ||
| 142 | int tp_datalen; /* data length of the trackpad interface */ | ||
| 143 | struct bcm5974_param p; /* finger pressure limits */ | ||
| 144 | struct bcm5974_param w; /* finger width limits */ | ||
| 145 | struct bcm5974_param x; /* horizontal limits */ | ||
| 146 | struct bcm5974_param y; /* vertical limits */ | ||
| 147 | }; | ||
| 148 | |||
| 149 | /* logical device structure */ | ||
| 150 | struct bcm5974 { | ||
| 151 | char phys[64]; | ||
| 152 | struct usb_device *udev; /* usb device */ | ||
| 153 | struct usb_interface *intf; /* our interface */ | ||
| 154 | struct input_dev *input; /* input dev */ | ||
| 155 | struct bcm5974_config cfg; /* device configuration */ | ||
| 156 | struct mutex pm_mutex; /* serialize access to open/suspend */ | ||
| 157 | int opened; /* 1: opened, 0: closed */ | ||
| 158 | struct urb *bt_urb; /* button usb request block */ | ||
| 159 | struct bt_data *bt_data; /* button transferred data */ | ||
| 160 | struct urb *tp_urb; /* trackpad usb request block */ | ||
| 161 | struct tp_data *tp_data; /* trackpad transferred data */ | ||
| 162 | }; | ||
| 163 | |||
| 164 | /* logical dimensions */ | ||
| 165 | #define DIM_PRESSURE 256 /* maximum finger pressure */ | ||
| 166 | #define DIM_WIDTH 16 /* maximum finger width */ | ||
| 167 | #define DIM_X 1280 /* maximum trackpad x value */ | ||
| 168 | #define DIM_Y 800 /* maximum trackpad y value */ | ||
| 169 | |||
| 170 | /* logical signal quality */ | ||
| 171 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ | ||
| 172 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ | ||
| 173 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ | ||
| 174 | |||
| 175 | /* device constants */ | ||
| 176 | static const struct bcm5974_config bcm5974_config_table[] = { | ||
| 177 | { | ||
| 178 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, | ||
| 179 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO, | ||
| 180 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS, | ||
| 181 | 0x84, sizeof(struct bt_data), | ||
| 182 | 0x81, sizeof(struct tp_data), | ||
| 183 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | ||
| 184 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
| 185 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, | ||
| 186 | { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } | ||
| 187 | }, | ||
| 188 | { | ||
| 189 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | ||
| 190 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, | ||
| 191 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, | ||
| 192 | 0x84, sizeof(struct bt_data), | ||
| 193 | 0x81, sizeof(struct tp_data), | ||
| 194 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | ||
| 195 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | ||
| 196 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | ||
| 197 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } | ||
| 198 | }, | ||
| 199 | {} | ||
| 200 | }; | ||
| 201 | |||
| 202 | /* return the device-specific configuration by device */ | ||
| 203 | static const struct bcm5974_config *bcm5974_get_config(struct usb_device *udev) | ||
| 204 | { | ||
| 205 | u16 id = le16_to_cpu(udev->descriptor.idProduct); | ||
| 206 | const struct bcm5974_config *cfg; | ||
| 207 | |||
| 208 | for (cfg = bcm5974_config_table; cfg->ansi; ++cfg) | ||
| 209 | if (cfg->ansi == id || cfg->iso == id || cfg->jis == id) | ||
| 210 | return cfg; | ||
| 211 | |||
| 212 | return bcm5974_config_table; | ||
| 213 | } | ||
| 214 | |||
| 215 | /* convert 16-bit little endian to signed integer */ | ||
| 216 | static inline int raw2int(__le16 x) | ||
| 217 | { | ||
| 218 | return (signed short)le16_to_cpu(x); | ||
| 219 | } | ||
| 220 | |||
| 221 | /* scale device data to logical dimensions (asserts devmin < devmax) */ | ||
| 222 | static inline int int2scale(const struct bcm5974_param *p, int x) | ||
| 223 | { | ||
| 224 | return x * p->dim / (p->devmax - p->devmin); | ||
| 225 | } | ||
| 226 | |||
| 227 | /* all logical value ranges are [0,dim). */ | ||
| 228 | static inline int int2bound(const struct bcm5974_param *p, int x) | ||
| 229 | { | ||
| 230 | int s = int2scale(p, x); | ||
| 231 | |||
| 232 | return clamp_val(s, 0, p->dim - 1); | ||
| 233 | } | ||
| 234 | |||
| 235 | /* setup which logical events to report */ | ||
| 236 | static void setup_events_to_report(struct input_dev *input_dev, | ||
| 237 | const struct bcm5974_config *cfg) | ||
| 238 | { | ||
| 239 | __set_bit(EV_ABS, input_dev->evbit); | ||
| 240 | |||
| 241 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
| 242 | 0, cfg->p.dim, cfg->p.fuzz, 0); | ||
| 243 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, | ||
| 244 | 0, cfg->w.dim, cfg->w.fuzz, 0); | ||
| 245 | input_set_abs_params(input_dev, ABS_X, | ||
| 246 | 0, cfg->x.dim, cfg->x.fuzz, 0); | ||
| 247 | input_set_abs_params(input_dev, ABS_Y, | ||
| 248 | 0, cfg->y.dim, cfg->y.fuzz, 0); | ||
| 249 | |||
| 250 | __set_bit(EV_KEY, input_dev->evbit); | ||
| 251 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
| 252 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
| 253 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
| 254 | __set_bit(BTN_LEFT, input_dev->keybit); | ||
| 255 | } | ||
| 256 | |||
| 257 | /* report button data as logical button state */ | ||
| 258 | static int report_bt_state(struct bcm5974 *dev, int size) | ||
| 259 | { | ||
| 260 | if (size != sizeof(struct bt_data)) | ||
| 261 | return -EIO; | ||
| 262 | |||
| 263 | input_report_key(dev->input, BTN_LEFT, dev->bt_data->button); | ||
| 264 | input_sync(dev->input); | ||
| 265 | |||
| 266 | return 0; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* report trackpad data as logical trackpad state */ | ||
| 270 | static int report_tp_state(struct bcm5974 *dev, int size) | ||
| 271 | { | ||
| 272 | const struct bcm5974_config *c = &dev->cfg; | ||
| 273 | const struct tp_finger *f = dev->tp_data->finger; | ||
| 274 | struct input_dev *input = dev->input; | ||
| 275 | const int fingers = (size - 26) / 28; | ||
| 276 | int p = 0, w, x, y, n = 0; | ||
| 277 | |||
| 278 | if (size < 26 || (size - 26) % 28 != 0) | ||
| 279 | return -EIO; | ||
| 280 | |||
| 281 | if (fingers) { | ||
| 282 | p = raw2int(f->force_major); | ||
| 283 | w = raw2int(f->size_major); | ||
| 284 | x = raw2int(f->abs_x); | ||
| 285 | y = raw2int(f->abs_y); | ||
| 286 | n = p > 0 ? fingers : 0; | ||
| 287 | |||
| 288 | dprintk(9, | ||
| 289 | "bcm5974: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", | ||
| 290 | p, w, x, y, n); | ||
| 291 | |||
| 292 | input_report_abs(input, ABS_TOOL_WIDTH, int2bound(&c->w, w)); | ||
| 293 | input_report_abs(input, ABS_X, int2bound(&c->x, x - c->x.devmin)); | ||
| 294 | input_report_abs(input, ABS_Y, int2bound(&c->y, c->y.devmax - y)); | ||
| 295 | } | ||
| 296 | |||
| 297 | input_report_abs(input, ABS_PRESSURE, int2bound(&c->p, p)); | ||
| 298 | |||
| 299 | input_report_key(input, BTN_TOOL_FINGER, n == 1); | ||
| 300 | input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2); | ||
| 301 | input_report_key(input, BTN_TOOL_TRIPLETAP, n > 2); | ||
| 302 | |||
| 303 | input_sync(input); | ||
| 304 | |||
| 305 | return 0; | ||
| 306 | } | ||
| 307 | |||
| 308 | /* Wellspring initialization constants */ | ||
| 309 | #define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1 | ||
| 310 | #define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9 | ||
| 311 | #define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300 | ||
| 312 | #define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0 | ||
| 313 | #define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01 | ||
| 314 | |||
| 315 | static int bcm5974_wellspring_mode(struct bcm5974 *dev) | ||
| 316 | { | ||
| 317 | char *data = kmalloc(8, GFP_KERNEL); | ||
| 318 | int retval = 0, size; | ||
| 319 | |||
| 320 | if (!data) { | ||
| 321 | err("bcm5974: out of memory"); | ||
| 322 | retval = -ENOMEM; | ||
| 323 | goto out; | ||
| 324 | } | ||
| 325 | |||
| 326 | /* read configuration */ | ||
| 327 | size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), | ||
| 328 | BCM5974_WELLSPRING_MODE_READ_REQUEST_ID, | ||
| 329 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 330 | BCM5974_WELLSPRING_MODE_REQUEST_VALUE, | ||
| 331 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); | ||
| 332 | |||
| 333 | if (size != 8) { | ||
| 334 | err("bcm5974: could not read from device"); | ||
| 335 | retval = -EIO; | ||
| 336 | goto out; | ||
| 337 | } | ||
| 338 | |||
| 339 | /* apply the mode switch */ | ||
| 340 | data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE; | ||
| 341 | |||
| 342 | /* write configuration */ | ||
| 343 | size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), | ||
| 344 | BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID, | ||
| 345 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
| 346 | BCM5974_WELLSPRING_MODE_REQUEST_VALUE, | ||
| 347 | BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); | ||
| 348 | |||
| 349 | if (size != 8) { | ||
| 350 | err("bcm5974: could not write to device"); | ||
| 351 | retval = -EIO; | ||
| 352 | goto out; | ||
| 353 | } | ||
| 354 | |||
| 355 | dprintk(2, "bcm5974: switched to wellspring mode.\n"); | ||
| 356 | |||
| 357 | out: | ||
| 358 | kfree(data); | ||
| 359 | return retval; | ||
| 360 | } | ||
| 361 | |||
| 362 | static void bcm5974_irq_button(struct urb *urb) | ||
| 363 | { | ||
| 364 | struct bcm5974 *dev = urb->context; | ||
| 365 | int error; | ||
| 366 | |||
| 367 | switch (urb->status) { | ||
| 368 | case 0: | ||
| 369 | break; | ||
| 370 | case -EOVERFLOW: | ||
| 371 | case -ECONNRESET: | ||
| 372 | case -ENOENT: | ||
| 373 | case -ESHUTDOWN: | ||
| 374 | dbg("bcm5974: button urb shutting down: %d", urb->status); | ||
| 375 | return; | ||
| 376 | default: | ||
| 377 | dbg("bcm5974: button urb status: %d", urb->status); | ||
| 378 | goto exit; | ||
| 379 | } | ||
| 380 | |||
| 381 | if (report_bt_state(dev, dev->bt_urb->actual_length)) | ||
| 382 | dprintk(1, "bcm5974: bad button package, length: %d\n", | ||
| 383 | dev->bt_urb->actual_length); | ||
| 384 | |||
| 385 | exit: | ||
| 386 | error = usb_submit_urb(dev->bt_urb, GFP_ATOMIC); | ||
| 387 | if (error) | ||
| 388 | err("bcm5974: button urb failed: %d", error); | ||
| 389 | } | ||
| 390 | |||
| 391 | static void bcm5974_irq_trackpad(struct urb *urb) | ||
| 392 | { | ||
| 393 | struct bcm5974 *dev = urb->context; | ||
| 394 | int error; | ||
| 395 | |||
| 396 | switch (urb->status) { | ||
| 397 | case 0: | ||
| 398 | break; | ||
| 399 | case -EOVERFLOW: | ||
| 400 | case -ECONNRESET: | ||
| 401 | case -ENOENT: | ||
| 402 | case -ESHUTDOWN: | ||
| 403 | dbg("bcm5974: trackpad urb shutting down: %d", urb->status); | ||
| 404 | return; | ||
| 405 | default: | ||
| 406 | dbg("bcm5974: trackpad urb status: %d", urb->status); | ||
| 407 | goto exit; | ||
| 408 | } | ||
| 409 | |||
| 410 | /* control response ignored */ | ||
| 411 | if (dev->tp_urb->actual_length == 2) | ||
| 412 | goto exit; | ||
| 413 | |||
| 414 | if (report_tp_state(dev, dev->tp_urb->actual_length)) | ||
| 415 | dprintk(1, "bcm5974: bad trackpad package, length: %d\n", | ||
| 416 | dev->tp_urb->actual_length); | ||
| 417 | |||
| 418 | exit: | ||
| 419 | error = usb_submit_urb(dev->tp_urb, GFP_ATOMIC); | ||
| 420 | if (error) | ||
| 421 | err("bcm5974: trackpad urb failed: %d", error); | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * The Wellspring trackpad, like many recent Apple trackpads, share | ||
| 426 | * the usb device with the keyboard. Since keyboards are usually | ||
| 427 | * handled by the HID system, the device ends up being handled by two | ||
| 428 | * modules. Setting up the device therefore becomes slightly | ||
| 429 | * complicated. To enable multitouch features, a mode switch is | ||
| 430 | * required, which is usually applied via the control interface of the | ||
| 431 | * device. It can be argued where this switch should take place. In | ||
| 432 | * some drivers, like appletouch, the switch is made during | ||
| 433 | * probe. However, the hid module may also alter the state of the | ||
| 434 | * device, resulting in trackpad malfunction under certain | ||
| 435 | * circumstances. To get around this problem, there is at least one | ||
| 436 | * example that utilizes the USB_QUIRK_RESET_RESUME quirk in order to | ||
| 437 | * recieve a reset_resume request rather than the normal resume. | ||
| 438 | * Since the implementation of reset_resume is equal to mode switch | ||
| 439 | * plus start_traffic, it seems easier to always do the switch when | ||
| 440 | * starting traffic on the device. | ||
| 441 | */ | ||
| 442 | static int bcm5974_start_traffic(struct bcm5974 *dev) | ||
| 443 | { | ||
| 444 | if (bcm5974_wellspring_mode(dev)) { | ||
| 445 | dprintk(1, "bcm5974: mode switch failed\n"); | ||
| 446 | goto error; | ||
| 447 | } | ||
| 448 | |||
| 449 | if (usb_submit_urb(dev->bt_urb, GFP_KERNEL)) | ||
| 450 | goto error; | ||
| 451 | |||
| 452 | if (usb_submit_urb(dev->tp_urb, GFP_KERNEL)) | ||
| 453 | goto err_kill_bt; | ||
| 454 | |||
| 455 | return 0; | ||
| 456 | |||
| 457 | err_kill_bt: | ||
| 458 | usb_kill_urb(dev->bt_urb); | ||
| 459 | error: | ||
| 460 | return -EIO; | ||
| 461 | } | ||
| 462 | |||
| 463 | static void bcm5974_pause_traffic(struct bcm5974 *dev) | ||
| 464 | { | ||
| 465 | usb_kill_urb(dev->tp_urb); | ||
| 466 | usb_kill_urb(dev->bt_urb); | ||
| 467 | } | ||
| 468 | |||
| 469 | /* | ||
| 470 | * The code below implements open/close and manual suspend/resume. | ||
| 471 | * All functions may be called in random order. | ||
| 472 | * | ||
| 473 | * Opening a suspended device fails with EACCES - permission denied. | ||
| 474 | * | ||
| 475 | * Failing a resume leaves the device resumed but closed. | ||
| 476 | */ | ||
| 477 | static int bcm5974_open(struct input_dev *input) | ||
| 478 | { | ||
| 479 | struct bcm5974 *dev = input_get_drvdata(input); | ||
| 480 | int error; | ||
| 481 | |||
| 482 | error = usb_autopm_get_interface(dev->intf); | ||
| 483 | if (error) | ||
| 484 | return error; | ||
| 485 | |||
| 486 | mutex_lock(&dev->pm_mutex); | ||
| 487 | |||
| 488 | error = bcm5974_start_traffic(dev); | ||
| 489 | if (!error) | ||
| 490 | dev->opened = 1; | ||
| 491 | |||
| 492 | mutex_unlock(&dev->pm_mutex); | ||
| 493 | |||
| 494 | if (error) | ||
| 495 | usb_autopm_put_interface(dev->intf); | ||
| 496 | |||
| 497 | return error; | ||
| 498 | } | ||
| 499 | |||
| 500 | static void bcm5974_close(struct input_dev *input) | ||
| 501 | { | ||
| 502 | struct bcm5974 *dev = input_get_drvdata(input); | ||
| 503 | |||
| 504 | mutex_lock(&dev->pm_mutex); | ||
| 505 | |||
| 506 | bcm5974_pause_traffic(dev); | ||
| 507 | dev->opened = 0; | ||
| 508 | |||
| 509 | mutex_unlock(&dev->pm_mutex); | ||
| 510 | |||
| 511 | usb_autopm_put_interface(dev->intf); | ||
| 512 | } | ||
| 513 | |||
| 514 | static int bcm5974_suspend(struct usb_interface *iface, pm_message_t message) | ||
| 515 | { | ||
| 516 | struct bcm5974 *dev = usb_get_intfdata(iface); | ||
| 517 | |||
| 518 | mutex_lock(&dev->pm_mutex); | ||
| 519 | |||
| 520 | if (dev->opened) | ||
| 521 | bcm5974_pause_traffic(dev); | ||
| 522 | |||
| 523 | mutex_unlock(&dev->pm_mutex); | ||
| 524 | |||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | |||
| 528 | static int bcm5974_resume(struct usb_interface *iface) | ||
| 529 | { | ||
| 530 | struct bcm5974 *dev = usb_get_intfdata(iface); | ||
| 531 | int error = 0; | ||
| 532 | |||
| 533 | mutex_lock(&dev->pm_mutex); | ||
| 534 | |||
| 535 | if (dev->opened) | ||
| 536 | error = bcm5974_start_traffic(dev); | ||
| 537 | |||
| 538 | mutex_unlock(&dev->pm_mutex); | ||
| 539 | |||
| 540 | return error; | ||
| 541 | } | ||
| 542 | |||
| 543 | static int bcm5974_probe(struct usb_interface *iface, | ||
| 544 | const struct usb_device_id *id) | ||
| 545 | { | ||
| 546 | struct usb_device *udev = interface_to_usbdev(iface); | ||
| 547 | const struct bcm5974_config *cfg; | ||
| 548 | struct bcm5974 *dev; | ||
| 549 | struct input_dev *input_dev; | ||
| 550 | int error = -ENOMEM; | ||
| 551 | |||
| 552 | /* find the product index */ | ||
| 553 | cfg = bcm5974_get_config(udev); | ||
| 554 | |||
| 555 | /* allocate memory for our device state and initialize it */ | ||
| 556 | dev = kzalloc(sizeof(struct bcm5974), GFP_KERNEL); | ||
| 557 | input_dev = input_allocate_device(); | ||
| 558 | if (!dev || !input_dev) { | ||
| 559 | err("bcm5974: out of memory"); | ||
| 560 | goto err_free_devs; | ||
| 561 | } | ||
| 562 | |||
| 563 | dev->udev = udev; | ||
| 564 | dev->intf = iface; | ||
| 565 | dev->input = input_dev; | ||
| 566 | dev->cfg = *cfg; | ||
| 567 | mutex_init(&dev->pm_mutex); | ||
| 568 | |||
| 569 | /* setup urbs */ | ||
| 570 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 571 | if (!dev->bt_urb) | ||
| 572 | goto err_free_devs; | ||
| 573 | |||
| 574 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 575 | if (!dev->tp_urb) | ||
| 576 | goto err_free_bt_urb; | ||
| 577 | |||
| 578 | dev->bt_data = usb_buffer_alloc(dev->udev, | ||
| 579 | dev->cfg.bt_datalen, GFP_KERNEL, | ||
| 580 | &dev->bt_urb->transfer_dma); | ||
| 581 | if (!dev->bt_data) | ||
| 582 | goto err_free_urb; | ||
| 583 | |||
| 584 | dev->tp_data = usb_buffer_alloc(dev->udev, | ||
| 585 | dev->cfg.tp_datalen, GFP_KERNEL, | ||
| 586 | &dev->tp_urb->transfer_dma); | ||
| 587 | if (!dev->tp_data) | ||
| 588 | goto err_free_bt_buffer; | ||
| 589 | |||
| 590 | usb_fill_int_urb(dev->bt_urb, udev, | ||
| 591 | usb_rcvintpipe(udev, cfg->bt_ep), | ||
| 592 | dev->bt_data, dev->cfg.bt_datalen, | ||
| 593 | bcm5974_irq_button, dev, 1); | ||
| 594 | |||
| 595 | usb_fill_int_urb(dev->tp_urb, udev, | ||
| 596 | usb_rcvintpipe(udev, cfg->tp_ep), | ||
| 597 | dev->tp_data, dev->cfg.tp_datalen, | ||
| 598 | bcm5974_irq_trackpad, dev, 1); | ||
| 599 | |||
| 600 | /* create bcm5974 device */ | ||
| 601 | usb_make_path(udev, dev->phys, sizeof(dev->phys)); | ||
| 602 | strlcat(dev->phys, "/input0", sizeof(dev->phys)); | ||
| 603 | |||
| 604 | input_dev->name = "bcm5974"; | ||
| 605 | input_dev->phys = dev->phys; | ||
| 606 | usb_to_input_id(dev->udev, &input_dev->id); | ||
| 607 | input_dev->dev.parent = &iface->dev; | ||
| 608 | |||
| 609 | input_set_drvdata(input_dev, dev); | ||
| 610 | |||
| 611 | input_dev->open = bcm5974_open; | ||
| 612 | input_dev->close = bcm5974_close; | ||
| 613 | |||
| 614 | setup_events_to_report(input_dev, cfg); | ||
| 615 | |||
| 616 | error = input_register_device(dev->input); | ||
| 617 | if (error) | ||
| 618 | goto err_free_buffer; | ||
| 619 | |||
| 620 | /* save our data pointer in this interface device */ | ||
| 621 | usb_set_intfdata(iface, dev); | ||
| 622 | |||
| 623 | return 0; | ||
| 624 | |||
| 625 | err_free_buffer: | ||
| 626 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | ||
| 627 | dev->tp_data, dev->tp_urb->transfer_dma); | ||
| 628 | err_free_bt_buffer: | ||
| 629 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | ||
| 630 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
| 631 | err_free_urb: | ||
| 632 | usb_free_urb(dev->tp_urb); | ||
| 633 | err_free_bt_urb: | ||
| 634 | usb_free_urb(dev->bt_urb); | ||
| 635 | err_free_devs: | ||
| 636 | usb_set_intfdata(iface, NULL); | ||
| 637 | input_free_device(input_dev); | ||
| 638 | kfree(dev); | ||
| 639 | return error; | ||
| 640 | } | ||
| 641 | |||
| 642 | static void bcm5974_disconnect(struct usb_interface *iface) | ||
| 643 | { | ||
| 644 | struct bcm5974 *dev = usb_get_intfdata(iface); | ||
| 645 | |||
| 646 | usb_set_intfdata(iface, NULL); | ||
| 647 | |||
| 648 | input_unregister_device(dev->input); | ||
| 649 | usb_buffer_free(dev->udev, dev->cfg.tp_datalen, | ||
| 650 | dev->tp_data, dev->tp_urb->transfer_dma); | ||
| 651 | usb_buffer_free(dev->udev, dev->cfg.bt_datalen, | ||
| 652 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
| 653 | usb_free_urb(dev->tp_urb); | ||
| 654 | usb_free_urb(dev->bt_urb); | ||
| 655 | kfree(dev); | ||
| 656 | } | ||
| 657 | |||
| 658 | static struct usb_driver bcm5974_driver = { | ||
| 659 | .name = "bcm5974", | ||
| 660 | .probe = bcm5974_probe, | ||
| 661 | .disconnect = bcm5974_disconnect, | ||
| 662 | .suspend = bcm5974_suspend, | ||
| 663 | .resume = bcm5974_resume, | ||
| 664 | .reset_resume = bcm5974_resume, | ||
| 665 | .id_table = bcm5974_table, | ||
| 666 | .supports_autosuspend = 1, | ||
| 667 | }; | ||
| 668 | |||
| 669 | static int __init bcm5974_init(void) | ||
| 670 | { | ||
| 671 | return usb_register(&bcm5974_driver); | ||
| 672 | } | ||
| 673 | |||
| 674 | static void __exit bcm5974_exit(void) | ||
| 675 | { | ||
| 676 | usb_deregister(&bcm5974_driver); | ||
| 677 | } | ||
| 678 | |||
| 679 | module_init(bcm5974_init); | ||
| 680 | module_exit(bcm5974_exit); | ||
| 681 | |||
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index fe732a574ec2..3282b741e246 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h | |||
| @@ -394,6 +394,13 @@ static struct dmi_system_id __initdata i8042_dmi_dritek_table[] = { | |||
| 394 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), | 394 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2490"), |
| 395 | }, | 395 | }, |
| 396 | }, | 396 | }, |
| 397 | { | ||
| 398 | .ident = "Acer TravelMate 4280", | ||
| 399 | .matches = { | ||
| 400 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
| 401 | DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"), | ||
| 402 | }, | ||
| 403 | }, | ||
| 397 | { } | 404 | { } |
| 398 | }; | 405 | }; |
| 399 | 406 | ||
diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 0ed044d5e685..765007899d9a 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c | |||
| @@ -269,8 +269,8 @@ static int xps2_setup(struct device *dev, struct resource *regs_res, | |||
| 269 | * we have the PS2 in a good state */ | 269 | * we have the PS2 in a good state */ |
| 270 | out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); | 270 | out_be32(drvdata->base_address + XPS2_SRST_OFFSET, XPS2_SRST_RESET); |
| 271 | 271 | ||
| 272 | dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%08X, irq=%d\n", | 272 | dev_info(dev, "Xilinx PS2 at 0x%08X mapped to 0x%p, irq=%d\n", |
| 273 | drvdata->phys_addr, (u32)drvdata->base_address, drvdata->irq); | 273 | drvdata->phys_addr, drvdata->base_address, drvdata->irq); |
| 274 | 274 | ||
| 275 | serio = &drvdata->serio; | 275 | serio = &drvdata->serio; |
| 276 | serio->id.type = SERIO_8042; | 276 | serio->id.type = SERIO_8042; |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 6e60a97a234c..25287e80e236 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -249,29 +249,26 @@ config TOUCHSCREEN_WM97XX | |||
| 249 | config TOUCHSCREEN_WM9705 | 249 | config TOUCHSCREEN_WM9705 |
| 250 | bool "WM9705 Touchscreen interface support" | 250 | bool "WM9705 Touchscreen interface support" |
| 251 | depends on TOUCHSCREEN_WM97XX | 251 | depends on TOUCHSCREEN_WM97XX |
| 252 | default y | ||
| 252 | help | 253 | help |
| 253 | Say Y here if you have a Wolfson Microelectronics WM9705 | 254 | Say Y here to enable support for the Wolfson Microelectronics |
| 254 | touchscreen controller connected to your system. | 255 | WM9705 touchscreen controller. |
| 255 | |||
| 256 | If unsure, say N. | ||
| 257 | 256 | ||
| 258 | config TOUCHSCREEN_WM9712 | 257 | config TOUCHSCREEN_WM9712 |
| 259 | bool "WM9712 Touchscreen interface support" | 258 | bool "WM9712 Touchscreen interface support" |
| 260 | depends on TOUCHSCREEN_WM97XX | 259 | depends on TOUCHSCREEN_WM97XX |
| 260 | default y | ||
| 261 | help | 261 | help |
| 262 | Say Y here if you have a Wolfson Microelectronics WM9712 | 262 | Say Y here to enable support for the Wolfson Microelectronics |
| 263 | touchscreen controller connected to your system. | 263 | WM9712 touchscreen controller. |
| 264 | |||
| 265 | If unsure, say N. | ||
| 266 | 264 | ||
| 267 | config TOUCHSCREEN_WM9713 | 265 | config TOUCHSCREEN_WM9713 |
| 268 | bool "WM9713 Touchscreen interface support" | 266 | bool "WM9713 Touchscreen interface support" |
| 269 | depends on TOUCHSCREEN_WM97XX | 267 | depends on TOUCHSCREEN_WM97XX |
| 268 | default y | ||
| 270 | help | 269 | help |
| 271 | Say Y here if you have a Wolfson Microelectronics WM9713 touchscreen | 270 | Say Y here to enable support for the Wolfson Microelectronics |
| 272 | controller connected to your system. | 271 | WM9713 touchscreen controller. |
| 273 | |||
| 274 | If unsure, say N. | ||
| 275 | 272 | ||
| 276 | config TOUCHSCREEN_WM97XX_MAINSTONE | 273 | config TOUCHSCREEN_WM97XX_MAINSTONE |
| 277 | tristate "WM97xx Mainstone accelerated touch" | 274 | tristate "WM97xx Mainstone accelerated touch" |
diff --git a/drivers/md/md.c b/drivers/md/md.c index c7aae66c6f9b..8cfadc5bd2ba 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -2393,6 +2393,8 @@ static void analyze_sbs(mddev_t * mddev) | |||
| 2393 | 2393 | ||
| 2394 | } | 2394 | } |
| 2395 | 2395 | ||
| 2396 | static void md_safemode_timeout(unsigned long data); | ||
| 2397 | |||
| 2396 | static ssize_t | 2398 | static ssize_t |
| 2397 | safe_delay_show(mddev_t *mddev, char *page) | 2399 | safe_delay_show(mddev_t *mddev, char *page) |
| 2398 | { | 2400 | { |
| @@ -2432,9 +2434,12 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len) | |||
| 2432 | if (msec == 0) | 2434 | if (msec == 0) |
| 2433 | mddev->safemode_delay = 0; | 2435 | mddev->safemode_delay = 0; |
| 2434 | else { | 2436 | else { |
| 2437 | unsigned long old_delay = mddev->safemode_delay; | ||
| 2435 | mddev->safemode_delay = (msec*HZ)/1000; | 2438 | mddev->safemode_delay = (msec*HZ)/1000; |
| 2436 | if (mddev->safemode_delay == 0) | 2439 | if (mddev->safemode_delay == 0) |
| 2437 | mddev->safemode_delay = 1; | 2440 | mddev->safemode_delay = 1; |
| 2441 | if (mddev->safemode_delay < old_delay) | ||
| 2442 | md_safemode_timeout((unsigned long)mddev); | ||
| 2438 | } | 2443 | } |
| 2439 | return len; | 2444 | return len; |
| 2440 | } | 2445 | } |
| @@ -4634,6 +4639,11 @@ static int update_size(mddev_t *mddev, sector_t num_sectors) | |||
| 4634 | */ | 4639 | */ |
| 4635 | if (mddev->sync_thread) | 4640 | if (mddev->sync_thread) |
| 4636 | return -EBUSY; | 4641 | return -EBUSY; |
| 4642 | if (mddev->bitmap) | ||
| 4643 | /* Sorry, cannot grow a bitmap yet, just remove it, | ||
| 4644 | * grow, and re-add. | ||
| 4645 | */ | ||
| 4646 | return -EBUSY; | ||
| 4637 | rdev_for_each(rdev, tmp, mddev) { | 4647 | rdev_for_each(rdev, tmp, mddev) { |
| 4638 | sector_t avail; | 4648 | sector_t avail; |
| 4639 | avail = rdev->size * 2; | 4649 | avail = rdev->size * 2; |
| @@ -5993,7 +6003,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
| 5993 | } | 6003 | } |
| 5994 | } | 6004 | } |
| 5995 | 6005 | ||
| 5996 | if (mddev->degraded) { | 6006 | if (mddev->degraded && ! mddev->ro) { |
| 5997 | rdev_for_each(rdev, rtmp, mddev) { | 6007 | rdev_for_each(rdev, rtmp, mddev) { |
| 5998 | if (rdev->raid_disk >= 0 && | 6008 | if (rdev->raid_disk >= 0 && |
| 5999 | !test_bit(In_sync, &rdev->flags) && | 6009 | !test_bit(In_sync, &rdev->flags) && |
| @@ -6067,6 +6077,8 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6067 | flush_signals(current); | 6077 | flush_signals(current); |
| 6068 | } | 6078 | } |
| 6069 | 6079 | ||
| 6080 | if (mddev->ro && !test_bit(MD_RECOVERY_NEEDED, &mddev->recovery)) | ||
| 6081 | return; | ||
| 6070 | if ( ! ( | 6082 | if ( ! ( |
| 6071 | (mddev->flags && !mddev->external) || | 6083 | (mddev->flags && !mddev->external) || |
| 6072 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 6084 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
| @@ -6080,6 +6092,15 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6080 | if (mddev_trylock(mddev)) { | 6092 | if (mddev_trylock(mddev)) { |
| 6081 | int spares = 0; | 6093 | int spares = 0; |
| 6082 | 6094 | ||
| 6095 | if (mddev->ro) { | ||
| 6096 | /* Only thing we do on a ro array is remove | ||
| 6097 | * failed devices. | ||
| 6098 | */ | ||
| 6099 | remove_and_add_spares(mddev); | ||
| 6100 | clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | ||
| 6101 | goto unlock; | ||
| 6102 | } | ||
| 6103 | |||
| 6083 | if (!mddev->external) { | 6104 | if (!mddev->external) { |
| 6084 | int did_change = 0; | 6105 | int did_change = 0; |
| 6085 | spin_lock_irq(&mddev->write_lock); | 6106 | spin_lock_irq(&mddev->write_lock); |
| @@ -6117,7 +6138,8 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6117 | /* resync has finished, collect result */ | 6138 | /* resync has finished, collect result */ |
| 6118 | md_unregister_thread(mddev->sync_thread); | 6139 | md_unregister_thread(mddev->sync_thread); |
| 6119 | mddev->sync_thread = NULL; | 6140 | mddev->sync_thread = NULL; |
| 6120 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { | 6141 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) && |
| 6142 | !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { | ||
| 6121 | /* success...*/ | 6143 | /* success...*/ |
| 6122 | /* activate any spares */ | 6144 | /* activate any spares */ |
| 6123 | if (mddev->pers->spare_active(mddev)) | 6145 | if (mddev->pers->spare_active(mddev)) |
| @@ -6169,6 +6191,7 @@ void md_check_recovery(mddev_t *mddev) | |||
| 6169 | } else if ((spares = remove_and_add_spares(mddev))) { | 6191 | } else if ((spares = remove_and_add_spares(mddev))) { |
| 6170 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6192 | clear_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
| 6171 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 6193 | clear_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
| 6194 | clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); | ||
| 6172 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); | 6195 | set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); |
| 6173 | } else if (mddev->recovery_cp < MaxSector) { | 6196 | } else if (mddev->recovery_cp < MaxSector) { |
| 6174 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 6197 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
| @@ -6232,7 +6255,11 @@ static int md_notify_reboot(struct notifier_block *this, | |||
| 6232 | 6255 | ||
| 6233 | for_each_mddev(mddev, tmp) | 6256 | for_each_mddev(mddev, tmp) |
| 6234 | if (mddev_trylock(mddev)) { | 6257 | if (mddev_trylock(mddev)) { |
| 6235 | do_md_stop (mddev, 1, 0); | 6258 | /* Force a switch to readonly even array |
| 6259 | * appears to still be in use. Hence | ||
| 6260 | * the '100'. | ||
| 6261 | */ | ||
| 6262 | do_md_stop (mddev, 1, 100); | ||
| 6236 | mddev_unlock(mddev); | 6263 | mddev_unlock(mddev); |
| 6237 | } | 6264 | } |
| 6238 | /* | 6265 | /* |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index d41bebb6da0f..e34cd0e62473 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -76,11 +76,13 @@ static void r10bio_pool_free(void *r10_bio, void *data) | |||
| 76 | kfree(r10_bio); | 76 | kfree(r10_bio); |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | /* Maximum size of each resync request */ | ||
| 79 | #define RESYNC_BLOCK_SIZE (64*1024) | 80 | #define RESYNC_BLOCK_SIZE (64*1024) |
| 80 | //#define RESYNC_BLOCK_SIZE PAGE_SIZE | ||
| 81 | #define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9) | ||
| 82 | #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) | 81 | #define RESYNC_PAGES ((RESYNC_BLOCK_SIZE + PAGE_SIZE-1) / PAGE_SIZE) |
| 83 | #define RESYNC_WINDOW (2048*1024) | 82 | /* amount of memory to reserve for resync requests */ |
| 83 | #define RESYNC_WINDOW (1024*1024) | ||
| 84 | /* maximum number of concurrent requests, memory permitting */ | ||
| 85 | #define RESYNC_DEPTH (32*1024*1024/RESYNC_BLOCK_SIZE) | ||
| 84 | 86 | ||
| 85 | /* | 87 | /* |
| 86 | * When performing a resync, we need to read and compare, so | 88 | * When performing a resync, we need to read and compare, so |
| @@ -690,7 +692,6 @@ static int flush_pending_writes(conf_t *conf) | |||
| 690 | * there is no normal IO happeing. It must arrange to call | 692 | * there is no normal IO happeing. It must arrange to call |
| 691 | * lower_barrier when the particular background IO completes. | 693 | * lower_barrier when the particular background IO completes. |
| 692 | */ | 694 | */ |
| 693 | #define RESYNC_DEPTH 32 | ||
| 694 | 695 | ||
| 695 | static void raise_barrier(conf_t *conf, int force) | 696 | static void raise_barrier(conf_t *conf, int force) |
| 696 | { | 697 | { |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 40e939675657..224de022e7c5 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -2568,10 +2568,10 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
| 2568 | if (dev->written) | 2568 | if (dev->written) |
| 2569 | s.written++; | 2569 | s.written++; |
| 2570 | rdev = rcu_dereference(conf->disks[i].rdev); | 2570 | rdev = rcu_dereference(conf->disks[i].rdev); |
| 2571 | if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | 2571 | if (blocked_rdev == NULL && |
| 2572 | rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | ||
| 2572 | blocked_rdev = rdev; | 2573 | blocked_rdev = rdev; |
| 2573 | atomic_inc(&rdev->nr_pending); | 2574 | atomic_inc(&rdev->nr_pending); |
| 2574 | break; | ||
| 2575 | } | 2575 | } |
| 2576 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { | 2576 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
| 2577 | /* The ReadError flag will just be confusing now */ | 2577 | /* The ReadError flag will just be confusing now */ |
| @@ -2588,8 +2588,14 @@ static bool handle_stripe5(struct stripe_head *sh) | |||
| 2588 | rcu_read_unlock(); | 2588 | rcu_read_unlock(); |
| 2589 | 2589 | ||
| 2590 | if (unlikely(blocked_rdev)) { | 2590 | if (unlikely(blocked_rdev)) { |
| 2591 | set_bit(STRIPE_HANDLE, &sh->state); | 2591 | if (s.syncing || s.expanding || s.expanded || |
| 2592 | goto unlock; | 2592 | s.to_write || s.written) { |
| 2593 | set_bit(STRIPE_HANDLE, &sh->state); | ||
| 2594 | goto unlock; | ||
| 2595 | } | ||
| 2596 | /* There is nothing for the blocked_rdev to block */ | ||
| 2597 | rdev_dec_pending(blocked_rdev, conf->mddev); | ||
| 2598 | blocked_rdev = NULL; | ||
| 2593 | } | 2599 | } |
| 2594 | 2600 | ||
| 2595 | if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { | 2601 | if (s.to_fill && !test_bit(STRIPE_BIOFILL_RUN, &sh->state)) { |
| @@ -2832,10 +2838,10 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
| 2832 | if (dev->written) | 2838 | if (dev->written) |
| 2833 | s.written++; | 2839 | s.written++; |
| 2834 | rdev = rcu_dereference(conf->disks[i].rdev); | 2840 | rdev = rcu_dereference(conf->disks[i].rdev); |
| 2835 | if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | 2841 | if (blocked_rdev == NULL && |
| 2842 | rdev && unlikely(test_bit(Blocked, &rdev->flags))) { | ||
| 2836 | blocked_rdev = rdev; | 2843 | blocked_rdev = rdev; |
| 2837 | atomic_inc(&rdev->nr_pending); | 2844 | atomic_inc(&rdev->nr_pending); |
| 2838 | break; | ||
| 2839 | } | 2845 | } |
| 2840 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { | 2846 | if (!rdev || !test_bit(In_sync, &rdev->flags)) { |
| 2841 | /* The ReadError flag will just be confusing now */ | 2847 | /* The ReadError flag will just be confusing now */ |
| @@ -2853,9 +2859,16 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) | |||
| 2853 | rcu_read_unlock(); | 2859 | rcu_read_unlock(); |
| 2854 | 2860 | ||
| 2855 | if (unlikely(blocked_rdev)) { | 2861 | if (unlikely(blocked_rdev)) { |
| 2856 | set_bit(STRIPE_HANDLE, &sh->state); | 2862 | if (s.syncing || s.expanding || s.expanded || |
| 2857 | goto unlock; | 2863 | s.to_write || s.written) { |
| 2864 | set_bit(STRIPE_HANDLE, &sh->state); | ||
| 2865 | goto unlock; | ||
| 2866 | } | ||
| 2867 | /* There is nothing for the blocked_rdev to block */ | ||
| 2868 | rdev_dec_pending(blocked_rdev, conf->mddev); | ||
| 2869 | blocked_rdev = NULL; | ||
| 2858 | } | 2870 | } |
| 2871 | |||
| 2859 | pr_debug("locked=%d uptodate=%d to_read=%d" | 2872 | pr_debug("locked=%d uptodate=%d to_read=%d" |
| 2860 | " to_write=%d failed=%d failed_num=%d,%d\n", | 2873 | " to_write=%d failed=%d failed_num=%d,%d\n", |
| 2861 | s.locked, s.uptodate, s.to_read, s.to_write, s.failed, | 2874 | s.locked, s.uptodate, s.to_read, s.to_write, s.failed, |
| @@ -4446,6 +4459,9 @@ static int raid5_check_reshape(mddev_t *mddev) | |||
| 4446 | return -EINVAL; /* Cannot shrink array or change level yet */ | 4459 | return -EINVAL; /* Cannot shrink array or change level yet */ |
| 4447 | if (mddev->delta_disks == 0) | 4460 | if (mddev->delta_disks == 0) |
| 4448 | return 0; /* nothing to do */ | 4461 | return 0; /* nothing to do */ |
| 4462 | if (mddev->bitmap) | ||
| 4463 | /* Cannot grow a bitmap yet */ | ||
| 4464 | return -EBUSY; | ||
| 4449 | 4465 | ||
| 4450 | /* Can only proceed if there are plenty of stripe_heads. | 4466 | /* Can only proceed if there are plenty of stripe_heads. |
| 4451 | * We need a minimum of one full stripe,, and for sensible progress | 4467 | * We need a minimum of one full stripe,, and for sensible progress |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 964124b60db2..75e86865234c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -226,10 +226,11 @@ EXPORT_SYMBOL_GPL(spi_alloc_device); | |||
| 226 | * Companion function to spi_alloc_device. Devices allocated with | 226 | * Companion function to spi_alloc_device. Devices allocated with |
| 227 | * spi_alloc_device can be added onto the spi bus with this function. | 227 | * spi_alloc_device can be added onto the spi bus with this function. |
| 228 | * | 228 | * |
| 229 | * Returns 0 on success; non-zero on failure | 229 | * Returns 0 on success; negative errno on failure |
| 230 | */ | 230 | */ |
| 231 | int spi_add_device(struct spi_device *spi) | 231 | int spi_add_device(struct spi_device *spi) |
| 232 | { | 232 | { |
| 233 | static DEFINE_MUTEX(spi_add_lock); | ||
| 233 | struct device *dev = spi->master->dev.parent; | 234 | struct device *dev = spi->master->dev.parent; |
| 234 | int status; | 235 | int status; |
| 235 | 236 | ||
| @@ -246,26 +247,43 @@ int spi_add_device(struct spi_device *spi) | |||
| 246 | "%s.%u", spi->master->dev.bus_id, | 247 | "%s.%u", spi->master->dev.bus_id, |
| 247 | spi->chip_select); | 248 | spi->chip_select); |
| 248 | 249 | ||
| 249 | /* drivers may modify this initial i/o setup */ | 250 | |
| 251 | /* We need to make sure there's no other device with this | ||
| 252 | * chipselect **BEFORE** we call setup(), else we'll trash | ||
| 253 | * its configuration. Lock against concurrent add() calls. | ||
| 254 | */ | ||
| 255 | mutex_lock(&spi_add_lock); | ||
| 256 | |||
| 257 | if (bus_find_device_by_name(&spi_bus_type, NULL, spi->dev.bus_id) | ||
| 258 | != NULL) { | ||
| 259 | dev_err(dev, "chipselect %d already in use\n", | ||
| 260 | spi->chip_select); | ||
| 261 | status = -EBUSY; | ||
| 262 | goto done; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* Drivers may modify this initial i/o setup, but will | ||
| 266 | * normally rely on the device being setup. Devices | ||
| 267 | * using SPI_CS_HIGH can't coexist well otherwise... | ||
| 268 | */ | ||
| 250 | status = spi->master->setup(spi); | 269 | status = spi->master->setup(spi); |
| 251 | if (status < 0) { | 270 | if (status < 0) { |
| 252 | dev_err(dev, "can't %s %s, status %d\n", | 271 | dev_err(dev, "can't %s %s, status %d\n", |
| 253 | "setup", spi->dev.bus_id, status); | 272 | "setup", spi->dev.bus_id, status); |
| 254 | return status; | 273 | goto done; |
| 255 | } | 274 | } |
| 256 | 275 | ||
| 257 | /* driver core catches callers that misbehave by defining | 276 | /* Device may be bound to an active driver when this returns */ |
| 258 | * devices that already exist. | ||
| 259 | */ | ||
| 260 | status = device_add(&spi->dev); | 277 | status = device_add(&spi->dev); |
| 261 | if (status < 0) { | 278 | if (status < 0) |
| 262 | dev_err(dev, "can't %s %s, status %d\n", | 279 | dev_err(dev, "can't %s %s, status %d\n", |
| 263 | "add", spi->dev.bus_id, status); | 280 | "add", spi->dev.bus_id, status); |
| 264 | return status; | 281 | else |
| 265 | } | 282 | dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); |
| 266 | 283 | ||
| 267 | dev_dbg(dev, "registered child %s\n", spi->dev.bus_id); | 284 | done: |
| 268 | return 0; | 285 | mutex_unlock(&spi_add_lock); |
| 286 | return status; | ||
| 269 | } | 287 | } |
| 270 | EXPORT_SYMBOL_GPL(spi_add_device); | 288 | EXPORT_SYMBOL_GPL(spi_add_device); |
| 271 | 289 | ||
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c index bd320a2bfb7c..fb51197d1c98 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fsl-diu-fb.c | |||
| @@ -479,6 +479,10 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var, | |||
| 479 | base_plane_width = machine_data->fsl_diu_info[0]->var.xres; | 479 | base_plane_width = machine_data->fsl_diu_info[0]->var.xres; |
| 480 | base_plane_height = machine_data->fsl_diu_info[0]->var.yres; | 480 | base_plane_height = machine_data->fsl_diu_info[0]->var.yres; |
| 481 | 481 | ||
| 482 | if (mfbi->x_aoi_d < 0) | ||
| 483 | mfbi->x_aoi_d = 0; | ||
| 484 | if (mfbi->y_aoi_d < 0) | ||
| 485 | mfbi->y_aoi_d = 0; | ||
| 482 | switch (index) { | 486 | switch (index) { |
| 483 | case 0: | 487 | case 0: |
| 484 | if (mfbi->x_aoi_d != 0) | 488 | if (mfbi->x_aoi_d != 0) |
| @@ -778,6 +782,22 @@ static void unmap_video_memory(struct fb_info *info) | |||
| 778 | } | 782 | } |
| 779 | 783 | ||
| 780 | /* | 784 | /* |
| 785 | * Using the fb_var_screeninfo in fb_info we set the aoi of this | ||
| 786 | * particular framebuffer. It is a light version of fsl_diu_set_par. | ||
| 787 | */ | ||
| 788 | static int fsl_diu_set_aoi(struct fb_info *info) | ||
| 789 | { | ||
| 790 | struct fb_var_screeninfo *var = &info->var; | ||
| 791 | struct mfb_info *mfbi = info->par; | ||
| 792 | struct diu_ad *ad = mfbi->ad; | ||
| 793 | |||
| 794 | /* AOI should not be greater than display size */ | ||
| 795 | ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); | ||
| 796 | ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); | ||
| 797 | return 0; | ||
| 798 | } | ||
| 799 | |||
| 800 | /* | ||
| 781 | * Using the fb_var_screeninfo in fb_info we set the resolution of this | 801 | * Using the fb_var_screeninfo in fb_info we set the resolution of this |
| 782 | * particular framebuffer. This function alters the fb_fix_screeninfo stored | 802 | * particular framebuffer. This function alters the fb_fix_screeninfo stored |
| 783 | * in fb_info. It does not alter var in fb_info since we are using that | 803 | * in fb_info. It does not alter var in fb_info since we are using that |
| @@ -817,11 +837,11 @@ static int fsl_diu_set_par(struct fb_info *info) | |||
| 817 | diu_ops.get_pixel_format(var->bits_per_pixel, | 837 | diu_ops.get_pixel_format(var->bits_per_pixel, |
| 818 | machine_data->monitor_port); | 838 | machine_data->monitor_port); |
| 819 | ad->addr = cpu_to_le32(info->fix.smem_start); | 839 | ad->addr = cpu_to_le32(info->fix.smem_start); |
| 820 | ad->src_size_g_alpha = cpu_to_le32((var->yres << 12) | | 840 | ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) | |
| 821 | var->xres) | mfbi->g_alpha; | 841 | var->xres_virtual) | mfbi->g_alpha; |
| 822 | /* fix me. AOI should not be greater than display size */ | 842 | /* AOI should not be greater than display size */ |
| 823 | ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres); | 843 | ad->aoi_size = cpu_to_le32((var->yres << 16) | var->xres); |
| 824 | ad->offset_xyi = 0; | 844 | ad->offset_xyi = cpu_to_le32((var->yoffset << 16) | var->xoffset); |
| 825 | ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); | 845 | ad->offset_xyd = cpu_to_le32((mfbi->y_aoi_d << 16) | mfbi->x_aoi_d); |
| 826 | 846 | ||
| 827 | /* Disable chroma keying function */ | 847 | /* Disable chroma keying function */ |
| @@ -921,6 +941,8 @@ static int fsl_diu_pan_display(struct fb_var_screeninfo *var, | |||
| 921 | else | 941 | else |
| 922 | info->var.vmode &= ~FB_VMODE_YWRAP; | 942 | info->var.vmode &= ~FB_VMODE_YWRAP; |
| 923 | 943 | ||
| 944 | fsl_diu_set_aoi(info); | ||
| 945 | |||
| 924 | return 0; | 946 | return 0; |
| 925 | } | 947 | } |
| 926 | 948 | ||
| @@ -989,7 +1011,7 @@ static int fsl_diu_ioctl(struct fb_info *info, unsigned int cmd, | |||
| 989 | pr_debug("set AOI display offset of index %d to (%d,%d)\n", | 1011 | pr_debug("set AOI display offset of index %d to (%d,%d)\n", |
| 990 | mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d); | 1012 | mfbi->index, aoi_d.x_aoi_d, aoi_d.y_aoi_d); |
| 991 | fsl_diu_check_var(&info->var, info); | 1013 | fsl_diu_check_var(&info->var, info); |
| 992 | fsl_diu_set_par(info); | 1014 | fsl_diu_set_aoi(info); |
| 993 | break; | 1015 | break; |
| 994 | case MFB_GET_AOID: | 1016 | case MFB_GET_AOID: |
| 995 | aoi_d.x_aoi_d = mfbi->x_aoi_d; | 1017 | aoi_d.x_aoi_d = mfbi->x_aoi_d; |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e8da4ee761b5..25ecbd5b0404 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -175,6 +175,8 @@ out_no_root: | |||
| 175 | if (inode) | 175 | if (inode) |
| 176 | iput(inode); | 176 | iput(inode); |
| 177 | 177 | ||
| 178 | cifs_umount(sb, cifs_sb); | ||
| 179 | |||
| 178 | out_mount_failed: | 180 | out_mount_failed: |
| 179 | if (cifs_sb) { | 181 | if (cifs_sb) { |
| 180 | #ifdef CONFIG_CIFS_DFS_UPCALL | 182 | #ifdef CONFIG_CIFS_DFS_UPCALL |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 28a22092d450..848286861c31 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -649,6 +649,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
| 649 | inode->i_fop = &simple_dir_operations; | 649 | inode->i_fop = &simple_dir_operations; |
| 650 | inode->i_uid = cifs_sb->mnt_uid; | 650 | inode->i_uid = cifs_sb->mnt_uid; |
| 651 | inode->i_gid = cifs_sb->mnt_gid; | 651 | inode->i_gid = cifs_sb->mnt_gid; |
| 652 | } else if (rc) { | ||
| 652 | _FreeXid(xid); | 653 | _FreeXid(xid); |
| 653 | iget_failed(inode); | 654 | iget_failed(inode); |
| 654 | return ERR_PTR(rc); | 655 | return ERR_PTR(rc); |
diff --git a/fs/inode.c b/fs/inode.c index b6726f644530..0487ddba1397 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -166,6 +166,7 @@ static struct inode *alloc_inode(struct super_block *sb) | |||
| 166 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE); | 166 | mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE); |
| 167 | mapping->assoc_mapping = NULL; | 167 | mapping->assoc_mapping = NULL; |
| 168 | mapping->backing_dev_info = &default_backing_dev_info; | 168 | mapping->backing_dev_info = &default_backing_dev_info; |
| 169 | mapping->writeback_index = 0; | ||
| 169 | 170 | ||
| 170 | /* | 171 | /* |
| 171 | * If the block_device provides a backing_dev_info for client | 172 | * If the block_device provides a backing_dev_info for client |
diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c index 697663b01bae..e1c0ec0ae989 100644 --- a/fs/omfs/bitmap.c +++ b/fs/omfs/bitmap.c | |||
| @@ -92,7 +92,7 @@ int omfs_allocate_block(struct super_block *sb, u64 block) | |||
| 92 | struct buffer_head *bh; | 92 | struct buffer_head *bh; |
| 93 | struct omfs_sb_info *sbi = OMFS_SB(sb); | 93 | struct omfs_sb_info *sbi = OMFS_SB(sb); |
| 94 | int bits_per_entry = 8 * sb->s_blocksize; | 94 | int bits_per_entry = 8 * sb->s_blocksize; |
| 95 | int map, bit; | 95 | unsigned int map, bit; |
| 96 | int ret = 0; | 96 | int ret = 0; |
| 97 | u64 tmp; | 97 | u64 tmp; |
| 98 | 98 | ||
| @@ -176,7 +176,8 @@ int omfs_clear_range(struct super_block *sb, u64 block, int count) | |||
| 176 | struct omfs_sb_info *sbi = OMFS_SB(sb); | 176 | struct omfs_sb_info *sbi = OMFS_SB(sb); |
| 177 | int bits_per_entry = 8 * sb->s_blocksize; | 177 | int bits_per_entry = 8 * sb->s_blocksize; |
| 178 | u64 tmp; | 178 | u64 tmp; |
| 179 | int map, bit, ret; | 179 | unsigned int map, bit; |
| 180 | int ret; | ||
| 180 | 181 | ||
| 181 | tmp = block; | 182 | tmp = block; |
| 182 | bit = do_div(tmp, bits_per_entry); | 183 | bit = do_div(tmp, bits_per_entry); |
diff --git a/fs/omfs/file.c b/fs/omfs/file.c index 7e2499053e4d..834b2331f6b3 100644 --- a/fs/omfs/file.c +++ b/fs/omfs/file.c | |||
| @@ -26,6 +26,13 @@ static int omfs_sync_file(struct file *file, struct dentry *dentry, | |||
| 26 | return err ? -EIO : 0; | 26 | return err ? -EIO : 0; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | static u32 omfs_max_extents(struct omfs_sb_info *sbi, int offset) | ||
| 30 | { | ||
| 31 | return (sbi->s_sys_blocksize - offset - | ||
| 32 | sizeof(struct omfs_extent)) / | ||
| 33 | sizeof(struct omfs_extent_entry) + 1; | ||
| 34 | } | ||
| 35 | |||
| 29 | void omfs_make_empty_table(struct buffer_head *bh, int offset) | 36 | void omfs_make_empty_table(struct buffer_head *bh, int offset) |
| 30 | { | 37 | { |
| 31 | struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; | 38 | struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; |
| @@ -45,6 +52,7 @@ int omfs_shrink_inode(struct inode *inode) | |||
| 45 | struct buffer_head *bh; | 52 | struct buffer_head *bh; |
| 46 | u64 next, last; | 53 | u64 next, last; |
| 47 | u32 extent_count; | 54 | u32 extent_count; |
| 55 | u32 max_extents; | ||
| 48 | int ret; | 56 | int ret; |
| 49 | 57 | ||
| 50 | /* traverse extent table, freeing each entry that is greater | 58 | /* traverse extent table, freeing each entry that is greater |
| @@ -62,15 +70,18 @@ int omfs_shrink_inode(struct inode *inode) | |||
| 62 | goto out; | 70 | goto out; |
| 63 | 71 | ||
| 64 | oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); | 72 | oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); |
| 73 | max_extents = omfs_max_extents(sbi, OMFS_EXTENT_START); | ||
| 65 | 74 | ||
| 66 | for (;;) { | 75 | for (;;) { |
| 67 | 76 | ||
| 68 | if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) { | 77 | if (omfs_is_bad(sbi, (struct omfs_header *) bh->b_data, next)) |
| 69 | brelse(bh); | 78 | goto out_brelse; |
| 70 | goto out; | ||
| 71 | } | ||
| 72 | 79 | ||
| 73 | extent_count = be32_to_cpu(oe->e_extent_count); | 80 | extent_count = be32_to_cpu(oe->e_extent_count); |
| 81 | |||
| 82 | if (extent_count > max_extents) | ||
| 83 | goto out_brelse; | ||
| 84 | |||
| 74 | last = next; | 85 | last = next; |
| 75 | next = be64_to_cpu(oe->e_next); | 86 | next = be64_to_cpu(oe->e_next); |
| 76 | entry = &oe->e_entry; | 87 | entry = &oe->e_entry; |
| @@ -98,10 +109,14 @@ int omfs_shrink_inode(struct inode *inode) | |||
| 98 | if (!bh) | 109 | if (!bh) |
| 99 | goto out; | 110 | goto out; |
| 100 | oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); | 111 | oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); |
| 112 | max_extents = omfs_max_extents(sbi, OMFS_EXTENT_CONT); | ||
| 101 | } | 113 | } |
| 102 | ret = 0; | 114 | ret = 0; |
| 103 | out: | 115 | out: |
| 104 | return ret; | 116 | return ret; |
| 117 | out_brelse: | ||
| 118 | brelse(bh); | ||
| 119 | return ret; | ||
| 105 | } | 120 | } |
| 106 | 121 | ||
| 107 | static void omfs_truncate(struct inode *inode) | 122 | static void omfs_truncate(struct inode *inode) |
| @@ -154,9 +169,7 @@ static int omfs_grow_extent(struct inode *inode, struct omfs_extent *oe, | |||
| 154 | goto out; | 169 | goto out; |
| 155 | } | 170 | } |
| 156 | } | 171 | } |
| 157 | max_count = (sbi->s_sys_blocksize - OMFS_EXTENT_START - | 172 | max_count = omfs_max_extents(sbi, OMFS_EXTENT_START); |
| 158 | sizeof(struct omfs_extent)) / | ||
| 159 | sizeof(struct omfs_extent_entry) + 1; | ||
| 160 | 173 | ||
| 161 | /* TODO: add a continuation block here */ | 174 | /* TODO: add a continuation block here */ |
| 162 | if (be32_to_cpu(oe->e_extent_count) > max_count-1) | 175 | if (be32_to_cpu(oe->e_extent_count) > max_count-1) |
| @@ -225,6 +238,7 @@ static int omfs_get_block(struct inode *inode, sector_t block, | |||
| 225 | sector_t next, offset; | 238 | sector_t next, offset; |
| 226 | int ret; | 239 | int ret; |
| 227 | u64 new_block; | 240 | u64 new_block; |
| 241 | u32 max_extents; | ||
| 228 | int extent_count; | 242 | int extent_count; |
| 229 | struct omfs_extent *oe; | 243 | struct omfs_extent *oe; |
| 230 | struct omfs_extent_entry *entry; | 244 | struct omfs_extent_entry *entry; |
| @@ -238,6 +252,7 @@ static int omfs_get_block(struct inode *inode, sector_t block, | |||
| 238 | goto out; | 252 | goto out; |
| 239 | 253 | ||
| 240 | oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); | 254 | oe = (struct omfs_extent *)(&bh->b_data[OMFS_EXTENT_START]); |
| 255 | max_extents = omfs_max_extents(sbi, OMFS_EXTENT_START); | ||
| 241 | next = inode->i_ino; | 256 | next = inode->i_ino; |
| 242 | 257 | ||
| 243 | for (;;) { | 258 | for (;;) { |
| @@ -249,6 +264,9 @@ static int omfs_get_block(struct inode *inode, sector_t block, | |||
| 249 | next = be64_to_cpu(oe->e_next); | 264 | next = be64_to_cpu(oe->e_next); |
| 250 | entry = &oe->e_entry; | 265 | entry = &oe->e_entry; |
| 251 | 266 | ||
| 267 | if (extent_count > max_extents) | ||
| 268 | goto out_brelse; | ||
| 269 | |||
| 252 | offset = find_block(inode, entry, block, extent_count, &remain); | 270 | offset = find_block(inode, entry, block, extent_count, &remain); |
| 253 | if (offset > 0) { | 271 | if (offset > 0) { |
| 254 | ret = 0; | 272 | ret = 0; |
| @@ -266,6 +284,7 @@ static int omfs_get_block(struct inode *inode, sector_t block, | |||
| 266 | if (!bh) | 284 | if (!bh) |
| 267 | goto out; | 285 | goto out; |
| 268 | oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); | 286 | oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]); |
| 287 | max_extents = omfs_max_extents(sbi, OMFS_EXTENT_CONT); | ||
| 269 | } | 288 | } |
| 270 | if (create) { | 289 | if (create) { |
| 271 | ret = omfs_grow_extent(inode, oe, &new_block); | 290 | ret = omfs_grow_extent(inode, oe, &new_block); |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index a95fe5984f4b..d29047b1b9b0 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
| @@ -232,8 +232,7 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino) | |||
| 232 | inode->i_mode = S_IFDIR | (S_IRWXUGO & ~sbi->s_dmask); | 232 | inode->i_mode = S_IFDIR | (S_IRWXUGO & ~sbi->s_dmask); |
| 233 | inode->i_op = &omfs_dir_inops; | 233 | inode->i_op = &omfs_dir_inops; |
| 234 | inode->i_fop = &omfs_dir_operations; | 234 | inode->i_fop = &omfs_dir_operations; |
| 235 | inode->i_size = be32_to_cpu(oi->i_head.h_body_size) + | 235 | inode->i_size = sbi->s_sys_blocksize; |
| 236 | sizeof(struct omfs_header); | ||
| 237 | inc_nlink(inode); | 236 | inc_nlink(inode); |
| 238 | break; | 237 | break; |
| 239 | case OMFS_FILE: | 238 | case OMFS_FILE: |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index d81fb9ed2b8e..154098157473 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
| @@ -263,8 +263,8 @@ int ubifs_calc_min_idx_lebs(struct ubifs_info *c) | |||
| 263 | 263 | ||
| 264 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; | 264 | idx_size = c->old_idx_sz + c->budg_idx_growth + c->budg_uncommitted_idx; |
| 265 | 265 | ||
| 266 | /* And make sure we have twice the index size of space reserved */ | 266 | /* And make sure we have thrice the index size of space reserved */ |
| 267 | idx_size <<= 1; | 267 | idx_size = idx_size + (idx_size << 1); |
| 268 | 268 | ||
| 269 | /* | 269 | /* |
| 270 | * We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes' | 270 | * We do not maintain 'old_idx_size' as 'old_idx_lebs'/'old_idx_bytes' |
| @@ -388,11 +388,11 @@ static int can_use_rp(struct ubifs_info *c) | |||
| 388 | * This function makes sure UBIFS has enough free eraseblocks for index growth | 388 | * This function makes sure UBIFS has enough free eraseblocks for index growth |
| 389 | * and data. | 389 | * and data. |
| 390 | * | 390 | * |
| 391 | * When budgeting index space, UBIFS reserves twice as more LEBs as the index | 391 | * When budgeting index space, UBIFS reserves thrice as many LEBs as the index |
| 392 | * would take if it was consolidated and written to the flash. This guarantees | 392 | * would take if it was consolidated and written to the flash. This guarantees |
| 393 | * that the "in-the-gaps" commit method always succeeds and UBIFS will always | 393 | * that the "in-the-gaps" commit method always succeeds and UBIFS will always |
| 394 | * be able to commit dirty index. So this function basically adds amount of | 394 | * be able to commit dirty index. So this function basically adds amount of |
| 395 | * budgeted index space to the size of the current index, multiplies this by 2, | 395 | * budgeted index space to the size of the current index, multiplies this by 3, |
| 396 | * and makes sure this does not exceed the amount of free eraseblocks. | 396 | * and makes sure this does not exceed the amount of free eraseblocks. |
| 397 | * | 397 | * |
| 398 | * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: | 398 | * Notes about @c->min_idx_lebs and @c->lst.idx_lebs variables: |
| @@ -543,8 +543,16 @@ int ubifs_budget_space(struct ubifs_info *c, struct ubifs_budget_req *req) | |||
| 543 | int err, idx_growth, data_growth, dd_growth; | 543 | int err, idx_growth, data_growth, dd_growth; |
| 544 | struct retries_info ri; | 544 | struct retries_info ri; |
| 545 | 545 | ||
| 546 | ubifs_assert(req->new_page <= 1); | ||
| 547 | ubifs_assert(req->dirtied_page <= 1); | ||
| 548 | ubifs_assert(req->new_dent <= 1); | ||
| 549 | ubifs_assert(req->mod_dent <= 1); | ||
| 550 | ubifs_assert(req->new_ino <= 1); | ||
| 551 | ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA); | ||
| 546 | ubifs_assert(req->dirtied_ino <= 4); | 552 | ubifs_assert(req->dirtied_ino <= 4); |
| 547 | ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); | 553 | ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); |
| 554 | ubifs_assert(!(req->new_ino_d & 7)); | ||
| 555 | ubifs_assert(!(req->dirtied_ino_d & 7)); | ||
| 548 | 556 | ||
| 549 | data_growth = calc_data_growth(c, req); | 557 | data_growth = calc_data_growth(c, req); |
| 550 | dd_growth = calc_dd_growth(c, req); | 558 | dd_growth = calc_dd_growth(c, req); |
| @@ -618,8 +626,16 @@ again: | |||
| 618 | */ | 626 | */ |
| 619 | void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) | 627 | void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) |
| 620 | { | 628 | { |
| 629 | ubifs_assert(req->new_page <= 1); | ||
| 630 | ubifs_assert(req->dirtied_page <= 1); | ||
| 631 | ubifs_assert(req->new_dent <= 1); | ||
| 632 | ubifs_assert(req->mod_dent <= 1); | ||
| 633 | ubifs_assert(req->new_ino <= 1); | ||
| 634 | ubifs_assert(req->new_ino_d <= UBIFS_MAX_INO_DATA); | ||
| 621 | ubifs_assert(req->dirtied_ino <= 4); | 635 | ubifs_assert(req->dirtied_ino <= 4); |
| 622 | ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); | 636 | ubifs_assert(req->dirtied_ino_d <= UBIFS_MAX_INO_DATA * 4); |
| 637 | ubifs_assert(!(req->new_ino_d & 7)); | ||
| 638 | ubifs_assert(!(req->dirtied_ino_d & 7)); | ||
| 623 | if (!req->recalculate) { | 639 | if (!req->recalculate) { |
| 624 | ubifs_assert(req->idx_growth >= 0); | 640 | ubifs_assert(req->idx_growth >= 0); |
| 625 | ubifs_assert(req->data_growth >= 0); | 641 | ubifs_assert(req->data_growth >= 0); |
| @@ -647,7 +663,11 @@ void ubifs_release_budget(struct ubifs_info *c, struct ubifs_budget_req *req) | |||
| 647 | 663 | ||
| 648 | ubifs_assert(c->budg_idx_growth >= 0); | 664 | ubifs_assert(c->budg_idx_growth >= 0); |
| 649 | ubifs_assert(c->budg_data_growth >= 0); | 665 | ubifs_assert(c->budg_data_growth >= 0); |
| 666 | ubifs_assert(c->budg_dd_growth >= 0); | ||
| 650 | ubifs_assert(c->min_idx_lebs < c->main_lebs); | 667 | ubifs_assert(c->min_idx_lebs < c->main_lebs); |
| 668 | ubifs_assert(!(c->budg_idx_growth & 7)); | ||
| 669 | ubifs_assert(!(c->budg_data_growth & 7)); | ||
| 670 | ubifs_assert(!(c->budg_dd_growth & 7)); | ||
| 651 | spin_unlock(&c->space_lock); | 671 | spin_unlock(&c->space_lock); |
| 652 | } | 672 | } |
| 653 | 673 | ||
| @@ -686,9 +706,10 @@ void ubifs_convert_page_budget(struct ubifs_info *c) | |||
| 686 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, | 706 | void ubifs_release_dirty_inode_budget(struct ubifs_info *c, |
| 687 | struct ubifs_inode *ui) | 707 | struct ubifs_inode *ui) |
| 688 | { | 708 | { |
| 689 | struct ubifs_budget_req req = {.dd_growth = c->inode_budget, | 709 | struct ubifs_budget_req req; |
| 690 | .dirtied_ino_d = ui->data_len}; | ||
| 691 | 710 | ||
| 711 | memset(&req, 0, sizeof(struct ubifs_budget_req)); | ||
| 712 | req.dd_growth = c->inode_budget + ALIGN(ui->data_len, 8); | ||
| 692 | ubifs_release_budget(c, &req); | 713 | ubifs_release_budget(c, &req); |
| 693 | } | 714 | } |
| 694 | 715 | ||
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c index 3b516316c9b3..0a6aa2cc78f0 100644 --- a/fs/ubifs/commit.c +++ b/fs/ubifs/commit.c | |||
| @@ -74,6 +74,7 @@ static int do_commit(struct ubifs_info *c) | |||
| 74 | goto out_up; | 74 | goto out_up; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | c->cmt_no += 1; | ||
| 77 | err = ubifs_gc_start_commit(c); | 78 | err = ubifs_gc_start_commit(c); |
| 78 | if (err) | 79 | if (err) |
| 79 | goto out_up; | 80 | goto out_up; |
| @@ -115,7 +116,7 @@ static int do_commit(struct ubifs_info *c) | |||
| 115 | goto out; | 116 | goto out; |
| 116 | 117 | ||
| 117 | mutex_lock(&c->mst_mutex); | 118 | mutex_lock(&c->mst_mutex); |
| 118 | c->mst_node->cmt_no = cpu_to_le64(++c->cmt_no); | 119 | c->mst_node->cmt_no = cpu_to_le64(c->cmt_no); |
| 119 | c->mst_node->log_lnum = cpu_to_le32(new_ltail_lnum); | 120 | c->mst_node->log_lnum = cpu_to_le32(new_ltail_lnum); |
| 120 | c->mst_node->root_lnum = cpu_to_le32(zroot.lnum); | 121 | c->mst_node->root_lnum = cpu_to_le32(zroot.lnum); |
| 121 | c->mst_node->root_offs = cpu_to_le32(zroot.offs); | 122 | c->mst_node->root_offs = cpu_to_le32(zroot.offs); |
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index 4e3aaeba4eca..b9cb77473758 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c | |||
| @@ -568,8 +568,8 @@ void dbg_dump_budget_req(const struct ubifs_budget_req *req) | |||
| 568 | void dbg_dump_lstats(const struct ubifs_lp_stats *lst) | 568 | void dbg_dump_lstats(const struct ubifs_lp_stats *lst) |
| 569 | { | 569 | { |
| 570 | spin_lock(&dbg_lock); | 570 | spin_lock(&dbg_lock); |
| 571 | printk(KERN_DEBUG "Lprops statistics: empty_lebs %d, idx_lebs %d\n", | 571 | printk(KERN_DEBUG "(pid %d) Lprops statistics: empty_lebs %d, " |
| 572 | lst->empty_lebs, lst->idx_lebs); | 572 | "idx_lebs %d\n", current->pid, lst->empty_lebs, lst->idx_lebs); |
| 573 | printk(KERN_DEBUG "\ttaken_empty_lebs %d, total_free %lld, " | 573 | printk(KERN_DEBUG "\ttaken_empty_lebs %d, total_free %lld, " |
| 574 | "total_dirty %lld\n", lst->taken_empty_lebs, lst->total_free, | 574 | "total_dirty %lld\n", lst->taken_empty_lebs, lst->total_free, |
| 575 | lst->total_dirty); | 575 | lst->total_dirty); |
| @@ -587,8 +587,8 @@ void dbg_dump_budg(struct ubifs_info *c) | |||
| 587 | struct ubifs_gced_idx_leb *idx_gc; | 587 | struct ubifs_gced_idx_leb *idx_gc; |
| 588 | 588 | ||
| 589 | spin_lock(&dbg_lock); | 589 | spin_lock(&dbg_lock); |
| 590 | printk(KERN_DEBUG "Budgeting info: budg_data_growth %lld, " | 590 | printk(KERN_DEBUG "(pid %d) Budgeting info: budg_data_growth %lld, " |
| 591 | "budg_dd_growth %lld, budg_idx_growth %lld\n", | 591 | "budg_dd_growth %lld, budg_idx_growth %lld\n", current->pid, |
| 592 | c->budg_data_growth, c->budg_dd_growth, c->budg_idx_growth); | 592 | c->budg_data_growth, c->budg_dd_growth, c->budg_idx_growth); |
| 593 | printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, " | 593 | printk(KERN_DEBUG "\tdata budget sum %lld, total budget sum %lld, " |
| 594 | "freeable_cnt %d\n", c->budg_data_growth + c->budg_dd_growth, | 594 | "freeable_cnt %d\n", c->budg_data_growth + c->budg_dd_growth, |
| @@ -634,7 +634,7 @@ void dbg_dump_lprops(struct ubifs_info *c) | |||
| 634 | struct ubifs_lprops lp; | 634 | struct ubifs_lprops lp; |
| 635 | struct ubifs_lp_stats lst; | 635 | struct ubifs_lp_stats lst; |
| 636 | 636 | ||
| 637 | printk(KERN_DEBUG "Dumping LEB properties\n"); | 637 | printk(KERN_DEBUG "(pid %d) Dumping LEB properties\n", current->pid); |
| 638 | ubifs_get_lp_stats(c, &lst); | 638 | ubifs_get_lp_stats(c, &lst); |
| 639 | dbg_dump_lstats(&lst); | 639 | dbg_dump_lstats(&lst); |
| 640 | 640 | ||
| @@ -655,7 +655,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum) | |||
| 655 | if (dbg_failure_mode) | 655 | if (dbg_failure_mode) |
| 656 | return; | 656 | return; |
| 657 | 657 | ||
| 658 | printk(KERN_DEBUG "Dumping LEB %d\n", lnum); | 658 | printk(KERN_DEBUG "(pid %d) Dumping LEB %d\n", current->pid, lnum); |
| 659 | 659 | ||
| 660 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); | 660 | sleb = ubifs_scan(c, lnum, 0, c->dbg_buf); |
| 661 | if (IS_ERR(sleb)) { | 661 | if (IS_ERR(sleb)) { |
| @@ -720,8 +720,8 @@ void dbg_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat) | |||
| 720 | { | 720 | { |
| 721 | int i; | 721 | int i; |
| 722 | 722 | ||
| 723 | printk(KERN_DEBUG "Dumping heap cat %d (%d elements)\n", | 723 | printk(KERN_DEBUG "(pid %d) Dumping heap cat %d (%d elements)\n", |
| 724 | cat, heap->cnt); | 724 | current->pid, cat, heap->cnt); |
| 725 | for (i = 0; i < heap->cnt; i++) { | 725 | for (i = 0; i < heap->cnt; i++) { |
| 726 | struct ubifs_lprops *lprops = heap->arr[i]; | 726 | struct ubifs_lprops *lprops = heap->arr[i]; |
| 727 | 727 | ||
| @@ -736,7 +736,7 @@ void dbg_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | |||
| 736 | { | 736 | { |
| 737 | int i; | 737 | int i; |
| 738 | 738 | ||
| 739 | printk(KERN_DEBUG "Dumping pnode:\n"); | 739 | printk(KERN_DEBUG "(pid %d) Dumping pnode:\n", current->pid); |
| 740 | printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", | 740 | printk(KERN_DEBUG "\taddress %zx parent %zx cnext %zx\n", |
| 741 | (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); | 741 | (size_t)pnode, (size_t)parent, (size_t)pnode->cnext); |
| 742 | printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", | 742 | printk(KERN_DEBUG "\tflags %lu iip %d level %d num %d\n", |
| @@ -755,7 +755,7 @@ void dbg_dump_tnc(struct ubifs_info *c) | |||
| 755 | int level; | 755 | int level; |
| 756 | 756 | ||
| 757 | printk(KERN_DEBUG "\n"); | 757 | printk(KERN_DEBUG "\n"); |
| 758 | printk(KERN_DEBUG "Dumping the TNC tree\n"); | 758 | printk(KERN_DEBUG "(pid %d) Dumping the TNC tree\n", current->pid); |
| 759 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); | 759 | znode = ubifs_tnc_levelorder_next(c->zroot.znode, NULL); |
| 760 | level = znode->level; | 760 | level = znode->level; |
| 761 | printk(KERN_DEBUG "== Level %d ==\n", level); | 761 | printk(KERN_DEBUG "== Level %d ==\n", level); |
| @@ -2208,16 +2208,17 @@ int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, | |||
| 2208 | int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, | 2208 | int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, |
| 2209 | int offset, int len, int dtype) | 2209 | int offset, int len, int dtype) |
| 2210 | { | 2210 | { |
| 2211 | int err; | 2211 | int err, failing; |
| 2212 | 2212 | ||
| 2213 | if (in_failure_mode(desc)) | 2213 | if (in_failure_mode(desc)) |
| 2214 | return -EIO; | 2214 | return -EIO; |
| 2215 | if (do_fail(desc, lnum, 1)) | 2215 | failing = do_fail(desc, lnum, 1); |
| 2216 | if (failing) | ||
| 2216 | cut_data(buf, len); | 2217 | cut_data(buf, len); |
| 2217 | err = ubi_leb_write(desc, lnum, buf, offset, len, dtype); | 2218 | err = ubi_leb_write(desc, lnum, buf, offset, len, dtype); |
| 2218 | if (err) | 2219 | if (err) |
| 2219 | return err; | 2220 | return err; |
| 2220 | if (in_failure_mode(desc)) | 2221 | if (failing) |
| 2221 | return -EIO; | 2222 | return -EIO; |
| 2222 | return 0; | 2223 | return 0; |
| 2223 | } | 2224 | } |
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h index 3c4f1e93c9e0..50315fc57185 100644 --- a/fs/ubifs/debug.h +++ b/fs/ubifs/debug.h | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | #define UBIFS_DBG(op) op | 28 | #define UBIFS_DBG(op) op |
| 29 | 29 | ||
| 30 | #define ubifs_assert(expr) do { \ | 30 | #define ubifs_assert(expr) do { \ |
| 31 | if (unlikely(!(expr))) { \ | 31 | if (unlikely(!(expr))) { \ |
| 32 | printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ | 32 | printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ |
| 33 | __func__, __LINE__, current->pid); \ | 33 | __func__, __LINE__, current->pid); \ |
| @@ -73,50 +73,50 @@ const char *dbg_key_str1(const struct ubifs_info *c, | |||
| 73 | const union ubifs_key *key); | 73 | const union ubifs_key *key); |
| 74 | 74 | ||
| 75 | /* | 75 | /* |
| 76 | * DBGKEY macros require dbg_lock to be held, which it is in the dbg message | 76 | * DBGKEY macros require @dbg_lock to be held, which it is in the dbg message |
| 77 | * macros. | 77 | * macros. |
| 78 | */ | 78 | */ |
| 79 | #define DBGKEY(key) dbg_key_str0(c, (key)) | 79 | #define DBGKEY(key) dbg_key_str0(c, (key)) |
| 80 | #define DBGKEY1(key) dbg_key_str1(c, (key)) | 80 | #define DBGKEY1(key) dbg_key_str1(c, (key)) |
| 81 | 81 | ||
| 82 | /* General messages */ | 82 | /* General messages */ |
| 83 | #define dbg_gen(fmt, ...) dbg_do_msg(UBIFS_MSG_GEN, fmt, ##__VA_ARGS__) | 83 | #define dbg_gen(fmt, ...) dbg_do_msg(UBIFS_MSG_GEN, fmt, ##__VA_ARGS__) |
| 84 | 84 | ||
| 85 | /* Additional journal messages */ | 85 | /* Additional journal messages */ |
| 86 | #define dbg_jnl(fmt, ...) dbg_do_msg(UBIFS_MSG_JNL, fmt, ##__VA_ARGS__) | 86 | #define dbg_jnl(fmt, ...) dbg_do_msg(UBIFS_MSG_JNL, fmt, ##__VA_ARGS__) |
| 87 | 87 | ||
| 88 | /* Additional TNC messages */ | 88 | /* Additional TNC messages */ |
| 89 | #define dbg_tnc(fmt, ...) dbg_do_msg(UBIFS_MSG_TNC, fmt, ##__VA_ARGS__) | 89 | #define dbg_tnc(fmt, ...) dbg_do_msg(UBIFS_MSG_TNC, fmt, ##__VA_ARGS__) |
| 90 | 90 | ||
| 91 | /* Additional lprops messages */ | 91 | /* Additional lprops messages */ |
| 92 | #define dbg_lp(fmt, ...) dbg_do_msg(UBIFS_MSG_LP, fmt, ##__VA_ARGS__) | 92 | #define dbg_lp(fmt, ...) dbg_do_msg(UBIFS_MSG_LP, fmt, ##__VA_ARGS__) |
| 93 | 93 | ||
| 94 | /* Additional LEB find messages */ | 94 | /* Additional LEB find messages */ |
| 95 | #define dbg_find(fmt, ...) dbg_do_msg(UBIFS_MSG_FIND, fmt, ##__VA_ARGS__) | 95 | #define dbg_find(fmt, ...) dbg_do_msg(UBIFS_MSG_FIND, fmt, ##__VA_ARGS__) |
| 96 | 96 | ||
| 97 | /* Additional mount messages */ | 97 | /* Additional mount messages */ |
| 98 | #define dbg_mnt(fmt, ...) dbg_do_msg(UBIFS_MSG_MNT, fmt, ##__VA_ARGS__) | 98 | #define dbg_mnt(fmt, ...) dbg_do_msg(UBIFS_MSG_MNT, fmt, ##__VA_ARGS__) |
| 99 | 99 | ||
| 100 | /* Additional I/O messages */ | 100 | /* Additional I/O messages */ |
| 101 | #define dbg_io(fmt, ...) dbg_do_msg(UBIFS_MSG_IO, fmt, ##__VA_ARGS__) | 101 | #define dbg_io(fmt, ...) dbg_do_msg(UBIFS_MSG_IO, fmt, ##__VA_ARGS__) |
| 102 | 102 | ||
| 103 | /* Additional commit messages */ | 103 | /* Additional commit messages */ |
| 104 | #define dbg_cmt(fmt, ...) dbg_do_msg(UBIFS_MSG_CMT, fmt, ##__VA_ARGS__) | 104 | #define dbg_cmt(fmt, ...) dbg_do_msg(UBIFS_MSG_CMT, fmt, ##__VA_ARGS__) |
| 105 | 105 | ||
| 106 | /* Additional budgeting messages */ | 106 | /* Additional budgeting messages */ |
| 107 | #define dbg_budg(fmt, ...) dbg_do_msg(UBIFS_MSG_BUDG, fmt, ##__VA_ARGS__) | 107 | #define dbg_budg(fmt, ...) dbg_do_msg(UBIFS_MSG_BUDG, fmt, ##__VA_ARGS__) |
| 108 | 108 | ||
| 109 | /* Additional log messages */ | 109 | /* Additional log messages */ |
| 110 | #define dbg_log(fmt, ...) dbg_do_msg(UBIFS_MSG_LOG, fmt, ##__VA_ARGS__) | 110 | #define dbg_log(fmt, ...) dbg_do_msg(UBIFS_MSG_LOG, fmt, ##__VA_ARGS__) |
| 111 | 111 | ||
| 112 | /* Additional gc messages */ | 112 | /* Additional gc messages */ |
| 113 | #define dbg_gc(fmt, ...) dbg_do_msg(UBIFS_MSG_GC, fmt, ##__VA_ARGS__) | 113 | #define dbg_gc(fmt, ...) dbg_do_msg(UBIFS_MSG_GC, fmt, ##__VA_ARGS__) |
| 114 | 114 | ||
| 115 | /* Additional scan messages */ | 115 | /* Additional scan messages */ |
| 116 | #define dbg_scan(fmt, ...) dbg_do_msg(UBIFS_MSG_SCAN, fmt, ##__VA_ARGS__) | 116 | #define dbg_scan(fmt, ...) dbg_do_msg(UBIFS_MSG_SCAN, fmt, ##__VA_ARGS__) |
| 117 | 117 | ||
| 118 | /* Additional recovery messages */ | 118 | /* Additional recovery messages */ |
| 119 | #define dbg_rcvry(fmt, ...) dbg_do_msg(UBIFS_MSG_RCVRY, fmt, ##__VA_ARGS__) | 119 | #define dbg_rcvry(fmt, ...) dbg_do_msg(UBIFS_MSG_RCVRY, fmt, ##__VA_ARGS__) |
| 120 | 120 | ||
| 121 | /* | 121 | /* |
| 122 | * Debugging message type flags (must match msg_type_names in debug.c). | 122 | * Debugging message type flags (must match msg_type_names in debug.c). |
| @@ -239,34 +239,23 @@ typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | |||
| 239 | struct ubifs_zbranch *zbr, void *priv); | 239 | struct ubifs_zbranch *zbr, void *priv); |
| 240 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | 240 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, |
| 241 | struct ubifs_znode *znode, void *priv); | 241 | struct ubifs_znode *znode, void *priv); |
| 242 | |||
| 243 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, | 242 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, |
| 244 | dbg_znode_callback znode_cb, void *priv); | 243 | dbg_znode_callback znode_cb, void *priv); |
| 245 | 244 | ||
| 246 | /* Checking functions */ | 245 | /* Checking functions */ |
| 247 | 246 | ||
| 248 | int dbg_check_lprops(struct ubifs_info *c); | 247 | int dbg_check_lprops(struct ubifs_info *c); |
| 249 | |||
| 250 | int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot); | 248 | int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot); |
| 251 | int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot); | 249 | int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot); |
| 252 | |||
| 253 | int dbg_check_cats(struct ubifs_info *c); | 250 | int dbg_check_cats(struct ubifs_info *c); |
| 254 | |||
| 255 | int dbg_check_ltab(struct ubifs_info *c); | 251 | int dbg_check_ltab(struct ubifs_info *c); |
| 256 | |||
| 257 | int dbg_check_synced_i_size(struct inode *inode); | 252 | int dbg_check_synced_i_size(struct inode *inode); |
| 258 | |||
| 259 | int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir); | 253 | int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir); |
| 260 | |||
| 261 | int dbg_check_tnc(struct ubifs_info *c, int extra); | 254 | int dbg_check_tnc(struct ubifs_info *c, int extra); |
| 262 | |||
| 263 | int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); | 255 | int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); |
| 264 | |||
| 265 | int dbg_check_filesystem(struct ubifs_info *c); | 256 | int dbg_check_filesystem(struct ubifs_info *c); |
| 266 | |||
| 267 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, | 257 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, |
| 268 | int add_pos); | 258 | int add_pos); |
| 269 | |||
| 270 | int dbg_check_lprops(struct ubifs_info *c); | 259 | int dbg_check_lprops(struct ubifs_info *c); |
| 271 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, | 260 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, |
| 272 | int row, int col); | 261 | int row, int col); |
| @@ -329,71 +318,77 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum, | |||
| 329 | #else /* !CONFIG_UBIFS_FS_DEBUG */ | 318 | #else /* !CONFIG_UBIFS_FS_DEBUG */ |
| 330 | 319 | ||
| 331 | #define UBIFS_DBG(op) | 320 | #define UBIFS_DBG(op) |
| 332 | #define ubifs_assert(expr) ({}) | 321 | |
| 333 | #define ubifs_assert_cmt_locked(c) | 322 | /* Use "if (0)" to make compiler check arguments even if debugging is off */ |
| 323 | #define ubifs_assert(expr) do { \ | ||
| 324 | if (0 && (expr)) \ | ||
| 325 | printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ | ||
| 326 | __func__, __LINE__, current->pid); \ | ||
| 327 | } while (0) | ||
| 328 | |||
| 329 | #define dbg_err(fmt, ...) do { \ | ||
| 330 | if (0) \ | ||
| 331 | ubifs_err(fmt, ##__VA_ARGS__); \ | ||
| 332 | } while (0) | ||
| 333 | |||
| 334 | #define dbg_msg(fmt, ...) do { \ | ||
| 335 | if (0) \ | ||
| 336 | printk(KERN_DEBUG "UBIFS DBG (pid %d): %s: " fmt "\n", \ | ||
| 337 | current->pid, __func__, ##__VA_ARGS__); \ | ||
| 338 | } while (0) | ||
| 339 | |||
| 334 | #define dbg_dump_stack() | 340 | #define dbg_dump_stack() |
| 335 | #define dbg_err(fmt, ...) ({}) | 341 | #define ubifs_assert_cmt_locked(c) |
| 336 | #define dbg_msg(fmt, ...) ({}) | ||
| 337 | #define dbg_key(c, key, fmt, ...) ({}) | ||
| 338 | |||
| 339 | #define dbg_gen(fmt, ...) ({}) | ||
| 340 | #define dbg_jnl(fmt, ...) ({}) | ||
| 341 | #define dbg_tnc(fmt, ...) ({}) | ||
| 342 | #define dbg_lp(fmt, ...) ({}) | ||
| 343 | #define dbg_find(fmt, ...) ({}) | ||
| 344 | #define dbg_mnt(fmt, ...) ({}) | ||
| 345 | #define dbg_io(fmt, ...) ({}) | ||
| 346 | #define dbg_cmt(fmt, ...) ({}) | ||
| 347 | #define dbg_budg(fmt, ...) ({}) | ||
| 348 | #define dbg_log(fmt, ...) ({}) | ||
| 349 | #define dbg_gc(fmt, ...) ({}) | ||
| 350 | #define dbg_scan(fmt, ...) ({}) | ||
| 351 | #define dbg_rcvry(fmt, ...) ({}) | ||
| 352 | |||
| 353 | #define dbg_ntype(type) "" | ||
| 354 | #define dbg_cstate(cmt_state) "" | ||
| 355 | #define dbg_get_key_dump(c, key) ({}) | ||
| 356 | #define dbg_dump_inode(c, inode) ({}) | ||
| 357 | #define dbg_dump_node(c, node) ({}) | ||
| 358 | #define dbg_dump_budget_req(req) ({}) | ||
| 359 | #define dbg_dump_lstats(lst) ({}) | ||
| 360 | #define dbg_dump_budg(c) ({}) | ||
| 361 | #define dbg_dump_lprop(c, lp) ({}) | ||
| 362 | #define dbg_dump_lprops(c) ({}) | ||
| 363 | #define dbg_dump_leb(c, lnum) ({}) | ||
| 364 | #define dbg_dump_znode(c, znode) ({}) | ||
| 365 | #define dbg_dump_heap(c, heap, cat) ({}) | ||
| 366 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | ||
| 367 | #define dbg_dump_tnc(c) ({}) | ||
| 368 | #define dbg_dump_index(c) ({}) | ||
| 369 | 342 | ||
| 370 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 | 343 | #define dbg_gen(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) |
| 344 | #define dbg_jnl(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 345 | #define dbg_tnc(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 346 | #define dbg_lp(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 347 | #define dbg_find(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 348 | #define dbg_mnt(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 349 | #define dbg_io(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 350 | #define dbg_cmt(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 351 | #define dbg_budg(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 352 | #define dbg_log(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 353 | #define dbg_gc(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 354 | #define dbg_scan(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 355 | #define dbg_rcvry(fmt, ...) dbg_msg(fmt, ##__VA_ARGS__) | ||
| 356 | |||
| 357 | #define DBGKEY(key) ((char *)(key)) | ||
| 358 | #define DBGKEY1(key) ((char *)(key)) | ||
| 359 | |||
| 360 | #define dbg_ntype(type) "" | ||
| 361 | #define dbg_cstate(cmt_state) "" | ||
| 362 | #define dbg_get_key_dump(c, key) ({}) | ||
| 363 | #define dbg_dump_inode(c, inode) ({}) | ||
| 364 | #define dbg_dump_node(c, node) ({}) | ||
| 365 | #define dbg_dump_budget_req(req) ({}) | ||
| 366 | #define dbg_dump_lstats(lst) ({}) | ||
| 367 | #define dbg_dump_budg(c) ({}) | ||
| 368 | #define dbg_dump_lprop(c, lp) ({}) | ||
| 369 | #define dbg_dump_lprops(c) ({}) | ||
| 370 | #define dbg_dump_leb(c, lnum) ({}) | ||
| 371 | #define dbg_dump_znode(c, znode) ({}) | ||
| 372 | #define dbg_dump_heap(c, heap, cat) ({}) | ||
| 373 | #define dbg_dump_pnode(c, pnode, parent, iip) ({}) | ||
| 374 | #define dbg_dump_tnc(c) ({}) | ||
| 375 | #define dbg_dump_index(c) ({}) | ||
| 371 | 376 | ||
| 377 | #define dbg_walk_index(c, leaf_cb, znode_cb, priv) 0 | ||
| 372 | #define dbg_old_index_check_init(c, zroot) 0 | 378 | #define dbg_old_index_check_init(c, zroot) 0 |
| 373 | #define dbg_check_old_index(c, zroot) 0 | 379 | #define dbg_check_old_index(c, zroot) 0 |
| 374 | |||
| 375 | #define dbg_check_cats(c) 0 | 380 | #define dbg_check_cats(c) 0 |
| 376 | |||
| 377 | #define dbg_check_ltab(c) 0 | 381 | #define dbg_check_ltab(c) 0 |
| 378 | |||
| 379 | #define dbg_check_synced_i_size(inode) 0 | 382 | #define dbg_check_synced_i_size(inode) 0 |
| 380 | |||
| 381 | #define dbg_check_dir_size(c, dir) 0 | 383 | #define dbg_check_dir_size(c, dir) 0 |
| 382 | |||
| 383 | #define dbg_check_tnc(c, x) 0 | 384 | #define dbg_check_tnc(c, x) 0 |
| 384 | |||
| 385 | #define dbg_check_idx_size(c, idx_size) 0 | 385 | #define dbg_check_idx_size(c, idx_size) 0 |
| 386 | |||
| 387 | #define dbg_check_filesystem(c) 0 | 386 | #define dbg_check_filesystem(c) 0 |
| 388 | |||
| 389 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) | 387 | #define dbg_check_heap(c, heap, cat, add_pos) ({}) |
| 390 | |||
| 391 | #define dbg_check_lprops(c) 0 | 388 | #define dbg_check_lprops(c) 0 |
| 392 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 | 389 | #define dbg_check_lpt_nodes(c, cnode, row, col) 0 |
| 393 | |||
| 394 | #define dbg_force_in_the_gaps_enabled 0 | 390 | #define dbg_force_in_the_gaps_enabled 0 |
| 395 | #define dbg_force_in_the_gaps() 0 | 391 | #define dbg_force_in_the_gaps() 0 |
| 396 | |||
| 397 | #define dbg_failure_mode 0 | 392 | #define dbg_failure_mode 0 |
| 398 | #define dbg_failure_mode_registration(c) ({}) | 393 | #define dbg_failure_mode_registration(c) ({}) |
| 399 | #define dbg_failure_mode_deregistration(c) ({}) | 394 | #define dbg_failure_mode_deregistration(c) ({}) |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index e90374be7d3b..5c96f1fb7016 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
| @@ -165,7 +165,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, | |||
| 165 | } | 165 | } |
| 166 | 166 | ||
| 167 | inode->i_ino = ++c->highest_inum; | 167 | inode->i_ino = ++c->highest_inum; |
| 168 | inode->i_generation = ++c->vfs_gen; | ||
| 169 | /* | 168 | /* |
| 170 | * The creation sequence number remains with this inode for its | 169 | * The creation sequence number remains with this inode for its |
| 171 | * lifetime. All nodes for this inode have a greater sequence number, | 170 | * lifetime. All nodes for this inode have a greater sequence number, |
| @@ -220,15 +219,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 220 | 219 | ||
| 221 | err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name); | 220 | err = ubifs_tnc_lookup_nm(c, &key, dent, &dentry->d_name); |
| 222 | if (err) { | 221 | if (err) { |
| 223 | /* | 222 | if (err == -ENOENT) { |
| 224 | * Do not hash the direntry if parent 'i_nlink' is zero, because | ||
| 225 | * this has side-effects - '->delete_inode()' call will not be | ||
| 226 | * called for the parent orphan inode, because 'd_count' of its | ||
| 227 | * direntry will stay 1 (it'll be negative direntry I guess) | ||
| 228 | * and prevent 'iput_final()' until the dentry is destroyed due | ||
| 229 | * to unmount or memory pressure. | ||
| 230 | */ | ||
| 231 | if (err == -ENOENT && dir->i_nlink != 0) { | ||
| 232 | dbg_gen("not found"); | 223 | dbg_gen("not found"); |
| 233 | goto done; | 224 | goto done; |
| 234 | } | 225 | } |
| @@ -525,7 +516,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 525 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | 516 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
| 526 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); | 517 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); |
| 527 | struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2, | 518 | struct ubifs_budget_req req = { .new_dent = 1, .dirtied_ino = 2, |
| 528 | .dirtied_ino_d = ui->data_len }; | 519 | .dirtied_ino_d = ALIGN(ui->data_len, 8) }; |
| 529 | 520 | ||
| 530 | /* | 521 | /* |
| 531 | * Budget request settings: new direntry, changing the target inode, | 522 | * Budget request settings: new direntry, changing the target inode, |
| @@ -727,8 +718,7 @@ static int ubifs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 727 | struct ubifs_inode *dir_ui = ubifs_inode(dir); | 718 | struct ubifs_inode *dir_ui = ubifs_inode(dir); |
| 728 | struct ubifs_info *c = dir->i_sb->s_fs_info; | 719 | struct ubifs_info *c = dir->i_sb->s_fs_info; |
| 729 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); | 720 | int err, sz_change = CALC_DENT_SIZE(dentry->d_name.len); |
| 730 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | 721 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1 }; |
| 731 | .dirtied_ino_d = 1 }; | ||
| 732 | 722 | ||
| 733 | /* | 723 | /* |
| 734 | * Budget request settings: new inode, new direntry and changing parent | 724 | * Budget request settings: new inode, new direntry and changing parent |
| @@ -789,7 +779,8 @@ static int ubifs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 789 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | 779 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); |
| 790 | int err, devlen = 0; | 780 | int err, devlen = 0; |
| 791 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | 781 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
| 792 | .new_ino_d = devlen, .dirtied_ino = 1 }; | 782 | .new_ino_d = ALIGN(devlen, 8), |
| 783 | .dirtied_ino = 1 }; | ||
| 793 | 784 | ||
| 794 | /* | 785 | /* |
| 795 | * Budget request settings: new inode, new direntry and changing parent | 786 | * Budget request settings: new inode, new direntry and changing parent |
| @@ -863,7 +854,8 @@ static int ubifs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 863 | int err, len = strlen(symname); | 854 | int err, len = strlen(symname); |
| 864 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); | 855 | int sz_change = CALC_DENT_SIZE(dentry->d_name.len); |
| 865 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | 856 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
| 866 | .new_ino_d = len, .dirtied_ino = 1 }; | 857 | .new_ino_d = ALIGN(len, 8), |
| 858 | .dirtied_ino = 1 }; | ||
| 867 | 859 | ||
| 868 | /* | 860 | /* |
| 869 | * Budget request settings: new inode, new direntry and changing parent | 861 | * Budget request settings: new inode, new direntry and changing parent |
| @@ -1012,7 +1004,7 @@ static int ubifs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 1012 | struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1, | 1004 | struct ubifs_budget_req req = { .new_dent = 1, .mod_dent = 1, |
| 1013 | .dirtied_ino = 3 }; | 1005 | .dirtied_ino = 3 }; |
| 1014 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, | 1006 | struct ubifs_budget_req ino_req = { .dirtied_ino = 1, |
| 1015 | .dirtied_ino_d = old_inode_ui->data_len }; | 1007 | .dirtied_ino_d = ALIGN(old_inode_ui->data_len, 8) }; |
| 1016 | struct timespec time; | 1008 | struct timespec time; |
| 1017 | 1009 | ||
| 1018 | /* | 1010 | /* |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 8565e586e533..4071d1cae29f 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
| @@ -890,7 +890,7 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode, | |||
| 890 | loff_t new_size = attr->ia_size; | 890 | loff_t new_size = attr->ia_size; |
| 891 | struct ubifs_inode *ui = ubifs_inode(inode); | 891 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 892 | struct ubifs_budget_req req = { .dirtied_ino = 1, | 892 | struct ubifs_budget_req req = { .dirtied_ino = 1, |
| 893 | .dirtied_ino_d = ui->data_len }; | 893 | .dirtied_ino_d = ALIGN(ui->data_len, 8) }; |
| 894 | 894 | ||
| 895 | err = ubifs_budget_space(c, &req); | 895 | err = ubifs_budget_space(c, &req); |
| 896 | if (err) | 896 | if (err) |
| @@ -941,7 +941,8 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 941 | struct inode *inode = dentry->d_inode; | 941 | struct inode *inode = dentry->d_inode; |
| 942 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 942 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
| 943 | 943 | ||
| 944 | dbg_gen("ino %lu, ia_valid %#x", inode->i_ino, attr->ia_valid); | 944 | dbg_gen("ino %lu, mode %#x, ia_valid %#x", |
| 945 | inode->i_ino, inode->i_mode, attr->ia_valid); | ||
| 945 | err = inode_change_ok(inode, attr); | 946 | err = inode_change_ok(inode, attr); |
| 946 | if (err) | 947 | if (err) |
| 947 | return err; | 948 | return err; |
| @@ -1051,7 +1052,7 @@ static int update_mctime(struct ubifs_info *c, struct inode *inode) | |||
| 1051 | if (mctime_update_needed(inode, &now)) { | 1052 | if (mctime_update_needed(inode, &now)) { |
| 1052 | int err, release; | 1053 | int err, release; |
| 1053 | struct ubifs_budget_req req = { .dirtied_ino = 1, | 1054 | struct ubifs_budget_req req = { .dirtied_ino = 1, |
| 1054 | .dirtied_ino_d = ui->data_len }; | 1055 | .dirtied_ino_d = ALIGN(ui->data_len, 8) }; |
| 1055 | 1056 | ||
| 1056 | err = ubifs_budget_space(c, &req); | 1057 | err = ubifs_budget_space(c, &req); |
| 1057 | if (err) | 1058 | if (err) |
| @@ -1270,6 +1271,7 @@ struct file_operations ubifs_file_operations = { | |||
| 1270 | .fsync = ubifs_fsync, | 1271 | .fsync = ubifs_fsync, |
| 1271 | .unlocked_ioctl = ubifs_ioctl, | 1272 | .unlocked_ioctl = ubifs_ioctl, |
| 1272 | .splice_read = generic_file_splice_read, | 1273 | .splice_read = generic_file_splice_read, |
| 1274 | .splice_write = generic_file_splice_write, | ||
| 1273 | #ifdef CONFIG_COMPAT | 1275 | #ifdef CONFIG_COMPAT |
| 1274 | .compat_ioctl = ubifs_compat_ioctl, | 1276 | .compat_ioctl = ubifs_compat_ioctl, |
| 1275 | #endif | 1277 | #endif |
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c index 10394c548367..adee7b5ddeab 100644 --- a/fs/ubifs/find.c +++ b/fs/ubifs/find.c | |||
| @@ -290,9 +290,14 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp, | |||
| 290 | idx_lp = idx_heap->arr[0]; | 290 | idx_lp = idx_heap->arr[0]; |
| 291 | sum = idx_lp->free + idx_lp->dirty; | 291 | sum = idx_lp->free + idx_lp->dirty; |
| 292 | /* | 292 | /* |
| 293 | * Since we reserve twice as more space for the index than it | 293 | * Since we reserve thrice as much space for the index than it |
| 294 | * actually takes, it does not make sense to pick indexing LEBs | 294 | * actually takes, it does not make sense to pick indexing LEBs |
| 295 | * with less than half LEB of dirty space. | 295 | * with less than, say, half LEB of dirty space. May be half is |
| 296 | * not the optimal boundary - this should be tested and | ||
| 297 | * checked. This boundary should determine how much we use | ||
| 298 | * in-the-gaps to consolidate the index comparing to how much | ||
| 299 | * we use garbage collector to consolidate it. The "half" | ||
| 300 | * criteria just feels to be fine. | ||
| 296 | */ | 301 | */ |
| 297 | if (sum < min_space || sum < c->half_leb_size) | 302 | if (sum < min_space || sum < c->half_leb_size) |
| 298 | idx_lp = NULL; | 303 | idx_lp = NULL; |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 3374f91b6709..054363f2b207 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
| @@ -54,6 +54,20 @@ | |||
| 54 | #include "ubifs.h" | 54 | #include "ubifs.h" |
| 55 | 55 | ||
| 56 | /** | 56 | /** |
| 57 | * ubifs_ro_mode - switch UBIFS to read read-only mode. | ||
| 58 | * @c: UBIFS file-system description object | ||
| 59 | * @err: error code which is the reason of switching to R/O mode | ||
| 60 | */ | ||
| 61 | void ubifs_ro_mode(struct ubifs_info *c, int err) | ||
| 62 | { | ||
| 63 | if (!c->ro_media) { | ||
| 64 | c->ro_media = 1; | ||
| 65 | ubifs_warn("switched to read-only mode, error %d", err); | ||
| 66 | dbg_dump_stack(); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | /** | ||
| 57 | * ubifs_check_node - check node. | 71 | * ubifs_check_node - check node. |
| 58 | * @c: UBIFS file-system description object | 72 | * @c: UBIFS file-system description object |
| 59 | * @buf: node to check | 73 | * @buf: node to check |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index 283155abe5f5..22993f867d19 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
| @@ -447,13 +447,11 @@ static int get_dent_type(int mode) | |||
| 447 | * @ino: buffer in which to pack inode node | 447 | * @ino: buffer in which to pack inode node |
| 448 | * @inode: inode to pack | 448 | * @inode: inode to pack |
| 449 | * @last: indicates the last node of the group | 449 | * @last: indicates the last node of the group |
| 450 | * @last_reference: non-zero if this is a deletion inode | ||
| 451 | */ | 450 | */ |
| 452 | static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino, | 451 | static void pack_inode(struct ubifs_info *c, struct ubifs_ino_node *ino, |
| 453 | const struct inode *inode, int last, | 452 | const struct inode *inode, int last) |
| 454 | int last_reference) | ||
| 455 | { | 453 | { |
| 456 | int data_len = 0; | 454 | int data_len = 0, last_reference = !inode->i_nlink; |
| 457 | struct ubifs_inode *ui = ubifs_inode(inode); | 455 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 458 | 456 | ||
| 459 | ino->ch.node_type = UBIFS_INO_NODE; | 457 | ino->ch.node_type = UBIFS_INO_NODE; |
| @@ -596,9 +594,9 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
| 596 | ubifs_prep_grp_node(c, dent, dlen, 0); | 594 | ubifs_prep_grp_node(c, dent, dlen, 0); |
| 597 | 595 | ||
| 598 | ino = (void *)dent + aligned_dlen; | 596 | ino = (void *)dent + aligned_dlen; |
| 599 | pack_inode(c, ino, inode, 0, last_reference); | 597 | pack_inode(c, ino, inode, 0); |
| 600 | ino = (void *)ino + aligned_ilen; | 598 | ino = (void *)ino + aligned_ilen; |
| 601 | pack_inode(c, ino, dir, 1, 0); | 599 | pack_inode(c, ino, dir, 1); |
| 602 | 600 | ||
| 603 | if (last_reference) { | 601 | if (last_reference) { |
| 604 | err = ubifs_add_orphan(c, inode->i_ino); | 602 | err = ubifs_add_orphan(c, inode->i_ino); |
| @@ -606,6 +604,7 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
| 606 | release_head(c, BASEHD); | 604 | release_head(c, BASEHD); |
| 607 | goto out_finish; | 605 | goto out_finish; |
| 608 | } | 606 | } |
| 607 | ui->del_cmtno = c->cmt_no; | ||
| 609 | } | 608 | } |
| 610 | 609 | ||
| 611 | err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); | 610 | err = write_head(c, BASEHD, dent, len, &lnum, &dent_offs, sync); |
| @@ -750,30 +749,25 @@ out_free: | |||
| 750 | * ubifs_jnl_write_inode - flush inode to the journal. | 749 | * ubifs_jnl_write_inode - flush inode to the journal. |
| 751 | * @c: UBIFS file-system description object | 750 | * @c: UBIFS file-system description object |
| 752 | * @inode: inode to flush | 751 | * @inode: inode to flush |
| 753 | * @deletion: inode has been deleted | ||
| 754 | * | 752 | * |
| 755 | * This function writes inode @inode to the journal. If the inode is | 753 | * This function writes inode @inode to the journal. If the inode is |
| 756 | * synchronous, it also synchronizes the write-buffer. Returns zero in case of | 754 | * synchronous, it also synchronizes the write-buffer. Returns zero in case of |
| 757 | * success and a negative error code in case of failure. | 755 | * success and a negative error code in case of failure. |
| 758 | */ | 756 | */ |
| 759 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, | 757 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode) |
| 760 | int deletion) | ||
| 761 | { | 758 | { |
| 762 | int err, len, lnum, offs, sync = 0; | 759 | int err, lnum, offs; |
| 763 | struct ubifs_ino_node *ino; | 760 | struct ubifs_ino_node *ino; |
| 764 | struct ubifs_inode *ui = ubifs_inode(inode); | 761 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 762 | int sync = 0, len = UBIFS_INO_NODE_SZ, last_reference = !inode->i_nlink; | ||
| 765 | 763 | ||
| 766 | dbg_jnl("ino %lu%s", inode->i_ino, | 764 | dbg_jnl("ino %lu, nlink %u", inode->i_ino, inode->i_nlink); |
| 767 | deletion ? " (last reference)" : ""); | ||
| 768 | if (deletion) | ||
| 769 | ubifs_assert(inode->i_nlink == 0); | ||
| 770 | 765 | ||
| 771 | len = UBIFS_INO_NODE_SZ; | ||
| 772 | /* | 766 | /* |
| 773 | * If the inode is being deleted, do not write the attached data. No | 767 | * If the inode is being deleted, do not write the attached data. No |
| 774 | * need to synchronize the write-buffer either. | 768 | * need to synchronize the write-buffer either. |
| 775 | */ | 769 | */ |
| 776 | if (!deletion) { | 770 | if (!last_reference) { |
| 777 | len += ui->data_len; | 771 | len += ui->data_len; |
| 778 | sync = IS_SYNC(inode); | 772 | sync = IS_SYNC(inode); |
| 779 | } | 773 | } |
| @@ -786,7 +780,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, | |||
| 786 | if (err) | 780 | if (err) |
| 787 | goto out_free; | 781 | goto out_free; |
| 788 | 782 | ||
| 789 | pack_inode(c, ino, inode, 1, deletion); | 783 | pack_inode(c, ino, inode, 1); |
| 790 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); | 784 | err = write_head(c, BASEHD, ino, len, &lnum, &offs, sync); |
| 791 | if (err) | 785 | if (err) |
| 792 | goto out_release; | 786 | goto out_release; |
| @@ -795,7 +789,7 @@ int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, | |||
| 795 | inode->i_ino); | 789 | inode->i_ino); |
| 796 | release_head(c, BASEHD); | 790 | release_head(c, BASEHD); |
| 797 | 791 | ||
| 798 | if (deletion) { | 792 | if (last_reference) { |
| 799 | err = ubifs_tnc_remove_ino(c, inode->i_ino); | 793 | err = ubifs_tnc_remove_ino(c, inode->i_ino); |
| 800 | if (err) | 794 | if (err) |
| 801 | goto out_ro; | 795 | goto out_ro; |
| @@ -828,6 +822,65 @@ out_free: | |||
| 828 | } | 822 | } |
| 829 | 823 | ||
| 830 | /** | 824 | /** |
| 825 | * ubifs_jnl_delete_inode - delete an inode. | ||
| 826 | * @c: UBIFS file-system description object | ||
| 827 | * @inode: inode to delete | ||
| 828 | * | ||
| 829 | * This function deletes inode @inode which includes removing it from orphans, | ||
| 830 | * deleting it from TNC and, in some cases, writing a deletion inode to the | ||
| 831 | * journal. | ||
| 832 | * | ||
| 833 | * When regular file inodes are unlinked or a directory inode is removed, the | ||
| 834 | * 'ubifs_jnl_update()' function writes a corresponding deletion inode and | ||
| 835 | * direntry to the media, and adds the inode to orphans. After this, when the | ||
| 836 | * last reference to this inode has been dropped, this function is called. In | ||
| 837 | * general, it has to write one more deletion inode to the media, because if | ||
| 838 | * a commit happened between 'ubifs_jnl_update()' and | ||
| 839 | * 'ubifs_jnl_delete_inode()', the deletion inode is not in the journal | ||
| 840 | * anymore, and in fact it might not be on the flash anymore, because it might | ||
| 841 | * have been garbage-collected already. And for optimization reasons UBIFS does | ||
| 842 | * not read the orphan area if it has been unmounted cleanly, so it would have | ||
| 843 | * no indication in the journal that there is a deleted inode which has to be | ||
| 844 | * removed from TNC. | ||
| 845 | * | ||
| 846 | * However, if there was no commit between 'ubifs_jnl_update()' and | ||
| 847 | * 'ubifs_jnl_delete_inode()', then there is no need to write the deletion | ||
| 848 | * inode to the media for the second time. And this is quite a typical case. | ||
| 849 | * | ||
| 850 | * This function returns zero in case of success and a negative error code in | ||
| 851 | * case of failure. | ||
| 852 | */ | ||
| 853 | int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode) | ||
| 854 | { | ||
| 855 | int err; | ||
| 856 | struct ubifs_inode *ui = ubifs_inode(inode); | ||
| 857 | |||
| 858 | ubifs_assert(inode->i_nlink == 0); | ||
| 859 | |||
| 860 | if (ui->del_cmtno != c->cmt_no) | ||
| 861 | /* A commit happened for sure */ | ||
| 862 | return ubifs_jnl_write_inode(c, inode); | ||
| 863 | |||
| 864 | down_read(&c->commit_sem); | ||
| 865 | /* | ||
| 866 | * Check commit number again, because the first test has been done | ||
| 867 | * without @c->commit_sem, so a commit might have happened. | ||
| 868 | */ | ||
| 869 | if (ui->del_cmtno != c->cmt_no) { | ||
| 870 | up_read(&c->commit_sem); | ||
| 871 | return ubifs_jnl_write_inode(c, inode); | ||
| 872 | } | ||
| 873 | |||
| 874 | err = ubifs_tnc_remove_ino(c, inode->i_ino); | ||
| 875 | if (err) | ||
| 876 | ubifs_ro_mode(c, err); | ||
| 877 | else | ||
| 878 | ubifs_delete_orphan(c, inode->i_ino); | ||
| 879 | up_read(&c->commit_sem); | ||
| 880 | return err; | ||
| 881 | } | ||
| 882 | |||
| 883 | /** | ||
| 831 | * ubifs_jnl_rename - rename a directory entry. | 884 | * ubifs_jnl_rename - rename a directory entry. |
| 832 | * @c: UBIFS file-system description object | 885 | * @c: UBIFS file-system description object |
| 833 | * @old_dir: parent inode of directory entry to rename | 886 | * @old_dir: parent inode of directory entry to rename |
| @@ -917,16 +970,16 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
| 917 | 970 | ||
| 918 | p = (void *)dent2 + aligned_dlen2; | 971 | p = (void *)dent2 + aligned_dlen2; |
| 919 | if (new_inode) { | 972 | if (new_inode) { |
| 920 | pack_inode(c, p, new_inode, 0, last_reference); | 973 | pack_inode(c, p, new_inode, 0); |
| 921 | p += ALIGN(ilen, 8); | 974 | p += ALIGN(ilen, 8); |
| 922 | } | 975 | } |
| 923 | 976 | ||
| 924 | if (!move) | 977 | if (!move) |
| 925 | pack_inode(c, p, old_dir, 1, 0); | 978 | pack_inode(c, p, old_dir, 1); |
| 926 | else { | 979 | else { |
| 927 | pack_inode(c, p, old_dir, 0, 0); | 980 | pack_inode(c, p, old_dir, 0); |
| 928 | p += ALIGN(plen, 8); | 981 | p += ALIGN(plen, 8); |
| 929 | pack_inode(c, p, new_dir, 1, 0); | 982 | pack_inode(c, p, new_dir, 1); |
| 930 | } | 983 | } |
| 931 | 984 | ||
| 932 | if (last_reference) { | 985 | if (last_reference) { |
| @@ -935,6 +988,7 @@ int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | |||
| 935 | release_head(c, BASEHD); | 988 | release_head(c, BASEHD); |
| 936 | goto out_finish; | 989 | goto out_finish; |
| 937 | } | 990 | } |
| 991 | new_ui->del_cmtno = c->cmt_no; | ||
| 938 | } | 992 | } |
| 939 | 993 | ||
| 940 | err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); | 994 | err = write_head(c, BASEHD, dent, len, &lnum, &offs, sync); |
| @@ -1131,7 +1185,7 @@ int ubifs_jnl_truncate(struct ubifs_info *c, const struct inode *inode, | |||
| 1131 | if (err) | 1185 | if (err) |
| 1132 | goto out_free; | 1186 | goto out_free; |
| 1133 | 1187 | ||
| 1134 | pack_inode(c, ino, inode, 0, 0); | 1188 | pack_inode(c, ino, inode, 0); |
| 1135 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); | 1189 | ubifs_prep_grp_node(c, trun, UBIFS_TRUN_NODE_SZ, dlen ? 0 : 1); |
| 1136 | if (dlen) | 1190 | if (dlen) |
| 1137 | ubifs_prep_grp_node(c, dn, dlen, 1); | 1191 | ubifs_prep_grp_node(c, dn, dlen, 1); |
| @@ -1251,9 +1305,9 @@ int ubifs_jnl_delete_xattr(struct ubifs_info *c, const struct inode *host, | |||
| 1251 | ubifs_prep_grp_node(c, xent, xlen, 0); | 1305 | ubifs_prep_grp_node(c, xent, xlen, 0); |
| 1252 | 1306 | ||
| 1253 | ino = (void *)xent + aligned_xlen; | 1307 | ino = (void *)xent + aligned_xlen; |
| 1254 | pack_inode(c, ino, inode, 0, 1); | 1308 | pack_inode(c, ino, inode, 0); |
| 1255 | ino = (void *)ino + UBIFS_INO_NODE_SZ; | 1309 | ino = (void *)ino + UBIFS_INO_NODE_SZ; |
| 1256 | pack_inode(c, ino, host, 1, 0); | 1310 | pack_inode(c, ino, host, 1); |
| 1257 | 1311 | ||
| 1258 | err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); | 1312 | err = write_head(c, BASEHD, xent, len, &lnum, &xent_offs, sync); |
| 1259 | if (!sync && !err) | 1313 | if (!sync && !err) |
| @@ -1320,7 +1374,7 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
| 1320 | const struct inode *host) | 1374 | const struct inode *host) |
| 1321 | { | 1375 | { |
| 1322 | int err, len1, len2, aligned_len, aligned_len1, lnum, offs; | 1376 | int err, len1, len2, aligned_len, aligned_len1, lnum, offs; |
| 1323 | struct ubifs_inode *host_ui = ubifs_inode(inode); | 1377 | struct ubifs_inode *host_ui = ubifs_inode(host); |
| 1324 | struct ubifs_ino_node *ino; | 1378 | struct ubifs_ino_node *ino; |
| 1325 | union ubifs_key key; | 1379 | union ubifs_key key; |
| 1326 | int sync = IS_DIRSYNC(host); | 1380 | int sync = IS_DIRSYNC(host); |
| @@ -1344,8 +1398,8 @@ int ubifs_jnl_change_xattr(struct ubifs_info *c, const struct inode *inode, | |||
| 1344 | if (err) | 1398 | if (err) |
| 1345 | goto out_free; | 1399 | goto out_free; |
| 1346 | 1400 | ||
| 1347 | pack_inode(c, ino, host, 0, 0); | 1401 | pack_inode(c, ino, host, 0); |
| 1348 | pack_inode(c, (void *)ino + aligned_len1, inode, 1, 0); | 1402 | pack_inode(c, (void *)ino + aligned_len1, inode, 1); |
| 1349 | 1403 | ||
| 1350 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); | 1404 | err = write_head(c, BASEHD, ino, aligned_len, &lnum, &offs, 0); |
| 1351 | if (!sync && !err) { | 1405 | if (!sync && !err) { |
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index 36857b9ed59e..3e0aa7367556 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c | |||
| @@ -317,6 +317,8 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) | |||
| 317 | return 0; | 317 | return 0; |
| 318 | 318 | ||
| 319 | out_unlock: | 319 | out_unlock: |
| 320 | if (err != -EAGAIN) | ||
| 321 | ubifs_ro_mode(c, err); | ||
| 320 | mutex_unlock(&c->log_mutex); | 322 | mutex_unlock(&c->log_mutex); |
| 321 | kfree(ref); | 323 | kfree(ref); |
| 322 | kfree(bud); | 324 | kfree(bud); |
| @@ -410,7 +412,7 @@ int ubifs_log_start_commit(struct ubifs_info *c, int *ltail_lnum) | |||
| 410 | return -ENOMEM; | 412 | return -ENOMEM; |
| 411 | 413 | ||
| 412 | cs->ch.node_type = UBIFS_CS_NODE; | 414 | cs->ch.node_type = UBIFS_CS_NODE; |
| 413 | cs->cmt_no = cpu_to_le64(c->cmt_no + 1); | 415 | cs->cmt_no = cpu_to_le64(c->cmt_no); |
| 414 | ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); | 416 | ubifs_prepare_node(c, cs, UBIFS_CS_NODE_SZ, 0); |
| 415 | 417 | ||
| 416 | /* | 418 | /* |
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h index 4beccfc256d2..87dabf9fe742 100644 --- a/fs/ubifs/misc.h +++ b/fs/ubifs/misc.h | |||
| @@ -80,20 +80,6 @@ static inline struct ubifs_inode *ubifs_inode(const struct inode *inode) | |||
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | /** | 82 | /** |
| 83 | * ubifs_ro_mode - switch UBIFS to read read-only mode. | ||
| 84 | * @c: UBIFS file-system description object | ||
| 85 | * @err: error code which is the reason of switching to R/O mode | ||
| 86 | */ | ||
| 87 | static inline void ubifs_ro_mode(struct ubifs_info *c, int err) | ||
| 88 | { | ||
| 89 | if (!c->ro_media) { | ||
| 90 | c->ro_media = 1; | ||
| 91 | ubifs_warn("switched to read-only mode, error %d", err); | ||
| 92 | dbg_dump_stack(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | /** | ||
| 97 | * ubifs_compr_present - check if compressor was compiled in. | 83 | * ubifs_compr_present - check if compressor was compiled in. |
| 98 | * @compr_type: compressor type to check | 84 | * @compr_type: compressor type to check |
| 99 | * | 85 | * |
| @@ -322,7 +308,7 @@ static inline long long ubifs_reported_space(const struct ubifs_info *c, | |||
| 322 | { | 308 | { |
| 323 | int divisor, factor; | 309 | int divisor, factor; |
| 324 | 310 | ||
| 325 | divisor = UBIFS_MAX_DATA_NODE_SZ + (c->max_idx_node_sz << 1); | 311 | divisor = UBIFS_MAX_DATA_NODE_SZ + (c->max_idx_node_sz * 3); |
| 326 | factor = UBIFS_MAX_DATA_NODE_SZ - UBIFS_DATA_NODE_SZ; | 312 | factor = UBIFS_MAX_DATA_NODE_SZ - UBIFS_DATA_NODE_SZ; |
| 327 | do_div(free, divisor); | 313 | do_div(free, divisor); |
| 328 | 314 | ||
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 3afeb9242c6a..02d3462f4d3e 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c | |||
| @@ -310,10 +310,10 @@ static int write_orph_node(struct ubifs_info *c, int atomic) | |||
| 310 | c->cmt_orphans -= cnt; | 310 | c->cmt_orphans -= cnt; |
| 311 | spin_unlock(&c->orphan_lock); | 311 | spin_unlock(&c->orphan_lock); |
| 312 | if (c->cmt_orphans) | 312 | if (c->cmt_orphans) |
| 313 | orph->cmt_no = cpu_to_le64(c->cmt_no + 1); | 313 | orph->cmt_no = cpu_to_le64(c->cmt_no); |
| 314 | else | 314 | else |
| 315 | /* Mark the last node of the commit */ | 315 | /* Mark the last node of the commit */ |
| 316 | orph->cmt_no = cpu_to_le64((c->cmt_no + 1) | (1ULL << 63)); | 316 | orph->cmt_no = cpu_to_le64((c->cmt_no) | (1ULL << 63)); |
| 317 | ubifs_assert(c->ohead_offs + len <= c->leb_size); | 317 | ubifs_assert(c->ohead_offs + len <= c->leb_size); |
| 318 | ubifs_assert(c->ohead_lnum >= c->orph_first); | 318 | ubifs_assert(c->ohead_lnum >= c->orph_first); |
| 319 | ubifs_assert(c->ohead_lnum <= c->orph_last); | 319 | ubifs_assert(c->ohead_lnum <= c->orph_last); |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index ca1e2d4e03cc..f71e6b8822c4 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
| 32 | #include <linux/ctype.h> | 32 | #include <linux/ctype.h> |
| 33 | #include <linux/random.h> | ||
| 34 | #include <linux/kthread.h> | 33 | #include <linux/kthread.h> |
| 35 | #include <linux/parser.h> | 34 | #include <linux/parser.h> |
| 36 | #include <linux/seq_file.h> | 35 | #include <linux/seq_file.h> |
| @@ -149,7 +148,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) | |||
| 149 | if (err) | 148 | if (err) |
| 150 | goto out_invalid; | 149 | goto out_invalid; |
| 151 | 150 | ||
| 152 | /* Disable readahead */ | 151 | /* Disable read-ahead */ |
| 153 | inode->i_mapping->backing_dev_info = &c->bdi; | 152 | inode->i_mapping->backing_dev_info = &c->bdi; |
| 154 | 153 | ||
| 155 | switch (inode->i_mode & S_IFMT) { | 154 | switch (inode->i_mode & S_IFMT) { |
| @@ -278,7 +277,7 @@ static void ubifs_destroy_inode(struct inode *inode) | |||
| 278 | */ | 277 | */ |
| 279 | static int ubifs_write_inode(struct inode *inode, int wait) | 278 | static int ubifs_write_inode(struct inode *inode, int wait) |
| 280 | { | 279 | { |
| 281 | int err; | 280 | int err = 0; |
| 282 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 281 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
| 283 | struct ubifs_inode *ui = ubifs_inode(inode); | 282 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 284 | 283 | ||
| @@ -299,10 +298,18 @@ static int ubifs_write_inode(struct inode *inode, int wait) | |||
| 299 | return 0; | 298 | return 0; |
| 300 | } | 299 | } |
| 301 | 300 | ||
| 302 | dbg_gen("inode %lu", inode->i_ino); | 301 | /* |
| 303 | err = ubifs_jnl_write_inode(c, inode, 0); | 302 | * As an optimization, do not write orphan inodes to the media just |
| 304 | if (err) | 303 | * because this is not needed. |
| 305 | ubifs_err("can't write inode %lu, error %d", inode->i_ino, err); | 304 | */ |
| 305 | dbg_gen("inode %lu, mode %#x, nlink %u", | ||
| 306 | inode->i_ino, (int)inode->i_mode, inode->i_nlink); | ||
| 307 | if (inode->i_nlink) { | ||
| 308 | err = ubifs_jnl_write_inode(c, inode); | ||
| 309 | if (err) | ||
| 310 | ubifs_err("can't write inode %lu, error %d", | ||
| 311 | inode->i_ino, err); | ||
| 312 | } | ||
| 306 | 313 | ||
| 307 | ui->dirty = 0; | 314 | ui->dirty = 0; |
| 308 | mutex_unlock(&ui->ui_mutex); | 315 | mutex_unlock(&ui->ui_mutex); |
| @@ -314,8 +321,9 @@ static void ubifs_delete_inode(struct inode *inode) | |||
| 314 | { | 321 | { |
| 315 | int err; | 322 | int err; |
| 316 | struct ubifs_info *c = inode->i_sb->s_fs_info; | 323 | struct ubifs_info *c = inode->i_sb->s_fs_info; |
| 324 | struct ubifs_inode *ui = ubifs_inode(inode); | ||
| 317 | 325 | ||
| 318 | if (ubifs_inode(inode)->xattr) | 326 | if (ui->xattr) |
| 319 | /* | 327 | /* |
| 320 | * Extended attribute inode deletions are fully handled in | 328 | * Extended attribute inode deletions are fully handled in |
| 321 | * 'ubifs_removexattr()'. These inodes are special and have | 329 | * 'ubifs_removexattr()'. These inodes are special and have |
| @@ -323,7 +331,7 @@ static void ubifs_delete_inode(struct inode *inode) | |||
| 323 | */ | 331 | */ |
| 324 | goto out; | 332 | goto out; |
| 325 | 333 | ||
| 326 | dbg_gen("inode %lu", inode->i_ino); | 334 | dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode); |
| 327 | ubifs_assert(!atomic_read(&inode->i_count)); | 335 | ubifs_assert(!atomic_read(&inode->i_count)); |
| 328 | ubifs_assert(inode->i_nlink == 0); | 336 | ubifs_assert(inode->i_nlink == 0); |
| 329 | 337 | ||
| @@ -331,15 +339,19 @@ static void ubifs_delete_inode(struct inode *inode) | |||
| 331 | if (is_bad_inode(inode)) | 339 | if (is_bad_inode(inode)) |
| 332 | goto out; | 340 | goto out; |
| 333 | 341 | ||
| 334 | ubifs_inode(inode)->ui_size = inode->i_size = 0; | 342 | ui->ui_size = inode->i_size = 0; |
| 335 | err = ubifs_jnl_write_inode(c, inode, 1); | 343 | err = ubifs_jnl_delete_inode(c, inode); |
| 336 | if (err) | 344 | if (err) |
| 337 | /* | 345 | /* |
| 338 | * Worst case we have a lost orphan inode wasting space, so a | 346 | * Worst case we have a lost orphan inode wasting space, so a |
| 339 | * simple error message is ok here. | 347 | * simple error message is OK here. |
| 340 | */ | 348 | */ |
| 341 | ubifs_err("can't write inode %lu, error %d", inode->i_ino, err); | 349 | ubifs_err("can't delete inode %lu, error %d", |
| 350 | inode->i_ino, err); | ||
| 351 | |||
| 342 | out: | 352 | out: |
| 353 | if (ui->dirty) | ||
| 354 | ubifs_release_dirty_inode_budget(c, ui); | ||
| 343 | clear_inode(inode); | 355 | clear_inode(inode); |
| 344 | } | 356 | } |
| 345 | 357 | ||
| @@ -1122,8 +1134,8 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1122 | if (err) | 1134 | if (err) |
| 1123 | goto out_infos; | 1135 | goto out_infos; |
| 1124 | 1136 | ||
| 1125 | ubifs_msg("mounted UBI device %d, volume %d", c->vi.ubi_num, | 1137 | ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"", |
| 1126 | c->vi.vol_id); | 1138 | c->vi.ubi_num, c->vi.vol_id, c->vi.name); |
| 1127 | if (mounted_read_only) | 1139 | if (mounted_read_only) |
| 1128 | ubifs_msg("mounted read-only"); | 1140 | ubifs_msg("mounted read-only"); |
| 1129 | x = (long long)c->main_lebs * c->leb_size; | 1141 | x = (long long)c->main_lebs * c->leb_size; |
| @@ -1469,6 +1481,7 @@ static void ubifs_put_super(struct super_block *sb) | |||
| 1469 | */ | 1481 | */ |
| 1470 | ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); | 1482 | ubifs_assert(atomic_long_read(&c->dirty_pg_cnt) == 0); |
| 1471 | ubifs_assert(c->budg_idx_growth == 0); | 1483 | ubifs_assert(c->budg_idx_growth == 0); |
| 1484 | ubifs_assert(c->budg_dd_growth == 0); | ||
| 1472 | ubifs_assert(c->budg_data_growth == 0); | 1485 | ubifs_assert(c->budg_data_growth == 0); |
| 1473 | 1486 | ||
| 1474 | /* | 1487 | /* |
| @@ -1657,7 +1670,6 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1657 | INIT_LIST_HEAD(&c->orph_new); | 1670 | INIT_LIST_HEAD(&c->orph_new); |
| 1658 | 1671 | ||
| 1659 | c->highest_inum = UBIFS_FIRST_INO; | 1672 | c->highest_inum = UBIFS_FIRST_INO; |
| 1660 | get_random_bytes(&c->vfs_gen, sizeof(int)); | ||
| 1661 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; | 1673 | c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; |
| 1662 | 1674 | ||
| 1663 | ubi_get_volume_info(ubi, &c->vi); | 1675 | ubi_get_volume_info(ubi, &c->vi); |
| @@ -1671,10 +1683,10 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1671 | } | 1683 | } |
| 1672 | 1684 | ||
| 1673 | /* | 1685 | /* |
| 1674 | * UBIFS provids 'backing_dev_info' in order to disable readahead. For | 1686 | * UBIFS provides 'backing_dev_info' in order to disable read-ahead. For |
| 1675 | * UBIFS, I/O is not deferred, it is done immediately in readpage, | 1687 | * UBIFS, I/O is not deferred, it is done immediately in readpage, |
| 1676 | * which means the user would have to wait not just for their own I/O | 1688 | * which means the user would have to wait not just for their own I/O |
| 1677 | * but the readahead I/O as well i.e. completely pointless. | 1689 | * but the read-ahead I/O as well i.e. completely pointless. |
| 1678 | * | 1690 | * |
| 1679 | * Read-ahead will be disabled because @c->bdi.ra_pages is 0. | 1691 | * Read-ahead will be disabled because @c->bdi.ra_pages is 0. |
| 1680 | */ | 1692 | */ |
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index 8117e65ba2e9..8ac76b1c2d55 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c | |||
| @@ -372,26 +372,25 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) | |||
| 372 | written = layout_leb_in_gaps(c, p); | 372 | written = layout_leb_in_gaps(c, p); |
| 373 | if (written < 0) { | 373 | if (written < 0) { |
| 374 | err = written; | 374 | err = written; |
| 375 | if (err == -ENOSPC) { | 375 | if (err != -ENOSPC) { |
| 376 | if (!dbg_force_in_the_gaps_enabled) { | 376 | kfree(c->gap_lebs); |
| 377 | /* | 377 | c->gap_lebs = NULL; |
| 378 | * Do not print scary warnings if the | 378 | return err; |
| 379 | * debugging option which forces | ||
| 380 | * in-the-gaps is enabled. | ||
| 381 | */ | ||
| 382 | ubifs_err("out of space"); | ||
| 383 | spin_lock(&c->space_lock); | ||
| 384 | dbg_dump_budg(c); | ||
| 385 | spin_unlock(&c->space_lock); | ||
| 386 | dbg_dump_lprops(c); | ||
| 387 | } | ||
| 388 | /* Try to commit anyway */ | ||
| 389 | err = 0; | ||
| 390 | break; | ||
| 391 | } | 379 | } |
| 392 | kfree(c->gap_lebs); | 380 | if (!dbg_force_in_the_gaps_enabled) { |
| 393 | c->gap_lebs = NULL; | 381 | /* |
| 394 | return err; | 382 | * Do not print scary warnings if the debugging |
| 383 | * option which forces in-the-gaps is enabled. | ||
| 384 | */ | ||
| 385 | ubifs_err("out of space"); | ||
| 386 | spin_lock(&c->space_lock); | ||
| 387 | dbg_dump_budg(c); | ||
| 388 | spin_unlock(&c->space_lock); | ||
| 389 | dbg_dump_lprops(c); | ||
| 390 | } | ||
| 391 | /* Try to commit anyway */ | ||
| 392 | err = 0; | ||
| 393 | break; | ||
| 395 | } | 394 | } |
| 396 | p++; | 395 | p++; |
| 397 | cnt -= written; | 396 | cnt -= written; |
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h index 0cc7da9bed47..bd2121f3426e 100644 --- a/fs/ubifs/ubifs-media.h +++ b/fs/ubifs/ubifs-media.h | |||
| @@ -228,10 +228,10 @@ enum { | |||
| 228 | /* Minimum number of orphan area logical eraseblocks */ | 228 | /* Minimum number of orphan area logical eraseblocks */ |
| 229 | #define UBIFS_MIN_ORPH_LEBS 1 | 229 | #define UBIFS_MIN_ORPH_LEBS 1 |
| 230 | /* | 230 | /* |
| 231 | * Minimum number of main area logical eraseblocks (buds, 2 for the index, 1 | 231 | * Minimum number of main area logical eraseblocks (buds, 3 for the index, 1 |
| 232 | * for GC, 1 for deletions, and at least 1 for committed data). | 232 | * for GC, 1 for deletions, and at least 1 for committed data). |
| 233 | */ | 233 | */ |
| 234 | #define UBIFS_MIN_MAIN_LEBS (UBIFS_MIN_BUD_LEBS + 5) | 234 | #define UBIFS_MIN_MAIN_LEBS (UBIFS_MIN_BUD_LEBS + 6) |
| 235 | 235 | ||
| 236 | /* Minimum number of logical eraseblocks */ | 236 | /* Minimum number of logical eraseblocks */ |
| 237 | #define UBIFS_MIN_LEB_CNT (UBIFS_SB_LEBS + UBIFS_MST_LEBS + \ | 237 | #define UBIFS_MIN_LEB_CNT (UBIFS_SB_LEBS + UBIFS_MST_LEBS + \ |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index e4f89f271827..d7f706f7a302 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -20,8 +20,6 @@ | |||
| 20 | * Adrian Hunter | 20 | * Adrian Hunter |
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | /* Implementation version 0.7 */ | ||
| 24 | |||
| 25 | #ifndef __UBIFS_H__ | 23 | #ifndef __UBIFS_H__ |
| 26 | #define __UBIFS_H__ | 24 | #define __UBIFS_H__ |
| 27 | 25 | ||
| @@ -322,6 +320,8 @@ struct ubifs_gced_idx_leb { | |||
| 322 | * struct ubifs_inode - UBIFS in-memory inode description. | 320 | * struct ubifs_inode - UBIFS in-memory inode description. |
| 323 | * @vfs_inode: VFS inode description object | 321 | * @vfs_inode: VFS inode description object |
| 324 | * @creat_sqnum: sequence number at time of creation | 322 | * @creat_sqnum: sequence number at time of creation |
| 323 | * @del_cmtno: commit number corresponding to the time the inode was deleted, | ||
| 324 | * protected by @c->commit_sem; | ||
| 325 | * @xattr_size: summarized size of all extended attributes in bytes | 325 | * @xattr_size: summarized size of all extended attributes in bytes |
| 326 | * @xattr_cnt: count of extended attributes this inode has | 326 | * @xattr_cnt: count of extended attributes this inode has |
| 327 | * @xattr_names: sum of lengths of all extended attribute names belonging to | 327 | * @xattr_names: sum of lengths of all extended attribute names belonging to |
| @@ -373,6 +373,7 @@ struct ubifs_gced_idx_leb { | |||
| 373 | struct ubifs_inode { | 373 | struct ubifs_inode { |
| 374 | struct inode vfs_inode; | 374 | struct inode vfs_inode; |
| 375 | unsigned long long creat_sqnum; | 375 | unsigned long long creat_sqnum; |
| 376 | unsigned long long del_cmtno; | ||
| 376 | unsigned int xattr_size; | 377 | unsigned int xattr_size; |
| 377 | unsigned int xattr_cnt; | 378 | unsigned int xattr_cnt; |
| 378 | unsigned int xattr_names; | 379 | unsigned int xattr_names; |
| @@ -779,7 +780,7 @@ struct ubifs_compressor { | |||
| 779 | /** | 780 | /** |
| 780 | * struct ubifs_budget_req - budget requirements of an operation. | 781 | * struct ubifs_budget_req - budget requirements of an operation. |
| 781 | * | 782 | * |
| 782 | * @fast: non-zero if the budgeting should try to aquire budget quickly and | 783 | * @fast: non-zero if the budgeting should try to acquire budget quickly and |
| 783 | * should not try to call write-back | 784 | * should not try to call write-back |
| 784 | * @recalculate: non-zero if @idx_growth, @data_growth, and @dd_growth fields | 785 | * @recalculate: non-zero if @idx_growth, @data_growth, and @dd_growth fields |
| 785 | * have to be re-calculated | 786 | * have to be re-calculated |
| @@ -805,21 +806,31 @@ struct ubifs_compressor { | |||
| 805 | * An inode may contain 4KiB of data at max., thus the widths of @new_ino_d | 806 | * An inode may contain 4KiB of data at max., thus the widths of @new_ino_d |
| 806 | * is 13 bits, and @dirtied_ino_d - 15, because up to 4 inodes may be made | 807 | * is 13 bits, and @dirtied_ino_d - 15, because up to 4 inodes may be made |
| 807 | * dirty by the re-name operation. | 808 | * dirty by the re-name operation. |
| 809 | * | ||
| 810 | * Note, UBIFS aligns node lengths to 8-bytes boundary, so the requester has to | ||
| 811 | * make sure the amount of inode data which contribute to @new_ino_d and | ||
| 812 | * @dirtied_ino_d fields are aligned. | ||
| 808 | */ | 813 | */ |
| 809 | struct ubifs_budget_req { | 814 | struct ubifs_budget_req { |
| 810 | unsigned int fast:1; | 815 | unsigned int fast:1; |
| 811 | unsigned int recalculate:1; | 816 | unsigned int recalculate:1; |
| 817 | #ifndef UBIFS_DEBUG | ||
| 812 | unsigned int new_page:1; | 818 | unsigned int new_page:1; |
| 813 | unsigned int dirtied_page:1; | 819 | unsigned int dirtied_page:1; |
| 814 | unsigned int new_dent:1; | 820 | unsigned int new_dent:1; |
| 815 | unsigned int mod_dent:1; | 821 | unsigned int mod_dent:1; |
| 816 | unsigned int new_ino:1; | 822 | unsigned int new_ino:1; |
| 817 | unsigned int new_ino_d:13; | 823 | unsigned int new_ino_d:13; |
| 818 | #ifndef UBIFS_DEBUG | ||
| 819 | unsigned int dirtied_ino:4; | 824 | unsigned int dirtied_ino:4; |
| 820 | unsigned int dirtied_ino_d:15; | 825 | unsigned int dirtied_ino_d:15; |
| 821 | #else | 826 | #else |
| 822 | /* Not bit-fields to check for overflows */ | 827 | /* Not bit-fields to check for overflows */ |
| 828 | unsigned int new_page; | ||
| 829 | unsigned int dirtied_page; | ||
| 830 | unsigned int new_dent; | ||
| 831 | unsigned int mod_dent; | ||
| 832 | unsigned int new_ino; | ||
| 833 | unsigned int new_ino_d; | ||
| 823 | unsigned int dirtied_ino; | 834 | unsigned int dirtied_ino; |
| 824 | unsigned int dirtied_ino_d; | 835 | unsigned int dirtied_ino_d; |
| 825 | #endif | 836 | #endif |
| @@ -860,13 +871,13 @@ struct ubifs_mount_opts { | |||
| 860 | * struct ubifs_info - UBIFS file-system description data structure | 871 | * struct ubifs_info - UBIFS file-system description data structure |
| 861 | * (per-superblock). | 872 | * (per-superblock). |
| 862 | * @vfs_sb: VFS @struct super_block object | 873 | * @vfs_sb: VFS @struct super_block object |
| 863 | * @bdi: backing device info object to make VFS happy and disable readahead | 874 | * @bdi: backing device info object to make VFS happy and disable read-ahead |
| 864 | * | 875 | * |
| 865 | * @highest_inum: highest used inode number | 876 | * @highest_inum: highest used inode number |
| 866 | * @vfs_gen: VFS inode generation counter | ||
| 867 | * @max_sqnum: current global sequence number | 877 | * @max_sqnum: current global sequence number |
| 868 | * @cmt_no: commit number (last successfully completed commit) | 878 | * @cmt_no: commit number of the last successfully completed commit, protected |
| 869 | * @cnt_lock: protects @highest_inum, @vfs_gen, and @max_sqnum counters | 879 | * by @commit_sem |
| 880 | * @cnt_lock: protects @highest_inum and @max_sqnum counters | ||
| 870 | * @fmt_version: UBIFS on-flash format version | 881 | * @fmt_version: UBIFS on-flash format version |
| 871 | * @uuid: UUID from super block | 882 | * @uuid: UUID from super block |
| 872 | * | 883 | * |
| @@ -1103,7 +1114,6 @@ struct ubifs_info { | |||
| 1103 | struct backing_dev_info bdi; | 1114 | struct backing_dev_info bdi; |
| 1104 | 1115 | ||
| 1105 | ino_t highest_inum; | 1116 | ino_t highest_inum; |
| 1106 | unsigned int vfs_gen; | ||
| 1107 | unsigned long long max_sqnum; | 1117 | unsigned long long max_sqnum; |
| 1108 | unsigned long long cmt_no; | 1118 | unsigned long long cmt_no; |
| 1109 | spinlock_t cnt_lock; | 1119 | spinlock_t cnt_lock; |
| @@ -1346,6 +1356,7 @@ extern struct backing_dev_info ubifs_backing_dev_info; | |||
| 1346 | extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; | 1356 | extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; |
| 1347 | 1357 | ||
| 1348 | /* io.c */ | 1358 | /* io.c */ |
| 1359 | void ubifs_ro_mode(struct ubifs_info *c, int err); | ||
| 1349 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); | 1360 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); |
| 1350 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | 1361 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, |
| 1351 | int dtype); | 1362 | int dtype); |
| @@ -1399,8 +1410,8 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir, | |||
| 1399 | int deletion, int xent); | 1410 | int deletion, int xent); |
| 1400 | int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, | 1411 | int ubifs_jnl_write_data(struct ubifs_info *c, const struct inode *inode, |
| 1401 | const union ubifs_key *key, const void *buf, int len); | 1412 | const union ubifs_key *key, const void *buf, int len); |
| 1402 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode, | 1413 | int ubifs_jnl_write_inode(struct ubifs_info *c, const struct inode *inode); |
| 1403 | int last_reference); | 1414 | int ubifs_jnl_delete_inode(struct ubifs_info *c, const struct inode *inode); |
| 1404 | int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, | 1415 | int ubifs_jnl_rename(struct ubifs_info *c, const struct inode *old_dir, |
| 1405 | const struct dentry *old_dentry, | 1416 | const struct dentry *old_dentry, |
| 1406 | const struct inode *new_dir, | 1417 | const struct inode *new_dir, |
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c index 1388a078e1a9..649bec78b645 100644 --- a/fs/ubifs/xattr.c +++ b/fs/ubifs/xattr.c | |||
| @@ -61,7 +61,7 @@ | |||
| 61 | 61 | ||
| 62 | /* | 62 | /* |
| 63 | * Limit the number of extended attributes per inode so that the total size | 63 | * Limit the number of extended attributes per inode so that the total size |
| 64 | * (xattr_size) is guaranteeded to fit in an 'unsigned int'. | 64 | * (@xattr_size) is guaranteeded to fit in an 'unsigned int'. |
| 65 | */ | 65 | */ |
| 66 | #define MAX_XATTRS_PER_INODE 65535 | 66 | #define MAX_XATTRS_PER_INODE 65535 |
| 67 | 67 | ||
| @@ -103,14 +103,14 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, | |||
| 103 | struct inode *inode; | 103 | struct inode *inode; |
| 104 | struct ubifs_inode *ui, *host_ui = ubifs_inode(host); | 104 | struct ubifs_inode *ui, *host_ui = ubifs_inode(host); |
| 105 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, | 105 | struct ubifs_budget_req req = { .new_ino = 1, .new_dent = 1, |
| 106 | .new_ino_d = size, .dirtied_ino = 1, | 106 | .new_ino_d = ALIGN(size, 8), .dirtied_ino = 1, |
| 107 | .dirtied_ino_d = host_ui->data_len}; | 107 | .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; |
| 108 | 108 | ||
| 109 | if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) | 109 | if (host_ui->xattr_cnt >= MAX_XATTRS_PER_INODE) |
| 110 | return -ENOSPC; | 110 | return -ENOSPC; |
| 111 | /* | 111 | /* |
| 112 | * Linux limits the maximum size of the extended attribute names list | 112 | * Linux limits the maximum size of the extended attribute names list |
| 113 | * to %XATTR_LIST_MAX. This means we should not allow creating more* | 113 | * to %XATTR_LIST_MAX. This means we should not allow creating more |
| 114 | * extended attributes if the name list becomes larger. This limitation | 114 | * extended attributes if the name list becomes larger. This limitation |
| 115 | * is artificial for UBIFS, though. | 115 | * is artificial for UBIFS, though. |
| 116 | */ | 116 | */ |
| @@ -128,7 +128,6 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, | |||
| 128 | goto out_budg; | 128 | goto out_budg; |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | mutex_lock(&host_ui->ui_mutex); | ||
| 132 | /* Re-define all operations to be "nothing" */ | 131 | /* Re-define all operations to be "nothing" */ |
| 133 | inode->i_mapping->a_ops = &none_address_operations; | 132 | inode->i_mapping->a_ops = &none_address_operations; |
| 134 | inode->i_op = &none_inode_operations; | 133 | inode->i_op = &none_inode_operations; |
| @@ -141,23 +140,19 @@ static int create_xattr(struct ubifs_info *c, struct inode *host, | |||
| 141 | ui->data = kmalloc(size, GFP_NOFS); | 140 | ui->data = kmalloc(size, GFP_NOFS); |
| 142 | if (!ui->data) { | 141 | if (!ui->data) { |
| 143 | err = -ENOMEM; | 142 | err = -ENOMEM; |
| 144 | goto out_unlock; | 143 | goto out_free; |
| 145 | } | 144 | } |
| 146 | |||
| 147 | memcpy(ui->data, value, size); | 145 | memcpy(ui->data, value, size); |
| 146 | inode->i_size = ui->ui_size = size; | ||
| 147 | ui->data_len = size; | ||
| 148 | |||
| 149 | mutex_lock(&host_ui->ui_mutex); | ||
| 148 | host->i_ctime = ubifs_current_time(host); | 150 | host->i_ctime = ubifs_current_time(host); |
| 149 | host_ui->xattr_cnt += 1; | 151 | host_ui->xattr_cnt += 1; |
| 150 | host_ui->xattr_size += CALC_DENT_SIZE(nm->len); | 152 | host_ui->xattr_size += CALC_DENT_SIZE(nm->len); |
| 151 | host_ui->xattr_size += CALC_XATTR_BYTES(size); | 153 | host_ui->xattr_size += CALC_XATTR_BYTES(size); |
| 152 | host_ui->xattr_names += nm->len; | 154 | host_ui->xattr_names += nm->len; |
| 153 | 155 | ||
| 154 | /* | ||
| 155 | * We do not use i_size_write() because nobody can race with us as we | ||
| 156 | * are holding host @host->i_mutex - every xattr operation for this | ||
| 157 | * inode is serialized by it. | ||
| 158 | */ | ||
| 159 | inode->i_size = ui->ui_size = size; | ||
| 160 | ui->data_len = size; | ||
| 161 | err = ubifs_jnl_update(c, host, nm, inode, 0, 1); | 156 | err = ubifs_jnl_update(c, host, nm, inode, 0, 1); |
| 162 | if (err) | 157 | if (err) |
| 163 | goto out_cancel; | 158 | goto out_cancel; |
| @@ -172,8 +167,8 @@ out_cancel: | |||
| 172 | host_ui->xattr_cnt -= 1; | 167 | host_ui->xattr_cnt -= 1; |
| 173 | host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); | 168 | host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); |
| 174 | host_ui->xattr_size -= CALC_XATTR_BYTES(size); | 169 | host_ui->xattr_size -= CALC_XATTR_BYTES(size); |
| 175 | out_unlock: | ||
| 176 | mutex_unlock(&host_ui->ui_mutex); | 170 | mutex_unlock(&host_ui->ui_mutex); |
| 171 | out_free: | ||
| 177 | make_bad_inode(inode); | 172 | make_bad_inode(inode); |
| 178 | iput(inode); | 173 | iput(inode); |
| 179 | out_budg: | 174 | out_budg: |
| @@ -200,29 +195,28 @@ static int change_xattr(struct ubifs_info *c, struct inode *host, | |||
| 200 | struct ubifs_inode *host_ui = ubifs_inode(host); | 195 | struct ubifs_inode *host_ui = ubifs_inode(host); |
| 201 | struct ubifs_inode *ui = ubifs_inode(inode); | 196 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 202 | struct ubifs_budget_req req = { .dirtied_ino = 2, | 197 | struct ubifs_budget_req req = { .dirtied_ino = 2, |
| 203 | .dirtied_ino_d = size + host_ui->data_len }; | 198 | .dirtied_ino_d = ALIGN(size, 8) + ALIGN(host_ui->data_len, 8) }; |
| 204 | 199 | ||
| 205 | ubifs_assert(ui->data_len == inode->i_size); | 200 | ubifs_assert(ui->data_len == inode->i_size); |
| 206 | err = ubifs_budget_space(c, &req); | 201 | err = ubifs_budget_space(c, &req); |
| 207 | if (err) | 202 | if (err) |
| 208 | return err; | 203 | return err; |
| 209 | 204 | ||
| 210 | mutex_lock(&host_ui->ui_mutex); | ||
| 211 | host->i_ctime = ubifs_current_time(host); | ||
| 212 | host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); | ||
| 213 | host_ui->xattr_size += CALC_XATTR_BYTES(size); | ||
| 214 | |||
| 215 | kfree(ui->data); | 205 | kfree(ui->data); |
| 216 | ui->data = kmalloc(size, GFP_NOFS); | 206 | ui->data = kmalloc(size, GFP_NOFS); |
| 217 | if (!ui->data) { | 207 | if (!ui->data) { |
| 218 | err = -ENOMEM; | 208 | err = -ENOMEM; |
| 219 | goto out_unlock; | 209 | goto out_free; |
| 220 | } | 210 | } |
| 221 | |||
| 222 | memcpy(ui->data, value, size); | 211 | memcpy(ui->data, value, size); |
| 223 | inode->i_size = ui->ui_size = size; | 212 | inode->i_size = ui->ui_size = size; |
| 224 | ui->data_len = size; | 213 | ui->data_len = size; |
| 225 | 214 | ||
| 215 | mutex_lock(&host_ui->ui_mutex); | ||
| 216 | host->i_ctime = ubifs_current_time(host); | ||
| 217 | host_ui->xattr_size -= CALC_XATTR_BYTES(ui->data_len); | ||
| 218 | host_ui->xattr_size += CALC_XATTR_BYTES(size); | ||
| 219 | |||
| 226 | /* | 220 | /* |
| 227 | * It is important to write the host inode after the xattr inode | 221 | * It is important to write the host inode after the xattr inode |
| 228 | * because if the host inode gets synchronized (via 'fsync()'), then | 222 | * because if the host inode gets synchronized (via 'fsync()'), then |
| @@ -240,9 +234,9 @@ static int change_xattr(struct ubifs_info *c, struct inode *host, | |||
| 240 | out_cancel: | 234 | out_cancel: |
| 241 | host_ui->xattr_size -= CALC_XATTR_BYTES(size); | 235 | host_ui->xattr_size -= CALC_XATTR_BYTES(size); |
| 242 | host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); | 236 | host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len); |
| 243 | make_bad_inode(inode); | ||
| 244 | out_unlock: | ||
| 245 | mutex_unlock(&host_ui->ui_mutex); | 237 | mutex_unlock(&host_ui->ui_mutex); |
| 238 | make_bad_inode(inode); | ||
| 239 | out_free: | ||
| 246 | ubifs_release_budget(c, &req); | 240 | ubifs_release_budget(c, &req); |
| 247 | return err; | 241 | return err; |
| 248 | } | 242 | } |
| @@ -312,6 +306,7 @@ int ubifs_setxattr(struct dentry *dentry, const char *name, | |||
| 312 | 306 | ||
| 313 | dbg_gen("xattr '%s', host ino %lu ('%.*s'), size %zd", name, | 307 | dbg_gen("xattr '%s', host ino %lu ('%.*s'), size %zd", name, |
| 314 | host->i_ino, dentry->d_name.len, dentry->d_name.name, size); | 308 | host->i_ino, dentry->d_name.len, dentry->d_name.name, size); |
| 309 | ubifs_assert(mutex_is_locked(&host->i_mutex)); | ||
| 315 | 310 | ||
| 316 | if (size > UBIFS_MAX_INO_DATA) | 311 | if (size > UBIFS_MAX_INO_DATA) |
| 317 | return -ERANGE; | 312 | return -ERANGE; |
| @@ -384,7 +379,6 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, | |||
| 384 | if (!xent) | 379 | if (!xent) |
| 385 | return -ENOMEM; | 380 | return -ENOMEM; |
| 386 | 381 | ||
| 387 | mutex_lock(&host->i_mutex); | ||
| 388 | xent_key_init(c, &key, host->i_ino, &nm); | 382 | xent_key_init(c, &key, host->i_ino, &nm); |
| 389 | err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); | 383 | err = ubifs_tnc_lookup_nm(c, &key, xent, &nm); |
| 390 | if (err) { | 384 | if (err) { |
| @@ -419,7 +413,6 @@ ssize_t ubifs_getxattr(struct dentry *dentry, const char *name, void *buf, | |||
| 419 | out_iput: | 413 | out_iput: |
| 420 | iput(inode); | 414 | iput(inode); |
| 421 | out_unlock: | 415 | out_unlock: |
| 422 | mutex_unlock(&host->i_mutex); | ||
| 423 | kfree(xent); | 416 | kfree(xent); |
| 424 | return err; | 417 | return err; |
| 425 | } | 418 | } |
| @@ -449,8 +442,6 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 449 | return -ERANGE; | 442 | return -ERANGE; |
| 450 | 443 | ||
| 451 | lowest_xent_key(c, &key, host->i_ino); | 444 | lowest_xent_key(c, &key, host->i_ino); |
| 452 | |||
| 453 | mutex_lock(&host->i_mutex); | ||
| 454 | while (1) { | 445 | while (1) { |
| 455 | int type; | 446 | int type; |
| 456 | 447 | ||
| @@ -479,7 +470,6 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 479 | pxent = xent; | 470 | pxent = xent; |
| 480 | key_read(c, &xent->key, &key); | 471 | key_read(c, &xent->key, &key); |
| 481 | } | 472 | } |
| 482 | mutex_unlock(&host->i_mutex); | ||
| 483 | 473 | ||
| 484 | kfree(pxent); | 474 | kfree(pxent); |
| 485 | if (err != -ENOENT) { | 475 | if (err != -ENOENT) { |
| @@ -497,8 +487,8 @@ static int remove_xattr(struct ubifs_info *c, struct inode *host, | |||
| 497 | int err; | 487 | int err; |
| 498 | struct ubifs_inode *host_ui = ubifs_inode(host); | 488 | struct ubifs_inode *host_ui = ubifs_inode(host); |
| 499 | struct ubifs_inode *ui = ubifs_inode(inode); | 489 | struct ubifs_inode *ui = ubifs_inode(inode); |
| 500 | struct ubifs_budget_req req = { .dirtied_ino = 1, .mod_dent = 1, | 490 | struct ubifs_budget_req req = { .dirtied_ino = 2, .mod_dent = 1, |
| 501 | .dirtied_ino_d = host_ui->data_len }; | 491 | .dirtied_ino_d = ALIGN(host_ui->data_len, 8) }; |
| 502 | 492 | ||
| 503 | ubifs_assert(ui->data_len == inode->i_size); | 493 | ubifs_assert(ui->data_len == inode->i_size); |
| 504 | 494 | ||
diff --git a/include/asm-mips/kexec.h b/include/asm-mips/kexec.h index cdbab43b7d3a..4314892aaebb 100644 --- a/include/asm-mips/kexec.h +++ b/include/asm-mips/kexec.h | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | /* Maximum address we can use for the control code buffer */ | 16 | /* Maximum address we can use for the control code buffer */ |
| 17 | #define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000) | 17 | #define KEXEC_CONTROL_MEMORY_LIMIT (0x20000000) |
| 18 | 18 | ||
| 19 | #define KEXEC_CONTROL_CODE_SIZE 4096 | 19 | #define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 20 | 20 | ||
| 21 | /* The native architecture */ | 21 | /* The native architecture */ |
| 22 | #define KEXEC_ARCH KEXEC_ARCH_MIPS | 22 | #define KEXEC_ARCH KEXEC_ARCH_MIPS |
diff --git a/include/asm-x86/kexec.h b/include/asm-x86/kexec.h index c0e52a14fd4d..4246ab7dc988 100644 --- a/include/asm-x86/kexec.h +++ b/include/asm-x86/kexec.h | |||
| @@ -41,6 +41,10 @@ | |||
| 41 | # define PAGES_NR 17 | 41 | # define PAGES_NR 17 |
| 42 | #endif | 42 | #endif |
| 43 | 43 | ||
| 44 | #ifdef CONFIG_X86_32 | ||
| 45 | # define KEXEC_CONTROL_CODE_MAX_SIZE 2048 | ||
| 46 | #endif | ||
| 47 | |||
| 44 | #ifndef __ASSEMBLY__ | 48 | #ifndef __ASSEMBLY__ |
| 45 | 49 | ||
| 46 | #include <linux/string.h> | 50 | #include <linux/string.h> |
| @@ -63,7 +67,7 @@ | |||
| 63 | /* Maximum address we can use for the control code buffer */ | 67 | /* Maximum address we can use for the control code buffer */ |
| 64 | # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE | 68 | # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE |
| 65 | 69 | ||
| 66 | # define KEXEC_CONTROL_CODE_SIZE 4096 | 70 | # define KEXEC_CONTROL_PAGE_SIZE 4096 |
| 67 | 71 | ||
| 68 | /* The native architecture */ | 72 | /* The native architecture */ |
| 69 | # define KEXEC_ARCH KEXEC_ARCH_386 | 73 | # define KEXEC_ARCH KEXEC_ARCH_386 |
| @@ -79,7 +83,7 @@ | |||
| 79 | # define KEXEC_CONTROL_MEMORY_LIMIT (0xFFFFFFFFFFUL) | 83 | # define KEXEC_CONTROL_MEMORY_LIMIT (0xFFFFFFFFFFUL) |
| 80 | 84 | ||
| 81 | /* Allocate one page for the pdp and the second for the code */ | 85 | /* Allocate one page for the pdp and the second for the code */ |
| 82 | # define KEXEC_CONTROL_CODE_SIZE (4096UL + 4096UL) | 86 | # define KEXEC_CONTROL_PAGE_SIZE (4096UL + 4096UL) |
| 83 | 87 | ||
| 84 | /* The native architecture */ | 88 | /* The native architecture */ |
| 85 | # define KEXEC_ARCH KEXEC_ARCH_X86_64 | 89 | # define KEXEC_ARCH KEXEC_ARCH_X86_64 |
diff --git a/include/asm-x86/mman.h b/include/asm-x86/mman.h index c1682b542daf..90bc4108a4fd 100644 --- a/include/asm-x86/mman.h +++ b/include/asm-x86/mman.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | 12 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ |
| 13 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | 13 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ |
| 14 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | 14 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ |
| 15 | #define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ | ||
| 15 | 16 | ||
| 16 | #define MCL_CURRENT 1 /* lock all current mappings */ | 17 | #define MCL_CURRENT 1 /* lock all current mappings */ |
| 17 | #define MCL_FUTURE 2 /* lock all future mappings */ | 18 | #define MCL_FUTURE 2 /* lock all future mappings */ |
diff --git a/include/linux/completion.h b/include/linux/completion.h index 57faa60de9bd..02ef8835999c 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h | |||
| @@ -49,6 +49,8 @@ extern unsigned long wait_for_completion_timeout(struct completion *x, | |||
| 49 | unsigned long timeout); | 49 | unsigned long timeout); |
| 50 | extern unsigned long wait_for_completion_interruptible_timeout( | 50 | extern unsigned long wait_for_completion_interruptible_timeout( |
| 51 | struct completion *x, unsigned long timeout); | 51 | struct completion *x, unsigned long timeout); |
| 52 | extern bool try_wait_for_completion(struct completion *x); | ||
| 53 | extern bool completion_done(struct completion *x); | ||
| 52 | 54 | ||
| 53 | extern void complete(struct completion *); | 55 | extern void complete(struct completion *); |
| 54 | extern void complete_all(struct completion *); | 56 | extern void complete_all(struct completion *); |
| @@ -56,48 +58,4 @@ extern void complete_all(struct completion *); | |||
| 56 | #define INIT_COMPLETION(x) ((x).done = 0) | 58 | #define INIT_COMPLETION(x) ((x).done = 0) |
| 57 | 59 | ||
| 58 | 60 | ||
| 59 | /** | ||
| 60 | * try_wait_for_completion - try to decrement a completion without blocking | ||
| 61 | * @x: completion structure | ||
| 62 | * | ||
| 63 | * Returns: 0 if a decrement cannot be done without blocking | ||
| 64 | * 1 if a decrement succeeded. | ||
| 65 | * | ||
| 66 | * If a completion is being used as a counting completion, | ||
| 67 | * attempt to decrement the counter without blocking. This | ||
| 68 | * enables us to avoid waiting if the resource the completion | ||
| 69 | * is protecting is not available. | ||
| 70 | */ | ||
| 71 | static inline bool try_wait_for_completion(struct completion *x) | ||
| 72 | { | ||
| 73 | int ret = 1; | ||
| 74 | |||
| 75 | spin_lock_irq(&x->wait.lock); | ||
| 76 | if (!x->done) | ||
| 77 | ret = 0; | ||
| 78 | else | ||
| 79 | x->done--; | ||
| 80 | spin_unlock_irq(&x->wait.lock); | ||
| 81 | return ret; | ||
| 82 | } | ||
| 83 | |||
| 84 | /** | ||
| 85 | * completion_done - Test to see if a completion has any waiters | ||
| 86 | * @x: completion structure | ||
| 87 | * | ||
| 88 | * Returns: 0 if there are waiters (wait_for_completion() in progress) | ||
| 89 | * 1 if there are no waiters. | ||
| 90 | * | ||
| 91 | */ | ||
| 92 | static inline bool completion_done(struct completion *x) | ||
| 93 | { | ||
| 94 | int ret = 1; | ||
| 95 | |||
| 96 | spin_lock_irq(&x->wait.lock); | ||
| 97 | if (!x->done) | ||
| 98 | ret = 0; | ||
| 99 | spin_unlock_irq(&x->wait.lock); | ||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | |||
| 103 | #endif | 61 | #endif |
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index f368d041e02d..bb384068272e 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h | |||
| @@ -98,6 +98,27 @@ static inline void tracer_disable(void) | |||
| 98 | #endif | 98 | #endif |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /* Ftrace disable/restore without lock. Some synchronization mechanism | ||
| 102 | * must be used to prevent ftrace_enabled to be changed between | ||
| 103 | * disable/restore. */ | ||
| 104 | static inline int __ftrace_enabled_save(void) | ||
| 105 | { | ||
| 106 | #ifdef CONFIG_FTRACE | ||
| 107 | int saved_ftrace_enabled = ftrace_enabled; | ||
| 108 | ftrace_enabled = 0; | ||
| 109 | return saved_ftrace_enabled; | ||
| 110 | #else | ||
| 111 | return 0; | ||
| 112 | #endif | ||
| 113 | } | ||
| 114 | |||
| 115 | static inline void __ftrace_enabled_restore(int enabled) | ||
| 116 | { | ||
| 117 | #ifdef CONFIG_FTRACE | ||
| 118 | ftrace_enabled = enabled; | ||
| 119 | #endif | ||
| 120 | } | ||
| 121 | |||
| 101 | #ifdef CONFIG_FRAME_POINTER | 122 | #ifdef CONFIG_FRAME_POINTER |
| 102 | /* TODO: need to fix this for ARM */ | 123 | /* TODO: need to fix this for ARM */ |
| 103 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) | 124 | # define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0)) |
diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 32110cede64f..17f76fc05173 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h | |||
| @@ -25,8 +25,8 @@ | |||
| 25 | #error KEXEC_CONTROL_MEMORY_LIMIT not defined | 25 | #error KEXEC_CONTROL_MEMORY_LIMIT not defined |
| 26 | #endif | 26 | #endif |
| 27 | 27 | ||
| 28 | #ifndef KEXEC_CONTROL_CODE_SIZE | 28 | #ifndef KEXEC_CONTROL_PAGE_SIZE |
| 29 | #error KEXEC_CONTROL_CODE_SIZE not defined | 29 | #error KEXEC_CONTROL_PAGE_SIZE not defined |
| 30 | #endif | 30 | #endif |
| 31 | 31 | ||
| 32 | #ifndef KEXEC_ARCH | 32 | #ifndef KEXEC_ARCH |
diff --git a/include/linux/reboot.h b/include/linux/reboot.h index b93b541cf111..988e55fe649b 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h | |||
| @@ -59,6 +59,7 @@ extern void machine_crash_shutdown(struct pt_regs *); | |||
| 59 | * Architecture independent implemenations of sys_reboot commands. | 59 | * Architecture independent implemenations of sys_reboot commands. |
| 60 | */ | 60 | */ |
| 61 | 61 | ||
| 62 | extern void kernel_restart_prepare(char *cmd); | ||
| 62 | extern void kernel_restart(char *cmd); | 63 | extern void kernel_restart(char *cmd); |
| 63 | extern void kernel_halt(void); | 64 | extern void kernel_halt(void); |
| 64 | extern void kernel_power_off(void); | 65 | extern void kernel_power_off(void); |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index c63435095970..2ce8207686e2 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -217,11 +217,11 @@ struct platform_hibernation_ops { | |||
| 217 | #ifdef CONFIG_HIBERNATION | 217 | #ifdef CONFIG_HIBERNATION |
| 218 | /* kernel/power/snapshot.c */ | 218 | /* kernel/power/snapshot.c */ |
| 219 | extern void __register_nosave_region(unsigned long b, unsigned long e, int km); | 219 | extern void __register_nosave_region(unsigned long b, unsigned long e, int km); |
| 220 | static inline void register_nosave_region(unsigned long b, unsigned long e) | 220 | static inline void __init register_nosave_region(unsigned long b, unsigned long e) |
| 221 | { | 221 | { |
| 222 | __register_nosave_region(b, e, 0); | 222 | __register_nosave_region(b, e, 0); |
| 223 | } | 223 | } |
| 224 | static inline void register_nosave_region_late(unsigned long b, unsigned long e) | 224 | static inline void __init register_nosave_region_late(unsigned long b, unsigned long e) |
| 225 | { | 225 | { |
| 226 | __register_nosave_region(b, e, 1); | 226 | __register_nosave_region(b, e, 1); |
| 227 | } | 227 | } |
diff --git a/include/linux/tty.h b/include/linux/tty.h index e3579cb086e0..0cbec74ec086 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -331,6 +331,8 @@ extern int tty_write_room(struct tty_struct *tty); | |||
| 331 | extern void tty_driver_flush_buffer(struct tty_struct *tty); | 331 | extern void tty_driver_flush_buffer(struct tty_struct *tty); |
| 332 | extern void tty_throttle(struct tty_struct *tty); | 332 | extern void tty_throttle(struct tty_struct *tty); |
| 333 | extern void tty_unthrottle(struct tty_struct *tty); | 333 | extern void tty_unthrottle(struct tty_struct *tty); |
| 334 | extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 335 | struct winsize *ws); | ||
| 334 | 336 | ||
| 335 | extern int is_current_pgrp_orphaned(void); | 337 | extern int is_current_pgrp_orphaned(void); |
| 336 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); | 338 | extern struct pid *tty_get_pgrp(struct tty_struct *tty); |
diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index e1065ac0d922..16d27944c321 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h | |||
| @@ -168,6 +168,18 @@ | |||
| 168 | * | 168 | * |
| 169 | * Optional: If not provided then the write method is called under | 169 | * Optional: If not provided then the write method is called under |
| 170 | * the atomic write lock to keep it serialized with the ldisc. | 170 | * the atomic write lock to keep it serialized with the ldisc. |
| 171 | * | ||
| 172 | * int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 173 | * unsigned int rows, unsigned int cols); | ||
| 174 | * | ||
| 175 | * Called when a termios request is issued which changes the | ||
| 176 | * requested terminal geometry. | ||
| 177 | * | ||
| 178 | * Optional: the default action is to update the termios structure | ||
| 179 | * without error. This is usually the correct behaviour. Drivers should | ||
| 180 | * not force errors here if they are not resizable objects (eg a serial | ||
| 181 | * line). See tty_do_resize() if you need to wrap the standard method | ||
| 182 | * in your own logic - the usual case. | ||
| 171 | */ | 183 | */ |
| 172 | 184 | ||
| 173 | #include <linux/fs.h> | 185 | #include <linux/fs.h> |
| @@ -206,6 +218,8 @@ struct tty_operations { | |||
| 206 | int (*tiocmget)(struct tty_struct *tty, struct file *file); | 218 | int (*tiocmget)(struct tty_struct *tty, struct file *file); |
| 207 | int (*tiocmset)(struct tty_struct *tty, struct file *file, | 219 | int (*tiocmset)(struct tty_struct *tty, struct file *file, |
| 208 | unsigned int set, unsigned int clear); | 220 | unsigned int set, unsigned int clear); |
| 221 | int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, | ||
| 222 | struct winsize *ws); | ||
| 209 | #ifdef CONFIG_CONSOLE_POLL | 223 | #ifdef CONFIG_CONSOLE_POLL |
| 210 | int (*poll_init)(struct tty_driver *driver, int line, char *options); | 224 | int (*poll_init)(struct tty_driver *driver, int line, char *options); |
| 211 | int (*poll_get_char)(struct tty_driver *driver, int line); | 225 | int (*poll_get_char)(struct tty_driver *driver, int line); |
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 1c78d56c57e5..1cbd0a7db4e6 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
| @@ -35,7 +35,6 @@ extern int fg_console, last_console, want_console; | |||
| 35 | int vc_allocate(unsigned int console); | 35 | int vc_allocate(unsigned int console); |
| 36 | int vc_cons_allocated(unsigned int console); | 36 | int vc_cons_allocated(unsigned int console); |
| 37 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); | 37 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); |
| 38 | int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); | ||
| 39 | void vc_deallocate(unsigned int console); | 38 | void vc_deallocate(unsigned int console); |
| 40 | void reset_palette(struct vc_data *vc); | 39 | void reset_palette(struct vc_data *vc); |
| 41 | void do_blank_screen(int entering_gfx); | 40 | void do_blank_screen(int entering_gfx); |
diff --git a/kernel/kexec.c b/kernel/kexec.c index c8a4370e2a34..59f3f0df35d4 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
| 14 | #include <linux/kexec.h> | 14 | #include <linux/kexec.h> |
| 15 | #include <linux/spinlock.h> | 15 | #include <linux/mutex.h> |
| 16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
| 17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
| 18 | #include <linux/syscalls.h> | 18 | #include <linux/syscalls.h> |
| @@ -77,7 +77,7 @@ int kexec_should_crash(struct task_struct *p) | |||
| 77 | * | 77 | * |
| 78 | * The code for the transition from the current kernel to the | 78 | * The code for the transition from the current kernel to the |
| 79 | * the new kernel is placed in the control_code_buffer, whose size | 79 | * the new kernel is placed in the control_code_buffer, whose size |
| 80 | * is given by KEXEC_CONTROL_CODE_SIZE. In the best case only a single | 80 | * is given by KEXEC_CONTROL_PAGE_SIZE. In the best case only a single |
| 81 | * page of memory is necessary, but some architectures require more. | 81 | * page of memory is necessary, but some architectures require more. |
| 82 | * Because this memory must be identity mapped in the transition from | 82 | * Because this memory must be identity mapped in the transition from |
| 83 | * virtual to physical addresses it must live in the range | 83 | * virtual to physical addresses it must live in the range |
| @@ -242,7 +242,7 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | |||
| 242 | */ | 242 | */ |
| 243 | result = -ENOMEM; | 243 | result = -ENOMEM; |
| 244 | image->control_code_page = kimage_alloc_control_pages(image, | 244 | image->control_code_page = kimage_alloc_control_pages(image, |
| 245 | get_order(KEXEC_CONTROL_CODE_SIZE)); | 245 | get_order(KEXEC_CONTROL_PAGE_SIZE)); |
| 246 | if (!image->control_code_page) { | 246 | if (!image->control_code_page) { |
| 247 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); | 247 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); |
| 248 | goto out; | 248 | goto out; |
| @@ -317,7 +317,7 @@ static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, | |||
| 317 | */ | 317 | */ |
| 318 | result = -ENOMEM; | 318 | result = -ENOMEM; |
| 319 | image->control_code_page = kimage_alloc_control_pages(image, | 319 | image->control_code_page = kimage_alloc_control_pages(image, |
| 320 | get_order(KEXEC_CONTROL_CODE_SIZE)); | 320 | get_order(KEXEC_CONTROL_PAGE_SIZE)); |
| 321 | if (!image->control_code_page) { | 321 | if (!image->control_code_page) { |
| 322 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); | 322 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); |
| 323 | goto out; | 323 | goto out; |
| @@ -924,19 +924,14 @@ static int kimage_load_segment(struct kimage *image, | |||
| 924 | */ | 924 | */ |
| 925 | struct kimage *kexec_image; | 925 | struct kimage *kexec_image; |
| 926 | struct kimage *kexec_crash_image; | 926 | struct kimage *kexec_crash_image; |
| 927 | /* | 927 | |
| 928 | * A home grown binary mutex. | 928 | static DEFINE_MUTEX(kexec_mutex); |
| 929 | * Nothing can wait so this mutex is safe to use | ||
| 930 | * in interrupt context :) | ||
| 931 | */ | ||
| 932 | static int kexec_lock; | ||
| 933 | 929 | ||
| 934 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, | 930 | asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, |
| 935 | struct kexec_segment __user *segments, | 931 | struct kexec_segment __user *segments, |
| 936 | unsigned long flags) | 932 | unsigned long flags) |
| 937 | { | 933 | { |
| 938 | struct kimage **dest_image, *image; | 934 | struct kimage **dest_image, *image; |
| 939 | int locked; | ||
| 940 | int result; | 935 | int result; |
| 941 | 936 | ||
| 942 | /* We only trust the superuser with rebooting the system. */ | 937 | /* We only trust the superuser with rebooting the system. */ |
| @@ -972,8 +967,7 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, | |||
| 972 | * | 967 | * |
| 973 | * KISS: always take the mutex. | 968 | * KISS: always take the mutex. |
| 974 | */ | 969 | */ |
| 975 | locked = xchg(&kexec_lock, 1); | 970 | if (!mutex_trylock(&kexec_mutex)) |
| 976 | if (locked) | ||
| 977 | return -EBUSY; | 971 | return -EBUSY; |
| 978 | 972 | ||
| 979 | dest_image = &kexec_image; | 973 | dest_image = &kexec_image; |
| @@ -1015,8 +1009,7 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, | |||
| 1015 | image = xchg(dest_image, image); | 1009 | image = xchg(dest_image, image); |
| 1016 | 1010 | ||
| 1017 | out: | 1011 | out: |
| 1018 | locked = xchg(&kexec_lock, 0); /* Release the mutex */ | 1012 | mutex_unlock(&kexec_mutex); |
| 1019 | BUG_ON(!locked); | ||
| 1020 | kimage_free(image); | 1013 | kimage_free(image); |
| 1021 | 1014 | ||
| 1022 | return result; | 1015 | return result; |
| @@ -1063,10 +1056,7 @@ asmlinkage long compat_sys_kexec_load(unsigned long entry, | |||
| 1063 | 1056 | ||
| 1064 | void crash_kexec(struct pt_regs *regs) | 1057 | void crash_kexec(struct pt_regs *regs) |
| 1065 | { | 1058 | { |
| 1066 | int locked; | 1059 | /* Take the kexec_mutex here to prevent sys_kexec_load |
| 1067 | |||
| 1068 | |||
| 1069 | /* Take the kexec_lock here to prevent sys_kexec_load | ||
| 1070 | * running on one cpu from replacing the crash kernel | 1060 | * running on one cpu from replacing the crash kernel |
| 1071 | * we are using after a panic on a different cpu. | 1061 | * we are using after a panic on a different cpu. |
| 1072 | * | 1062 | * |
| @@ -1074,8 +1064,7 @@ void crash_kexec(struct pt_regs *regs) | |||
| 1074 | * of memory the xchg(&kexec_crash_image) would be | 1064 | * of memory the xchg(&kexec_crash_image) would be |
| 1075 | * sufficient. But since I reuse the memory... | 1065 | * sufficient. But since I reuse the memory... |
| 1076 | */ | 1066 | */ |
| 1077 | locked = xchg(&kexec_lock, 1); | 1067 | if (mutex_trylock(&kexec_mutex)) { |
| 1078 | if (!locked) { | ||
| 1079 | if (kexec_crash_image) { | 1068 | if (kexec_crash_image) { |
| 1080 | struct pt_regs fixed_regs; | 1069 | struct pt_regs fixed_regs; |
| 1081 | crash_setup_regs(&fixed_regs, regs); | 1070 | crash_setup_regs(&fixed_regs, regs); |
| @@ -1083,8 +1072,7 @@ void crash_kexec(struct pt_regs *regs) | |||
| 1083 | machine_crash_shutdown(&fixed_regs); | 1072 | machine_crash_shutdown(&fixed_regs); |
| 1084 | machine_kexec(kexec_crash_image); | 1073 | machine_kexec(kexec_crash_image); |
| 1085 | } | 1074 | } |
| 1086 | locked = xchg(&kexec_lock, 0); | 1075 | mutex_unlock(&kexec_mutex); |
| 1087 | BUG_ON(!locked); | ||
| 1088 | } | 1076 | } |
| 1089 | } | 1077 | } |
| 1090 | 1078 | ||
| @@ -1426,25 +1414,23 @@ static int __init crash_save_vmcoreinfo_init(void) | |||
| 1426 | 1414 | ||
| 1427 | module_init(crash_save_vmcoreinfo_init) | 1415 | module_init(crash_save_vmcoreinfo_init) |
| 1428 | 1416 | ||
| 1429 | /** | 1417 | /* |
| 1430 | * kernel_kexec - reboot the system | 1418 | * Move into place and start executing a preloaded standalone |
| 1431 | * | 1419 | * executable. If nothing was preloaded return an error. |
| 1432 | * Move into place and start executing a preloaded standalone | ||
| 1433 | * executable. If nothing was preloaded return an error. | ||
| 1434 | */ | 1420 | */ |
| 1435 | int kernel_kexec(void) | 1421 | int kernel_kexec(void) |
| 1436 | { | 1422 | { |
| 1437 | int error = 0; | 1423 | int error = 0; |
| 1438 | 1424 | ||
| 1439 | if (xchg(&kexec_lock, 1)) | 1425 | if (!mutex_trylock(&kexec_mutex)) |
| 1440 | return -EBUSY; | 1426 | return -EBUSY; |
| 1441 | if (!kexec_image) { | 1427 | if (!kexec_image) { |
| 1442 | error = -EINVAL; | 1428 | error = -EINVAL; |
| 1443 | goto Unlock; | 1429 | goto Unlock; |
| 1444 | } | 1430 | } |
| 1445 | 1431 | ||
| 1446 | if (kexec_image->preserve_context) { | ||
| 1447 | #ifdef CONFIG_KEXEC_JUMP | 1432 | #ifdef CONFIG_KEXEC_JUMP |
| 1433 | if (kexec_image->preserve_context) { | ||
| 1448 | mutex_lock(&pm_mutex); | 1434 | mutex_lock(&pm_mutex); |
| 1449 | pm_prepare_console(); | 1435 | pm_prepare_console(); |
| 1450 | error = freeze_processes(); | 1436 | error = freeze_processes(); |
| @@ -1459,6 +1445,7 @@ int kernel_kexec(void) | |||
| 1459 | error = disable_nonboot_cpus(); | 1445 | error = disable_nonboot_cpus(); |
| 1460 | if (error) | 1446 | if (error) |
| 1461 | goto Resume_devices; | 1447 | goto Resume_devices; |
| 1448 | device_pm_lock(); | ||
| 1462 | local_irq_disable(); | 1449 | local_irq_disable(); |
| 1463 | /* At this point, device_suspend() has been called, | 1450 | /* At this point, device_suspend() has been called, |
| 1464 | * but *not* device_power_down(). We *must* | 1451 | * but *not* device_power_down(). We *must* |
| @@ -1470,26 +1457,22 @@ int kernel_kexec(void) | |||
| 1470 | error = device_power_down(PMSG_FREEZE); | 1457 | error = device_power_down(PMSG_FREEZE); |
| 1471 | if (error) | 1458 | if (error) |
| 1472 | goto Enable_irqs; | 1459 | goto Enable_irqs; |
| 1473 | save_processor_state(); | 1460 | } else |
| 1474 | #endif | 1461 | #endif |
| 1475 | } else { | 1462 | { |
| 1476 | blocking_notifier_call_chain(&reboot_notifier_list, | 1463 | kernel_restart_prepare(NULL); |
| 1477 | SYS_RESTART, NULL); | ||
| 1478 | system_state = SYSTEM_RESTART; | ||
| 1479 | device_shutdown(); | ||
| 1480 | sysdev_shutdown(); | ||
| 1481 | printk(KERN_EMERG "Starting new kernel\n"); | 1464 | printk(KERN_EMERG "Starting new kernel\n"); |
| 1482 | machine_shutdown(); | 1465 | machine_shutdown(); |
| 1483 | } | 1466 | } |
| 1484 | 1467 | ||
| 1485 | machine_kexec(kexec_image); | 1468 | machine_kexec(kexec_image); |
| 1486 | 1469 | ||
| 1487 | if (kexec_image->preserve_context) { | ||
| 1488 | #ifdef CONFIG_KEXEC_JUMP | 1470 | #ifdef CONFIG_KEXEC_JUMP |
| 1489 | restore_processor_state(); | 1471 | if (kexec_image->preserve_context) { |
| 1490 | device_power_up(PMSG_RESTORE); | 1472 | device_power_up(PMSG_RESTORE); |
| 1491 | Enable_irqs: | 1473 | Enable_irqs: |
| 1492 | local_irq_enable(); | 1474 | local_irq_enable(); |
| 1475 | device_pm_unlock(); | ||
| 1493 | enable_nonboot_cpus(); | 1476 | enable_nonboot_cpus(); |
| 1494 | Resume_devices: | 1477 | Resume_devices: |
| 1495 | device_resume(PMSG_RESTORE); | 1478 | device_resume(PMSG_RESTORE); |
| @@ -1499,11 +1482,10 @@ int kernel_kexec(void) | |||
| 1499 | Restore_console: | 1482 | Restore_console: |
| 1500 | pm_restore_console(); | 1483 | pm_restore_console(); |
| 1501 | mutex_unlock(&pm_mutex); | 1484 | mutex_unlock(&pm_mutex); |
| 1502 | #endif | ||
| 1503 | } | 1485 | } |
| 1486 | #endif | ||
| 1504 | 1487 | ||
| 1505 | Unlock: | 1488 | Unlock: |
| 1506 | xchg(&kexec_lock, 0); | 1489 | mutex_unlock(&kexec_mutex); |
| 1507 | |||
| 1508 | return error; | 1490 | return error; |
| 1509 | } | 1491 | } |
diff --git a/kernel/sched.c b/kernel/sched.c index d601fb0406ca..95e6ad3c231d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -4669,6 +4669,52 @@ int __sched wait_for_completion_killable(struct completion *x) | |||
| 4669 | } | 4669 | } |
| 4670 | EXPORT_SYMBOL(wait_for_completion_killable); | 4670 | EXPORT_SYMBOL(wait_for_completion_killable); |
| 4671 | 4671 | ||
| 4672 | /** | ||
| 4673 | * try_wait_for_completion - try to decrement a completion without blocking | ||
| 4674 | * @x: completion structure | ||
| 4675 | * | ||
| 4676 | * Returns: 0 if a decrement cannot be done without blocking | ||
| 4677 | * 1 if a decrement succeeded. | ||
| 4678 | * | ||
| 4679 | * If a completion is being used as a counting completion, | ||
| 4680 | * attempt to decrement the counter without blocking. This | ||
| 4681 | * enables us to avoid waiting if the resource the completion | ||
| 4682 | * is protecting is not available. | ||
| 4683 | */ | ||
| 4684 | bool try_wait_for_completion(struct completion *x) | ||
| 4685 | { | ||
| 4686 | int ret = 1; | ||
| 4687 | |||
| 4688 | spin_lock_irq(&x->wait.lock); | ||
| 4689 | if (!x->done) | ||
| 4690 | ret = 0; | ||
| 4691 | else | ||
| 4692 | x->done--; | ||
| 4693 | spin_unlock_irq(&x->wait.lock); | ||
| 4694 | return ret; | ||
| 4695 | } | ||
| 4696 | EXPORT_SYMBOL(try_wait_for_completion); | ||
| 4697 | |||
| 4698 | /** | ||
| 4699 | * completion_done - Test to see if a completion has any waiters | ||
| 4700 | * @x: completion structure | ||
| 4701 | * | ||
| 4702 | * Returns: 0 if there are waiters (wait_for_completion() in progress) | ||
| 4703 | * 1 if there are no waiters. | ||
| 4704 | * | ||
| 4705 | */ | ||
| 4706 | bool completion_done(struct completion *x) | ||
| 4707 | { | ||
| 4708 | int ret = 1; | ||
| 4709 | |||
| 4710 | spin_lock_irq(&x->wait.lock); | ||
| 4711 | if (!x->done) | ||
| 4712 | ret = 0; | ||
| 4713 | spin_unlock_irq(&x->wait.lock); | ||
| 4714 | return ret; | ||
| 4715 | } | ||
| 4716 | EXPORT_SYMBOL(completion_done); | ||
| 4717 | |||
| 4672 | static long __sched | 4718 | static long __sched |
| 4673 | sleep_on_common(wait_queue_head_t *q, int state, long timeout) | 4719 | sleep_on_common(wait_queue_head_t *q, int state, long timeout) |
| 4674 | { | 4720 | { |
diff --git a/kernel/sys.c b/kernel/sys.c index c01858090a98..3dacb00a7f76 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -274,7 +274,7 @@ void emergency_restart(void) | |||
| 274 | } | 274 | } |
| 275 | EXPORT_SYMBOL_GPL(emergency_restart); | 275 | EXPORT_SYMBOL_GPL(emergency_restart); |
| 276 | 276 | ||
| 277 | static void kernel_restart_prepare(char *cmd) | 277 | void kernel_restart_prepare(char *cmd) |
| 278 | { | 278 | { |
| 279 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); | 279 | blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd); |
| 280 | system_state = SYSTEM_RESTART; | 280 | system_state = SYSTEM_RESTART; |
diff --git a/mm/bootmem.c b/mm/bootmem.c index 4af15d0340ad..e023c68b0255 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c | |||
| @@ -473,7 +473,7 @@ find_block: | |||
| 473 | goto find_block; | 473 | goto find_block; |
| 474 | } | 474 | } |
| 475 | 475 | ||
| 476 | if (bdata->last_end_off && | 476 | if (bdata->last_end_off & (PAGE_SIZE - 1) && |
| 477 | PFN_DOWN(bdata->last_end_off) + 1 == sidx) | 477 | PFN_DOWN(bdata->last_end_off) + 1 == sidx) |
| 478 | start_off = ALIGN(bdata->last_end_off, align); | 478 | start_off = ALIGN(bdata->last_end_off, align); |
| 479 | else | 479 | else |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index f7d95b224a98..31f52d3fc21f 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
| @@ -845,7 +845,7 @@ config SND_VIRTUOSO | |||
| 845 | select SND_OXYGEN_LIB | 845 | select SND_OXYGEN_LIB |
| 846 | help | 846 | help |
| 847 | Say Y here to include support for sound cards based on the | 847 | Say Y here to include support for sound cards based on the |
| 848 | Asus AV100/AV200 chips, i.e., Xonar D2, DX and D2X. | 848 | Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. |
| 849 | 849 | ||
| 850 | To compile this driver as a module, choose M here: the module | 850 | To compile this driver as a module, choose M here: the module |
| 851 | will be called snd-virtuoso. | 851 | will be called snd-virtuoso. |
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 9a2c16bf94e0..01d7b75f9182 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
| @@ -36,15 +36,15 @@ | |||
| 36 | */ | 36 | */ |
| 37 | 37 | ||
| 38 | /* | 38 | /* |
| 39 | * Xonar DX | 39 | * Xonar D1/DX |
| 40 | * -------- | 40 | * ----------- |
| 41 | * | 41 | * |
| 42 | * CMI8788: | 42 | * CMI8788: |
| 43 | * | 43 | * |
| 44 | * I²C <-> CS4398 (front) | 44 | * I²C <-> CS4398 (front) |
| 45 | * <-> CS4362A (surround, center/LFE, back) | 45 | * <-> CS4362A (surround, center/LFE, back) |
| 46 | * | 46 | * |
| 47 | * GPI 0 <- external power present | 47 | * GPI 0 <- external power present (DX only) |
| 48 | * | 48 | * |
| 49 | * GPIO 0 -> enable output to speakers | 49 | * GPIO 0 -> enable output to speakers |
| 50 | * GPIO 1 -> enable front panel I/O | 50 | * GPIO 1 -> enable front panel I/O |
| @@ -96,6 +96,7 @@ MODULE_PARM_DESC(enable, "enable card"); | |||
| 96 | enum { | 96 | enum { |
| 97 | MODEL_D2, | 97 | MODEL_D2, |
| 98 | MODEL_D2X, | 98 | MODEL_D2X, |
| 99 | MODEL_D1, | ||
| 99 | MODEL_DX, | 100 | MODEL_DX, |
| 100 | }; | 101 | }; |
| 101 | 102 | ||
| @@ -103,6 +104,7 @@ static struct pci_device_id xonar_ids[] __devinitdata = { | |||
| 103 | { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 }, | 104 | { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 }, |
| 104 | { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX }, | 105 | { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX }, |
| 105 | { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, | 106 | { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, |
| 107 | { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, | ||
| 106 | { } | 108 | { } |
| 107 | }; | 109 | }; |
| 108 | MODULE_DEVICE_TABLE(pci, xonar_ids); | 110 | MODULE_DEVICE_TABLE(pci, xonar_ids); |
| @@ -313,15 +315,12 @@ static void cs43xx_init(struct oxygen *chip) | |||
| 313 | cs4362a_write(chip, 0x01, CS4362A_CPEN); | 315 | cs4362a_write(chip, 0x01, CS4362A_CPEN); |
| 314 | } | 316 | } |
| 315 | 317 | ||
| 316 | static void xonar_dx_init(struct oxygen *chip) | 318 | static void xonar_d1_init(struct oxygen *chip) |
| 317 | { | 319 | { |
| 318 | struct xonar_data *data = chip->model_data; | 320 | struct xonar_data *data = chip->model_data; |
| 319 | 321 | ||
| 320 | data->anti_pop_delay = 800; | 322 | data->anti_pop_delay = 800; |
| 321 | data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; | 323 | data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; |
| 322 | data->ext_power_reg = OXYGEN_GPI_DATA; | ||
| 323 | data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; | ||
| 324 | data->ext_power_bit = GPI_DX_EXT_POWER; | ||
| 325 | data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; | 324 | data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; |
| 326 | data->cs4362a_fm = CS4362A_FM_SINGLE | | 325 | data->cs4362a_fm = CS4362A_FM_SINGLE | |
| 327 | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; | 326 | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; |
| @@ -345,6 +344,16 @@ static void xonar_dx_init(struct oxygen *chip) | |||
| 345 | snd_component_add(chip->card, "CS5361"); | 344 | snd_component_add(chip->card, "CS5361"); |
| 346 | } | 345 | } |
| 347 | 346 | ||
| 347 | static void xonar_dx_init(struct oxygen *chip) | ||
| 348 | { | ||
| 349 | struct xonar_data *data = chip->model_data; | ||
| 350 | |||
| 351 | data->ext_power_reg = OXYGEN_GPI_DATA; | ||
| 352 | data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; | ||
| 353 | data->ext_power_bit = GPI_DX_EXT_POWER; | ||
| 354 | xonar_d1_init(chip); | ||
| 355 | } | ||
| 356 | |||
| 348 | static void xonar_cleanup(struct oxygen *chip) | 357 | static void xonar_cleanup(struct oxygen *chip) |
| 349 | { | 358 | { |
| 350 | struct xonar_data *data = chip->model_data; | 359 | struct xonar_data *data = chip->model_data; |
| @@ -352,7 +361,7 @@ static void xonar_cleanup(struct oxygen *chip) | |||
| 352 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); | 361 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); |
| 353 | } | 362 | } |
| 354 | 363 | ||
| 355 | static void xonar_dx_cleanup(struct oxygen *chip) | 364 | static void xonar_d1_cleanup(struct oxygen *chip) |
| 356 | { | 365 | { |
| 357 | xonar_cleanup(chip); | 366 | xonar_cleanup(chip); |
| 358 | cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); | 367 | cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); |
| @@ -365,7 +374,7 @@ static void xonar_d2_resume(struct oxygen *chip) | |||
| 365 | xonar_enable_output(chip); | 374 | xonar_enable_output(chip); |
| 366 | } | 375 | } |
| 367 | 376 | ||
| 368 | static void xonar_dx_resume(struct oxygen *chip) | 377 | static void xonar_d1_resume(struct oxygen *chip) |
| 369 | { | 378 | { |
| 370 | cs43xx_init(chip); | 379 | cs43xx_init(chip); |
| 371 | xonar_enable_output(chip); | 380 | xonar_enable_output(chip); |
| @@ -513,7 +522,7 @@ static const struct snd_kcontrol_new front_panel_switch = { | |||
| 513 | .put = front_panel_put, | 522 | .put = front_panel_put, |
| 514 | }; | 523 | }; |
| 515 | 524 | ||
| 516 | static void xonar_dx_ac97_switch(struct oxygen *chip, | 525 | static void xonar_d1_ac97_switch(struct oxygen *chip, |
| 517 | unsigned int reg, unsigned int mute) | 526 | unsigned int reg, unsigned int mute) |
| 518 | { | 527 | { |
| 519 | if (reg == AC97_LINE) { | 528 | if (reg == AC97_LINE) { |
| @@ -536,7 +545,7 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template) | |||
| 536 | return 0; | 545 | return 0; |
| 537 | } | 546 | } |
| 538 | 547 | ||
| 539 | static int xonar_dx_control_filter(struct snd_kcontrol_new *template) | 548 | static int xonar_d1_control_filter(struct snd_kcontrol_new *template) |
| 540 | { | 549 | { |
| 541 | if (!strncmp(template->name, "CD Capture ", 11)) | 550 | if (!strncmp(template->name, "CD Capture ", 11)) |
| 542 | return 1; /* no CD input */ | 551 | return 1; /* no CD input */ |
| @@ -548,7 +557,7 @@ static int xonar_mixer_init(struct oxygen *chip) | |||
| 548 | return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); | 557 | return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); |
| 549 | } | 558 | } |
| 550 | 559 | ||
| 551 | static int xonar_dx_mixer_init(struct oxygen *chip) | 560 | static int xonar_d1_mixer_init(struct oxygen *chip) |
| 552 | { | 561 | { |
| 553 | return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); | 562 | return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); |
| 554 | } | 563 | } |
| @@ -615,23 +624,51 @@ static const struct oxygen_model xonar_models[] = { | |||
| 615 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 624 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 616 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 625 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 617 | }, | 626 | }, |
| 627 | [MODEL_D1] = { | ||
| 628 | .shortname = "Xonar D1", | ||
| 629 | .longname = "Asus Virtuoso 100", | ||
| 630 | .chip = "AV200", | ||
| 631 | .owner = THIS_MODULE, | ||
| 632 | .init = xonar_d1_init, | ||
| 633 | .control_filter = xonar_d1_control_filter, | ||
| 634 | .mixer_init = xonar_d1_mixer_init, | ||
| 635 | .cleanup = xonar_d1_cleanup, | ||
| 636 | .suspend = xonar_d1_cleanup, | ||
| 637 | .resume = xonar_d1_resume, | ||
| 638 | .set_dac_params = set_cs43xx_params, | ||
| 639 | .set_adc_params = set_cs53x1_params, | ||
| 640 | .update_dac_volume = update_cs43xx_volume, | ||
| 641 | .update_dac_mute = update_cs43xx_mute, | ||
| 642 | .ac97_switch = xonar_d1_ac97_switch, | ||
| 643 | .dac_tlv = cs4362a_db_scale, | ||
| 644 | .model_data_size = sizeof(struct xonar_data), | ||
| 645 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | ||
| 646 | PLAYBACK_1_TO_SPDIF | | ||
| 647 | CAPTURE_0_FROM_I2S_2, | ||
| 648 | .dac_channels = 8, | ||
| 649 | .dac_volume_min = 0, | ||
| 650 | .dac_volume_max = 127, | ||
| 651 | .function_flags = OXYGEN_FUNCTION_2WIRE, | ||
| 652 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | ||
| 653 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | ||
| 654 | }, | ||
| 618 | [MODEL_DX] = { | 655 | [MODEL_DX] = { |
| 619 | .shortname = "Xonar DX", | 656 | .shortname = "Xonar DX", |
| 620 | .longname = "Asus Virtuoso 100", | 657 | .longname = "Asus Virtuoso 100", |
| 621 | .chip = "AV200", | 658 | .chip = "AV200", |
| 622 | .owner = THIS_MODULE, | 659 | .owner = THIS_MODULE, |
| 623 | .init = xonar_dx_init, | 660 | .init = xonar_dx_init, |
| 624 | .control_filter = xonar_dx_control_filter, | 661 | .control_filter = xonar_d1_control_filter, |
| 625 | .mixer_init = xonar_dx_mixer_init, | 662 | .mixer_init = xonar_d1_mixer_init, |
| 626 | .cleanup = xonar_dx_cleanup, | 663 | .cleanup = xonar_d1_cleanup, |
| 627 | .suspend = xonar_dx_cleanup, | 664 | .suspend = xonar_d1_cleanup, |
| 628 | .resume = xonar_dx_resume, | 665 | .resume = xonar_d1_resume, |
| 629 | .set_dac_params = set_cs43xx_params, | 666 | .set_dac_params = set_cs43xx_params, |
| 630 | .set_adc_params = set_cs53x1_params, | 667 | .set_adc_params = set_cs53x1_params, |
| 631 | .update_dac_volume = update_cs43xx_volume, | 668 | .update_dac_volume = update_cs43xx_volume, |
| 632 | .update_dac_mute = update_cs43xx_mute, | 669 | .update_dac_mute = update_cs43xx_mute, |
| 633 | .gpio_changed = xonar_gpio_changed, | 670 | .gpio_changed = xonar_gpio_changed, |
| 634 | .ac97_switch = xonar_dx_ac97_switch, | 671 | .ac97_switch = xonar_d1_ac97_switch, |
| 635 | .dac_tlv = cs4362a_db_scale, | 672 | .dac_tlv = cs4362a_db_scale, |
| 636 | .model_data_size = sizeof(struct xonar_data), | 673 | .model_data_size = sizeof(struct xonar_data), |
| 637 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | 674 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 3ecce5168e94..e44153fa38de 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
| @@ -82,7 +82,7 @@ static const u16 wm8990_reg[] = { | |||
| 82 | 0x0003, /* R35 - ClassD1 */ | 82 | 0x0003, /* R35 - ClassD1 */ |
| 83 | 0x0000, /* R36 */ | 83 | 0x0000, /* R36 */ |
| 84 | 0x0100, /* R37 - ClassD3 */ | 84 | 0x0100, /* R37 - ClassD3 */ |
| 85 | 0x0000, /* R38 */ | 85 | 0x0079, /* R38 - ClassD4 */ |
| 86 | 0x0000, /* R39 - Input Mixer1 */ | 86 | 0x0000, /* R39 - Input Mixer1 */ |
| 87 | 0x0000, /* R40 - Input Mixer2 */ | 87 | 0x0000, /* R40 - Input Mixer2 */ |
| 88 | 0x0000, /* R41 - Input Mixer3 */ | 88 | 0x0000, /* R41 - Input Mixer3 */ |
| @@ -311,11 +311,15 @@ SOC_SINGLE("Speaker Mode Switch", WM8990_CLASSD1, | |||
| 311 | WM8990_CDMODE_BIT, 1, 0), | 311 | WM8990_CDMODE_BIT, 1, 0), |
| 312 | 312 | ||
| 313 | SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME, | 313 | SOC_SINGLE("Speaker Output Attenuation Volume", WM8990_SPEAKER_VOLUME, |
| 314 | WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0), | 314 | WM8990_SPKATTN_SHIFT, WM8990_SPKATTN_MASK, 0), |
| 315 | SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3, | 315 | SOC_SINGLE("Speaker DC Boost Volume", WM8990_CLASSD3, |
| 316 | WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0), | 316 | WM8990_DCGAIN_SHIFT, WM8990_DCGAIN_MASK, 0), |
| 317 | SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3, | 317 | SOC_SINGLE("Speaker AC Boost Volume", WM8990_CLASSD3, |
| 318 | WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0), | 318 | WM8990_ACGAIN_SHIFT, WM8990_ACGAIN_MASK, 0), |
| 319 | SOC_SINGLE_TLV("Speaker Volume", WM8990_CLASSD4, | ||
| 320 | WM8990_SPKVOL_SHIFT, WM8990_SPKVOL_MASK, 0, out_pga_tlv), | ||
| 321 | SOC_SINGLE("Speaker ZC Switch", WM8990_CLASSD4, | ||
| 322 | WM8990_SPKZC_SHIFT, WM8990_SPKZC_MASK, 0), | ||
| 319 | 323 | ||
| 320 | SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume", | 324 | SOC_WM899X_OUTPGA_SINGLE_R_TLV("Left DAC Digital Volume", |
| 321 | WM8990_LEFT_DAC_DIGITAL_VOLUME, | 325 | WM8990_LEFT_DAC_DIGITAL_VOLUME, |
| @@ -920,7 +924,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 920 | {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"}, | 924 | {"SPKMIX", "SPKMIX Left Mixer PGA Switch", "LOPGA"}, |
| 921 | {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"}, | 925 | {"SPKMIX", "SPKMIX Right Mixer PGA Switch", "ROPGA"}, |
| 922 | {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"}, | 926 | {"SPKMIX", "SPKMIX Right DAC Switch", "Right DAC"}, |
| 923 | {"SPKMIX", "SPKMIX Left DAC Switch", "Right DAC"}, | 927 | {"SPKMIX", "SPKMIX Left DAC Switch", "Left DAC"}, |
| 924 | 928 | ||
| 925 | /* LONMIX */ | 929 | /* LONMIX */ |
| 926 | {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"}, | 930 | {"LONMIX", "LONMIX Left Mixer PGA Switch", "LOPGA"}, |
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h index 6bea57485283..0a08325d5443 100644 --- a/sound/soc/codecs/wm8990.h +++ b/sound/soc/codecs/wm8990.h | |||
| @@ -54,6 +54,7 @@ | |||
| 54 | #define WM8990_SPEAKER_VOLUME 0x22 | 54 | #define WM8990_SPEAKER_VOLUME 0x22 |
| 55 | #define WM8990_CLASSD1 0x23 | 55 | #define WM8990_CLASSD1 0x23 |
| 56 | #define WM8990_CLASSD3 0x25 | 56 | #define WM8990_CLASSD3 0x25 |
| 57 | #define WM8990_CLASSD4 0x26 | ||
| 57 | #define WM8990_INPUT_MIXER1 0x27 | 58 | #define WM8990_INPUT_MIXER1 0x27 |
| 58 | #define WM8990_INPUT_MIXER2 0x28 | 59 | #define WM8990_INPUT_MIXER2 0x28 |
| 59 | #define WM8990_INPUT_MIXER3 0x29 | 60 | #define WM8990_INPUT_MIXER3 0x29 |
| @@ -528,8 +529,8 @@ | |||
| 528 | /* | 529 | /* |
| 529 | * R34 (0x22) - Speaker Volume | 530 | * R34 (0x22) - Speaker Volume |
| 530 | */ | 531 | */ |
| 531 | #define WM8990_SPKVOL_MASK 0x0003 /* SPKVOL - [1:0] */ | 532 | #define WM8990_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */ |
| 532 | #define WM8990_SPKVOL_SHIFT 0 | 533 | #define WM8990_SPKATTN_SHIFT 0 |
| 533 | 534 | ||
| 534 | /* | 535 | /* |
| 535 | * R35 (0x23) - ClassD1 | 536 | * R35 (0x23) - ClassD1 |
| @@ -544,6 +545,15 @@ | |||
| 544 | #define WM8990_DCGAIN_SHIFT 3 | 545 | #define WM8990_DCGAIN_SHIFT 3 |
| 545 | #define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */ | 546 | #define WM8990_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */ |
| 546 | #define WM8990_ACGAIN_SHIFT 0 | 547 | #define WM8990_ACGAIN_SHIFT 0 |
| 548 | |||
| 549 | /* | ||
| 550 | * R38 (0x26) - ClassD4 | ||
| 551 | */ | ||
| 552 | #define WM8990_SPKZC_MASK 0x0001 /* SPKZC */ | ||
| 553 | #define WM8990_SPKZC_SHIFT 7 /* SPKZC */ | ||
| 554 | #define WM8990_SPKVOL_MASK 0x007F /* SPKVOL - [6:0] */ | ||
| 555 | #define WM8990_SPKVOL_SHIFT 0 /* SPKVOL - [6:0] */ | ||
| 556 | |||
| 547 | /* | 557 | /* |
| 548 | * R39 (0x27) - Input Mixer1 | 558 | * R39 (0x27) - Input Mixer1 |
| 549 | */ | 559 | */ |
