aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CREDITS12
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/kernel-api.tmpl2
-rw-r--r--Documentation/DocBook/mtdnand.tmpl6
-rw-r--r--Documentation/Intel-IOMMU.txt115
-rw-r--r--Documentation/SubmitChecklist2
-rw-r--r--Documentation/SubmittingDrivers3
-rw-r--r--Documentation/accounting/cgroupstats.txt27
-rw-r--r--Documentation/arm/Samsung-S3C24XX/DMA.txt18
-rw-r--r--Documentation/cachetlb.txt27
-rw-r--r--Documentation/cdrom/cdrom-standard.tex2
-rw-r--r--Documentation/cgroups.txt545
-rw-r--r--Documentation/cpu-hotplug.txt4
-rw-r--r--Documentation/cpusets.txt226
-rw-r--r--Documentation/device-mapper/dm-uevent.txt97
-rw-r--r--Documentation/devices.txt2
-rw-r--r--Documentation/driver-model/devres.txt4
-rw-r--r--Documentation/fb/deferred_io.txt4
-rw-r--r--Documentation/feature-removal-schedule.txt24
-rw-r--r--Documentation/filesystems/9p.txt2
-rw-r--r--Documentation/filesystems/Exporting115
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/ext3.txt14
-rw-r--r--Documentation/filesystems/files.txt6
-rw-r--r--Documentation/filesystems/proc.txt7
-rw-r--r--Documentation/filesystems/sysfs.txt2
-rw-r--r--Documentation/filesystems/vfs.txt2
-rw-r--r--Documentation/i2c/i2c-protocol2
-rw-r--r--Documentation/i386/boot.txt34
-rw-r--r--Documentation/ia64/err_inject.txt6
-rw-r--r--Documentation/input/atarikbd.txt8
-rw-r--r--Documentation/input/ff.txt2
-rw-r--r--Documentation/input/iforce-protocol.txt20
-rw-r--r--Documentation/input/input-programming.txt17
-rw-r--r--Documentation/isdn/CREDITS2
-rw-r--r--Documentation/isdn/README.concap2
-rw-r--r--Documentation/java.txt2
-rw-r--r--Documentation/kbuild/kconfig-language.txt14
-rw-r--r--Documentation/kbuild/makefiles.txt22
-rw-r--r--Documentation/kdump/kdump.txt26
-rw-r--r--Documentation/kernel-docs.txt4
-rw-r--r--Documentation/kernel-parameters.txt71
-rw-r--r--Documentation/m68k/kernel-options.txt5
-rw-r--r--Documentation/markers.txt81
-rw-r--r--Documentation/memory-hotplug.txt58
-rw-r--r--Documentation/mips/00-INDEX2
-rw-r--r--Documentation/mips/AU1xxx_IDE.README2
-rw-r--r--Documentation/mips/time.README173
-rw-r--r--Documentation/mutex-design.txt4
-rw-r--r--Documentation/networking/bcm43xx.txt2
-rw-r--r--Documentation/networking/ip-sysctl.txt2
-rw-r--r--Documentation/networking/rxrpc.txt2
-rw-r--r--Documentation/networking/udplite.txt6
-rw-r--r--Documentation/power/swsusp-and-swap-files.txt2
-rw-r--r--Documentation/powerpc/eeh-pci-error-recovery.txt4
-rw-r--r--Documentation/powerpc/mpc52xx-device-tree-bindings.txt16
-rw-r--r--Documentation/scsi/aic79xx.txt2
-rw-r--r--Documentation/scsi/aic7xxx.txt6
-rw-r--r--Documentation/scsi/arcmsr_spec.txt2
-rw-r--r--Documentation/scsi/ibmmca.txt58
-rw-r--r--Documentation/sharedsubtree.txt1
-rw-r--r--Documentation/sound/alsa/soc/DAI.txt8
-rw-r--r--Documentation/sound/alsa/soc/clocking.txt10
-rw-r--r--Documentation/sound/alsa/soc/codec.txt6
-rw-r--r--Documentation/sound/alsa/soc/dapm.txt4
-rw-r--r--Documentation/sound/alsa/soc/overview.txt17
-rw-r--r--Documentation/sound/alsa/soc/platform.txt2
-rw-r--r--Documentation/sound/alsa/soc/pops_clicks.txt6
-rw-r--r--Documentation/spi/pxa2xx2
-rw-r--r--Documentation/thinkpad-acpi.txt29
-rw-r--r--Documentation/usb/usb-serial.txt2
-rw-r--r--MAINTAINERS18
-rw-r--r--Makefile75
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/kernel/err_marvel.c2
-rw-r--r--arch/alpha/kernel/err_titan.c2
-rw-r--r--arch/alpha/kernel/osf_sys.c2
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/alpha/kernel/semaphore.c16
-rw-r--r--arch/alpha/kernel/smp.c1
-rw-r--r--arch/alpha/kernel/sys_alcor.c2
-rw-r--r--arch/alpha/kernel/sys_sio.c2
-rw-r--r--arch/alpha/kernel/traps.c6
-rw-r--r--arch/alpha/lib/checksum.c2
-rw-r--r--arch/alpha/lib/csum_partial_copy.c2
-rw-r--r--arch/alpha/lib/fls.c2
-rw-r--r--arch/alpha/mm/fault.c4
-rw-r--r--arch/alpha/mm/init.c2
-rw-r--r--arch/alpha/oprofile/Kconfig23
-rw-r--r--arch/alpha/oprofile/op_impl.h2
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/common/dmabounce.c2
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/ptrace.c8
-rw-r--r--arch/arm/kernel/traps.c10
-rw-r--r--arch/arm/mach-at91/gpio.c2
-rw-r--r--arch/arm/mach-omap1/irq.c2
-rw-r--r--arch/arm/mach-omap2/timer-gp.c2
-rw-r--r--arch/arm/mach-s3c2410/clock.c2
-rw-r--r--arch/arm/mach-s3c2412/clock.c2
-rw-r--r--arch/arm/mach-s3c2443/clock.c2
-rw-r--r--arch/arm/mm/alignment.c2
-rw-r--r--arch/arm/mm/fault.c2
-rw-r--r--arch/arm/nwfpe/fpopcode.h34
-rw-r--r--arch/arm/oprofile/Kconfig42
-rw-r--r--arch/arm/plat-omap/dma.c2
-rw-r--r--arch/arm/plat-omap/gpio.c2
-rw-r--r--arch/avr32/Kconfig2
-rw-r--r--arch/avr32/kernel/traps.c2
-rw-r--r--arch/avr32/mm/fault.c6
-rw-r--r--arch/blackfin/Kconfig134
-rw-r--r--arch/blackfin/Makefile23
-rw-r--r--arch/blackfin/boot/Makefile3
-rw-r--r--arch/blackfin/boot/install.sh57
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig1241
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig9
-rw-r--r--arch/blackfin/kernel/Makefile1
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c26
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c35
-rw-r--r--arch/blackfin/kernel/dma-mapping.c3
-rw-r--r--arch/blackfin/kernel/gptimers.c250
-rw-r--r--arch/blackfin/kernel/reboot.c2
-rw-r--r--arch/blackfin/kernel/setup.c116
-rw-r--r--arch/blackfin/kernel/traps.c2
-rw-r--r--arch/blackfin/lib/Makefile2
-rw-r--r--arch/blackfin/lib/udivdi3.S375
-rw-r--r--arch/blackfin/mach-bf527/Kconfig251
-rw-r--r--arch/blackfin/mach-bf527/Makefile9
-rw-r--r--arch/blackfin/mach-bf527/boards/Makefile7
-rw-r--r--arch/blackfin/mach-bf527/boards/eth_mac.c50
-rw-r--r--arch/blackfin/mach-bf527/boards/ezkit.c737
-rw-r--r--arch/blackfin/mach-bf527/cpu.c161
-rw-r--r--arch/blackfin/mach-bf527/dma.c115
-rw-r--r--arch/blackfin/mach-bf527/head.S456
-rw-r--r--arch/blackfin/mach-bf527/ints-priority.c100
-rw-r--r--arch/blackfin/mach-bf533/boards/cm_bf533.c2
-rw-r--r--arch/blackfin/mach-bf533/boards/ezkit.c2
-rw-r--r--arch/blackfin/mach-bf533/boards/generic_board.c2
-rw-r--r--arch/blackfin/mach-bf533/boards/stamp.c2
-rw-r--r--arch/blackfin/mach-bf537/boards/cm_bf537.c2
-rw-r--r--arch/blackfin/mach-bf537/boards/generic_board.c2
-rw-r--r--arch/blackfin/mach-bf537/boards/pnav10.c2
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c2
-rw-r--r--arch/blackfin/mach-bf548/boards/ezkit.c4
-rw-r--r--arch/blackfin/mach-bf548/dma.c1
-rw-r--r--arch/blackfin/mach-bf561/boards/cm_bf561.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/ezkit.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/generic_board.c2
-rw-r--r--arch/blackfin/mach-bf561/boards/tepla.c2
-rw-r--r--arch/blackfin/mach-common/ints-priority-dc.c8
-rw-r--r--arch/blackfin/mach-common/ints-priority-sc.c55
-rw-r--r--arch/blackfin/oprofile/Kconfig29
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/cris/arch-v10/Kconfig2
-rw-r--r--arch/cris/arch-v10/boot/compressed/misc.c2
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c2
-rw-r--r--arch/cris/arch-v10/kernel/debugport.c2
-rw-r--r--arch/cris/arch-v10/kernel/entry.S2
-rw-r--r--arch/cris/arch-v10/kernel/fasttimer.c2
-rw-r--r--arch/cris/arch-v10/kernel/irq.c2
-rw-r--r--arch/cris/arch-v10/kernel/kgdb.c2
-rw-r--r--arch/cris/arch-v10/kernel/process.c2
-rw-r--r--arch/cris/arch-v10/kernel/shadows.c2
-rw-r--r--arch/cris/arch-v10/lib/dram_init.S4
-rw-r--r--arch/cris/arch-v10/lib/string.c2
-rw-r--r--arch/cris/arch-v10/lib/usercopy.c6
-rw-r--r--arch/cris/arch-v32/boot/compressed/misc.c6
-rw-r--r--arch/cris/arch-v32/drivers/axisflashmap.c2
-rw-r--r--arch/cris/arch-v32/drivers/i2c.c2
-rw-r--r--arch/cris/arch-v32/drivers/nandflash.c2
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c2
-rw-r--r--arch/cris/arch-v32/kernel/fasttimer.c2
-rw-r--r--arch/cris/arch-v32/kernel/irq.c8
-rw-r--r--arch/cris/arch-v32/kernel/process.c2
-rw-r--r--arch/cris/arch-v32/kernel/signal.c4
-rw-r--r--arch/cris/arch-v32/kernel/smp.c2
-rw-r--r--arch/cris/arch-v32/kernel/time.c2
-rw-r--r--arch/cris/arch-v32/kernel/traps.c2
-rw-r--r--arch/cris/arch-v32/lib/dram_init.S2
-rw-r--r--arch/cris/arch-v32/lib/string.c2
-rw-r--r--arch/cris/arch-v32/lib/usercopy.c6
-rw-r--r--arch/cris/arch-v32/mm/tlb.c6
-rw-r--r--arch/cris/kernel/irq.c8
-rw-r--r--arch/cris/mm/fault.c4
-rw-r--r--arch/cris/mm/init.c2
-rw-r--r--arch/cris/mm/tlb.c2
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/frv/kernel/irq-mb93091.c2
-rw-r--r--arch/frv/kernel/irq-mb93093.c2
-rw-r--r--arch/frv/kernel/irq-mb93493.c2
-rw-r--r--arch/frv/kernel/irq.c4
-rw-r--r--arch/frv/kernel/semaphore.c2
-rw-r--r--arch/frv/kernel/time.c4
-rw-r--r--arch/h8300/Kconfig2
-rw-r--r--arch/h8300/Kconfig.debug6
-rw-r--r--arch/h8300/kernel/irq.c2
-rw-r--r--arch/h8300/kernel/time.c2
-rw-r--r--arch/h8300/kernel/traps.c2
-rw-r--r--arch/h8300/platform/h8s/ints.c2
-rw-r--r--arch/h8300/platform/h8s/ints_h8s.c2
-rw-r--r--arch/i386/Kconfig33
-rw-r--r--arch/i386/Makefile6
-rw-r--r--arch/ia64/Kconfig23
-rw-r--r--arch/ia64/configs/sn2_defconfig1
-rw-r--r--arch/ia64/hp/common/sba_iommu.c2
-rw-r--r--arch/ia64/hp/sim/simscsi.c4
-rw-r--r--arch/ia64/ia32/sys_ia32.c6
-rw-r--r--arch/ia64/kernel/efi.c8
-rw-r--r--arch/ia64/kernel/perfmon.c161
-rw-r--r--arch/ia64/kernel/perfmon_default_smpl.c8
-rw-r--r--arch/ia64/kernel/process.c3
-rw-r--r--arch/ia64/kernel/setup.c102
-rw-r--r--arch/ia64/kernel/signal.c4
-rw-r--r--arch/ia64/kernel/traps.c6
-rw-r--r--arch/ia64/kernel/unaligned.c5
-rw-r--r--arch/ia64/mm/fault.c2
-rw-r--r--arch/ia64/mm/init.c2
-rw-r--r--arch/ia64/oprofile/Kconfig20
-rw-r--r--arch/ia64/sn/pci/pci_dma.c2
-rw-r--r--arch/m32r/Kconfig2
-rw-r--r--arch/m32r/kernel/irq.c2
-rw-r--r--arch/m32r/kernel/signal.c2
-rw-r--r--arch/m32r/kernel/smp.c18
-rw-r--r--arch/m32r/kernel/smpboot.c6
-rw-r--r--arch/m32r/kernel/sys_m32r.c2
-rw-r--r--arch/m32r/kernel/traps.c2
-rw-r--r--arch/m32r/mm/fault.c2
-rw-r--r--arch/m32r/oprofile/Kconfig23
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68k/amiga/pcmcia.c2
-rw-r--r--arch/m68k/ifpsp060/CHANGES2
-rw-r--r--arch/m68k/ifpsp060/MISC2
-rw-r--r--arch/m68k/ifpsp060/README2
-rw-r--r--arch/m68k/ifpsp060/TEST.DOC2
-rw-r--r--arch/m68k/ifpsp060/fplsp.doc2
-rw-r--r--arch/m68k/ifpsp060/fpsp.doc2
-rw-r--r--arch/m68k/ifpsp060/fskeleton.S2
-rw-r--r--arch/m68k/ifpsp060/ilsp.doc2
-rw-r--r--arch/m68k/ifpsp060/iskeleton.S2
-rw-r--r--arch/m68k/ifpsp060/isp.doc2
-rw-r--r--arch/m68k/ifpsp060/os.S2
-rw-r--r--arch/m68k/ifpsp060/src/fplsp.S2
-rw-r--r--arch/m68k/ifpsp060/src/fpsp.S2
-rw-r--r--arch/m68k/ifpsp060/src/ftest.S2
-rw-r--r--arch/m68k/ifpsp060/src/ilsp.S2
-rw-r--r--arch/m68k/ifpsp060/src/isp.S2
-rw-r--r--arch/m68k/ifpsp060/src/itest.S2
-rw-r--r--arch/m68k/ifpsp060/src/pfpsp.S2
-rw-r--r--arch/m68k/kernel/dma.c2
-rw-r--r--arch/m68k/kernel/traps.c4
-rw-r--r--arch/m68k/mac/config.c4
-rw-r--r--arch/m68k/mac/iop.c4
-rw-r--r--arch/m68k/mac/oss.c2
-rw-r--r--arch/m68k/mac/via.c2
-rw-r--r--arch/m68k/math-emu/fp_log.c2
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/m68k/q40/q40ints.c4
-rw-r--r--arch/m68k/sun3/mmu_emu.c2
-rw-r--r--arch/m68k/tools/amiga/dmesg.c2
-rw-r--r--arch/m68knommu/Kconfig2
-rw-r--r--arch/m68knommu/platform/5307/pit.c2
-rw-r--r--arch/mips/Kconfig8
-rw-r--r--arch/mips/Kconfig.debug12
-rw-r--r--arch/mips/Makefile18
-rw-r--r--arch/mips/au1000/pb1200/irqmap.c2
-rw-r--r--arch/mips/basler/excite/excite_irq.c2
-rw-r--r--arch/mips/bcm47xx/time.c7
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/setup.c24
-rw-r--r--arch/mips/cobalt/time.c35
-rw-r--r--arch/mips/configs/ip27_defconfig1
-rw-r--r--arch/mips/configs/mipssim_defconfig532
-rw-r--r--arch/mips/configs/sb1250-swarm_defconfig1
-rw-r--r--arch/mips/emma2rh/markeins/setup.c6
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c144
-rw-r--r--arch/mips/kernel/cevt-r4k.c5
-rw-r--r--arch/mips/kernel/irixelf.c4
-rw-r--r--arch/mips/kernel/irixsig.c2
-rw-r--r--arch/mips/kernel/module.c2
-rw-r--r--arch/mips/kernel/sysirix.c4
-rw-r--r--arch/mips/kernel/time.c92
-rw-r--r--arch/mips/kernel/traps.c2
-rw-r--r--arch/mips/lemote/lm2e/setup.c5
-rw-r--r--arch/mips/mips-boards/generic/time.c13
-rw-r--r--arch/mips/mm/dma-default.c16
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/oprofile/Kconfig23
-rw-r--r--arch/mips/pci/pci-excite.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_time.c3
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c5
-rw-r--r--arch/mips/sgi-ip27/ip27-init.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c134
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c75
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c9
-rw-r--r--arch/mips/sibyte/bcm1480/time.c165
-rw-r--r--arch/mips/sibyte/sb1250/irq.c63
-rw-r--r--arch/mips/sibyte/sb1250/smp.c9
-rw-r--r--arch/mips/sibyte/sb1250/time.c184
-rw-r--r--arch/mips/sibyte/swarm/setup.c25
-rw-r--r--arch/mips/sni/pcimt.c2
-rw-r--r--arch/mips/sni/time.c18
-rw-r--r--arch/mips/tx4927/common/tx4927_setup.c16
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c10
-rw-r--r--arch/mips/tx4938/common/setup.c7
-rw-r--r--arch/mips/vr41xx/common/init.c5
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/parisc/Makefile58
-rw-r--r--arch/parisc/configs/712_defconfig446
-rw-r--r--arch/parisc/configs/a500_defconfig646
-rw-r--r--arch/parisc/configs/b180_defconfig474
-rw-r--r--arch/parisc/configs/c3000_defconfig582
-rw-r--r--arch/parisc/defconfig615
-rw-r--r--arch/parisc/hpux/gate.S4
-rw-r--r--arch/parisc/kernel/asm-offsets.c3
-rw-r--r--arch/parisc/kernel/entry.S41
-rw-r--r--arch/parisc/kernel/head.S6
-rw-r--r--arch/parisc/kernel/hpmc.S4
-rw-r--r--arch/parisc/kernel/init_task.c1
-rw-r--r--arch/parisc/kernel/pacache.S8
-rw-r--r--arch/parisc/kernel/parisc_ksyms.c22
-rw-r--r--arch/parisc/kernel/pci-dma.c9
-rw-r--r--arch/parisc/kernel/pci.c42
-rw-r--r--arch/parisc/kernel/processor.c7
-rw-r--r--arch/parisc/kernel/signal.c2
-rw-r--r--arch/parisc/kernel/smp.c12
-rw-r--r--arch/parisc/kernel/sys_parisc32.c7
-rw-r--r--arch/parisc/kernel/syscall.S13
-rw-r--r--arch/parisc/kernel/syscall_table.S1
-rw-r--r--arch/parisc/kernel/time.c6
-rw-r--r--arch/parisc/kernel/traps.c10
-rw-r--r--arch/parisc/kernel/unaligned.c2
-rw-r--r--arch/parisc/kernel/unwind.c4
-rw-r--r--arch/parisc/kernel/vmlinux.lds.S313
-rw-r--r--arch/parisc/lib/Makefile2
-rw-r--r--arch/parisc/lib/libgcc/Makefile4
-rw-r--r--arch/parisc/lib/libgcc/__ashldi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__ashrdi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__clzsi2.c30
-rw-r--r--arch/parisc/lib/libgcc/__divdi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__divsi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__lshrdi3.c19
-rw-r--r--arch/parisc/lib/libgcc/__moddi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__modsi3.c23
-rw-r--r--arch/parisc/lib/libgcc/__muldi3.c22
-rw-r--r--arch/parisc/lib/libgcc/__udivdi3.c7
-rw-r--r--arch/parisc/lib/libgcc/__udivmoddi4.c31
-rw-r--r--arch/parisc/lib/libgcc/__udivmodsi4.c31
-rw-r--r--arch/parisc/lib/libgcc/__udivsi3.c7
-rw-r--r--arch/parisc/lib/libgcc/__umoddi3.c10
-rw-r--r--arch/parisc/lib/libgcc/__umodsi3.c10
-rw-r--r--arch/parisc/lib/libgcc/__umulsidi3.c46
-rw-r--r--arch/parisc/lib/libgcc/libgcc.h32
-rw-r--r--arch/parisc/lib/memcpy.c4
-rw-r--r--arch/parisc/lib/milli/Makefile1
-rw-r--r--arch/parisc/lib/milli/divI.S254
-rw-r--r--arch/parisc/lib/milli/divU.S235
-rw-r--r--arch/parisc/lib/milli/div_const.S682
-rw-r--r--arch/parisc/lib/milli/dyncall.S32
-rw-r--r--arch/parisc/lib/milli/milli.S2071
-rw-r--r--arch/parisc/lib/milli/milli.h165
-rw-r--r--arch/parisc/lib/milli/mulI.S474
-rw-r--r--arch/parisc/lib/milli/remI.S185
-rw-r--r--arch/parisc/lib/milli/remU.S148
-rw-r--r--arch/parisc/mm/fault.c2
-rw-r--r--arch/parisc/mm/init.c2
-rw-r--r--arch/parisc/oprofile/Kconfig23
-rw-r--r--arch/powerpc/Kconfig15
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts26
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts26
-rw-r--r--arch/powerpc/configs/cell_defconfig1
-rw-r--r--arch/powerpc/configs/ppc64_defconfig1
-rw-r--r--arch/powerpc/configs/pseries_defconfig1
-rw-r--r--arch/powerpc/kernel/cpu_setup_6xx.S2
-rw-r--r--arch/powerpc/kernel/dma_64.c3
-rw-r--r--arch/powerpc/kernel/ibmebus.c3
-rw-r--r--arch/powerpc/kernel/iommu.c2
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/l2cr_6xx.S2
-rw-r--r--arch/powerpc/kernel/machine_kexec.c54
-rw-r--r--arch/powerpc/kernel/process.c2
-rw-r--r--arch/powerpc/kernel/traps.c4
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/oprofile/Kconfig24
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c4
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c71
-rw-r--r--arch/powerpc/platforms/Kconfig2
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/celleb/scc_uhc.c2
-rw-r--r--arch/powerpc/platforms/maple/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c5
-rw-r--r--arch/powerpc/platforms/pseries/ras.c2
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.c9
-rw-r--r--arch/ppc/Kconfig2
-rw-r--r--arch/ppc/boot/Makefile2
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/ppc/platforms/chestnut.c1
-rw-r--r--arch/s390/Kconfig16
-rw-r--r--arch/s390/defconfig131
-rw-r--r--arch/s390/kernel/ipl.c2
-rw-r--r--arch/s390/kernel/process.c20
-rw-r--r--arch/s390/kernel/smp.c65
-rw-r--r--arch/s390/lib/uaccess_pt.c92
-rw-r--r--arch/s390/mm/Makefile2
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/s390/mm/init.c32
-rw-r--r--arch/s390/mm/pgtable.c94
-rw-r--r--arch/s390/mm/vmem.c53
-rw-r--r--arch/s390/oprofile/Kconfig22
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/kernel/machine_kexec.c21
-rw-r--r--arch/sh/kernel/process.c2
-rw-r--r--arch/sh/kernel/setup.c38
-rw-r--r--arch/sh/kernel/signal.c4
-rw-r--r--arch/sh/kernel/traps.c7
-rw-r--r--arch/sh/mm/fault.c2
-rw-r--r--arch/sh/oprofile/Kconfig23
-rw-r--r--arch/sh64/Kconfig2
-rw-r--r--arch/sh64/kernel/pci_sh5.c2
-rw-r--r--arch/sh64/kernel/traps.c4
-rw-r--r--arch/sh64/mm/fault.c10
-rw-r--r--arch/sh64/oprofile/Kconfig23
-rw-r--r--arch/sparc/Kconfig6
-rw-r--r--arch/sparc/kernel/ioport.c17
-rw-r--r--arch/sparc/kernel/ptrace.c4
-rw-r--r--arch/sparc/kernel/sys_sparc.c2
-rw-r--r--arch/sparc/kernel/sys_sunos.c2
-rw-r--r--arch/sparc/kernel/traps.c4
-rw-r--r--arch/sparc/mm/io-unit.c2
-rw-r--r--arch/sparc/mm/iommu.c8
-rw-r--r--arch/sparc/mm/sun4c.c2
-rw-r--r--arch/sparc/oprofile/Kconfig17
-rw-r--r--arch/sparc64/Kconfig19
-rw-r--r--arch/sparc64/Makefile4
-rw-r--r--arch/sparc64/defconfig91
-rw-r--r--arch/sparc64/kernel/Makefile9
-rw-r--r--arch/sparc64/kernel/iommu.c7
-rw-r--r--arch/sparc64/kernel/iommu_common.c13
-rw-r--r--arch/sparc64/kernel/irq.c85
-rw-r--r--arch/sparc64/kernel/ldc.c2
-rw-r--r--arch/sparc64/kernel/pci.c3
-rw-r--r--arch/sparc64/kernel/pci_msi.c14
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c7
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c2
-rw-r--r--arch/sparc64/kernel/traps.c2
-rw-r--r--arch/sparc64/math-emu/Makefile2
-rw-r--r--arch/sparc64/oprofile/Kconfig17
-rw-r--r--arch/sparc64/solaris/misc.c4
-rw-r--r--arch/um/Kconfig4
-rw-r--r--arch/um/drivers/line.c2
-rw-r--r--arch/um/drivers/null.c2
-rw-r--r--arch/um/drivers/stderr_console.c2
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/kernel/gmon_syms.c4
-rw-r--r--arch/um/kernel/irq.c2
-rw-r--r--arch/um/kernel/ptrace.c2
-rw-r--r--arch/um/kernel/trap.c2
-rw-r--r--arch/um/sys-i386/bug.c2
-rw-r--r--arch/um/sys-i386/tls.c2
-rw-r--r--arch/um/sys-x86_64/bug.c2
-rw-r--r--arch/um/sys-x86_64/sysrq.c4
-rw-r--r--arch/v850/Kconfig2
-rw-r--r--arch/v850/kernel/me2.c4
-rw-r--r--arch/v850/kernel/rte_mb_a_pci.c4
-rw-r--r--arch/x86/boot/compressed/head_32.S15
-rw-r--r--arch/x86/boot/compressed/misc_32.c7
-rw-r--r--arch/x86/boot/compressed/misc_64.c4
-rw-r--r--arch/x86/boot/header.S7
-rw-r--r--arch/x86/ia32/ia32_binfmt.c124
-rw-r--r--arch/x86/kernel/Makefile_323
-rw-r--r--arch/x86/kernel/Makefile_644
-rw-r--r--arch/x86/kernel/acpi/Makefile_323
-rw-r--r--arch/x86/kernel/acpi/boot.c10
-rw-r--r--arch/x86/kernel/acpi/cstate.c4
-rw-r--r--arch/x86/kernel/acpi/earlyquirk_32.c84
-rw-r--r--arch/x86/kernel/acpi/processor.c2
-rw-r--r--arch/x86/kernel/alternative.c6
-rw-r--r--arch/x86/kernel/apic_32.c4
-rw-r--r--arch/x86/kernel/apm_32.c2
-rw-r--r--arch/x86/kernel/asm-offsets_32.c7
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/cpu/centaur.c4
-rw-r--r--arch/x86/kernel/cpu/common.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig_32 (renamed from arch/x86/kernel/cpu/cpufreq/Kconfig)0
-rw-r--r--arch/x86/kernel/cpu/cpufreq/Kconfig_64 (renamed from arch/x86/kernel/cpufreq/Kconfig)2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/e_powersaver.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/elanfreq.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/gx-suspmod.c8
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longrun.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k6.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.h4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/sc520_freq.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c6
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-lib.c2
-rw-r--r--arch/x86/kernel/cpu/cyrix.c10
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c12
-rw-r--r--arch/x86/kernel/cpu/mtrr/cyrix.c4
-rw-r--r--arch/x86/kernel/cpu/mtrr/generic.c2
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c2
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c16
-rw-r--r--arch/x86/kernel/cpu/proc.c11
-rw-r--r--arch/x86/kernel/cpuid.c34
-rw-r--r--arch/x86/kernel/crash_dump_32.c1
-rw-r--r--arch/x86/kernel/e820_32.c23
-rw-r--r--arch/x86/kernel/e820_64.c25
-rw-r--r--arch/x86/kernel/early-quirks.c (renamed from arch/x86/kernel/early-quirks_64.c)19
-rw-r--r--arch/x86/kernel/efi_32.c4
-rw-r--r--arch/x86/kernel/genapic_64.c15
-rw-r--r--arch/x86/kernel/genapic_flat_64.c2
-rw-r--r--arch/x86/kernel/head64.c2
-rw-r--r--arch/x86/kernel/head_32.S44
-rw-r--r--arch/x86/kernel/hpet.c5
-rw-r--r--arch/x86/kernel/i8253.c2
-rw-r--r--arch/x86/kernel/i8259_32.c3
-rw-r--r--arch/x86/kernel/init_task.c (renamed from arch/x86/kernel/init_task_32.c)11
-rw-r--r--arch/x86/kernel/init_task_64.c54
-rw-r--r--arch/x86/kernel/io_apic_32.c17
-rw-r--r--arch/x86/kernel/io_apic_64.c63
-rw-r--r--arch/x86/kernel/machine_kexec_32.c22
-rw-r--r--arch/x86/kernel/machine_kexec_64.c27
-rw-r--r--arch/x86/kernel/mce_64.c7
-rw-r--r--arch/x86/kernel/mce_amd_64.c4
-rw-r--r--arch/x86/kernel/microcode.c6
-rw-r--r--arch/x86/kernel/mpparse_32.c2
-rw-r--r--arch/x86/kernel/mpparse_64.c17
-rw-r--r--arch/x86/kernel/msr.c2
-rw-r--r--arch/x86/kernel/pci-calgary_64.c10
-rw-r--r--arch/x86/kernel/pci-dma_64.c7
-rw-r--r--arch/x86/kernel/pci-gart_64.c4
-rw-r--r--arch/x86/kernel/pci-nommu_64.c4
-rw-r--r--arch/x86/kernel/process_32.c56
-rw-r--r--arch/x86/kernel/ptrace_32.c2
-rw-r--r--arch/x86/kernel/quirks.c112
-rw-r--r--arch/x86/kernel/reboot_64.c3
-rw-r--r--arch/x86/kernel/reboot_fixups_32.c8
-rw-r--r--arch/x86/kernel/setup64.c10
-rw-r--r--arch/x86/kernel/setup_32.c59
-rw-r--r--arch/x86/kernel/setup_64.c73
-rw-r--r--arch/x86/kernel/signal_32.c6
-rw-r--r--arch/x86/kernel/signal_64.c2
-rw-r--r--arch/x86/kernel/smp_32.c8
-rw-r--r--arch/x86/kernel/smp_64.c119
-rw-r--r--arch/x86/kernel/smpboot_32.c83
-rw-r--r--arch/x86/kernel/smpboot_64.c76
-rw-r--r--arch/x86/kernel/summit_32.c2
-rw-r--r--arch/x86/kernel/suspend_64.c13
-rw-r--r--arch/x86/kernel/traps_32.c58
-rw-r--r--arch/x86/kernel/traps_64.c18
-rw-r--r--arch/x86/kernel/tsc_32.c12
-rw-r--r--arch/x86/kernel/tsc_64.c4
-rw-r--r--arch/x86/kernel/vsyscall_64.c6
-rw-r--r--arch/x86/lib/delay_32.c2
-rw-r--r--arch/x86/lib/delay_64.c3
-rw-r--r--arch/x86/lib/usercopy_32.c2
-rw-r--r--arch/x86/mach-default/setup.c4
-rw-r--r--arch/x86/mach-generic/default.c2
-rw-r--r--arch/x86/mach-generic/probe.c2
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c24
-rw-r--r--arch/x86/mach-voyager/voyager_thread.c2
-rw-r--r--arch/x86/mm/boot_ioremap_32.c2
-rw-r--r--arch/x86/mm/discontig_32.c2
-rw-r--r--arch/x86/mm/fault_32.c13
-rw-r--r--arch/x86/mm/fault_64.c22
-rw-r--r--arch/x86/mm/numa_64.c2
-rw-r--r--arch/x86/mm/pageattr_64.c15
-rw-r--r--arch/x86/mm/srat_64.c2
-rw-r--r--arch/x86/oprofile/backtrace.c110
-rw-r--r--arch/x86/oprofile/op_x86_model.h2
-rw-r--r--arch/x86/pci/irq.c4
-rw-r--r--arch/x86_64/.gitignore1
-rw-r--r--arch/x86_64/Kconfig57
-rw-r--r--arch/x86_64/Makefile6
-rw-r--r--arch/xtensa/Kconfig2
-rw-r--r--arch/xtensa/boot/Makefile3
-rw-r--r--arch/xtensa/kernel/traps.c6
-rw-r--r--arch/xtensa/mm/fault.c2
-rw-r--r--arch/xtensa/platform-iss/network.c2
-rw-r--r--block/elevator.c2
-rw-r--r--block/ll_rw_blk.c12
-rw-r--r--crypto/api.c2
-rw-r--r--crypto/digest.c2
-rw-r--r--crypto/fcrypt.c2
-rw-r--r--crypto/hmac.c3
-rw-r--r--crypto/scatterwalk.c2
-rw-r--r--crypto/scatterwalk.h6
-rw-r--r--crypto/tcrypt.c4
-rw-r--r--crypto/xcbc.c2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/Kconfig16
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c33
-rw-r--r--drivers/acpi/battery.c1038
-rw-r--r--drivers/acpi/bus.c23
-rw-r--r--drivers/acpi/button.c6
-rw-r--r--drivers/acpi/ec.c93
-rw-r--r--drivers/acpi/events/evevent.c6
-rw-r--r--drivers/acpi/hardware/hwregs.c89
-rw-r--r--drivers/acpi/hardware/hwsleep.c40
-rw-r--r--drivers/acpi/osl.c8
-rw-r--r--drivers/acpi/processor_core.c30
-rw-r--r--drivers/acpi/processor_idle.c488
-rw-r--r--drivers/acpi/sbs.c1869
-rw-r--r--drivers/acpi/sbshc.c309
-rw-r--r--drivers/acpi/sbshc.h27
-rw-r--r--drivers/acpi/sleep/main.c6
-rw-r--r--drivers/acpi/sleep/sleep.h1
-rw-r--r--drivers/acpi/sleep/wakeup.c117
-rw-r--r--drivers/acpi/tables/tbutils.c2
-rw-r--r--drivers/acpi/thermal.c28
-rw-r--r--drivers/acpi/video.c30
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/ata/libata-core.c12
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/ata/libata-sff.c2
-rw-r--r--drivers/ata/pata_cmd64x.c2
-rw-r--r--drivers/ata/pata_cs5530.c2
-rw-r--r--drivers/ata/pata_cs5535.c2
-rw-r--r--drivers/ata/pata_cs5536.c4
-rw-r--r--drivers/ata/pata_it821x.c4
-rw-r--r--drivers/ata/pata_mpiix.c2
-rw-r--r--drivers/ata/pata_ns87410.c2
-rw-r--r--drivers/ata/pata_oldpiix.c2
-rw-r--r--drivers/ata/pata_radisys.c2
-rw-r--r--drivers/ata/pata_sc1200.c2
-rw-r--r--drivers/ata/pata_sil680.c2
-rw-r--r--drivers/ata/pata_via.c2
-rw-r--r--drivers/ata/sata_sis.c15
-rw-r--r--drivers/atm/firestream.c2
-rw-r--r--drivers/base/memory.c9
-rw-r--r--drivers/block/DAC960.c2
-rw-r--r--drivers/block/Kconfig21
-rw-r--r--drivers/block/cciss.c4
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/cryptoloop.c12
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/nbd.c3
-rw-r--r--drivers/block/rd.c2
-rw-r--r--drivers/block/sunvdc.c1
-rw-r--r--drivers/block/sx8.c1
-rw-r--r--drivers/block/ub.c11
-rw-r--r--drivers/block/viodasd.c2
-rw-r--r--drivers/bluetooth/Kconfig35
-rw-r--r--drivers/bluetooth/Makefile4
-rw-r--r--drivers/bluetooth/bluecard_cs.c5
-rw-r--r--drivers/bluetooth/bpa10x.c624
-rw-r--r--drivers/bluetooth/bt3c_cs.c5
-rw-r--r--drivers/bluetooth/btsdio.c406
-rw-r--r--drivers/bluetooth/btuart_cs.c5
-rw-r--r--drivers/bluetooth/btusb.c564
-rw-r--r--drivers/bluetooth/dtl1_cs.c5
-rw-r--r--drivers/bluetooth/hci_bcsp.c3
-rw-r--r--drivers/bluetooth/hci_ldisc.c8
-rw-r--r--drivers/bluetooth/hci_ll.c531
-rw-r--r--drivers/bluetooth/hci_uart.h8
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/char/cyclades.c4
-rw-r--r--drivers/char/drm/drm_bufs.c2
-rw-r--r--drivers/char/drm/drm_drv.c2
-rw-r--r--drivers/char/drm/drm_fops.c7
-rw-r--r--drivers/char/drm/drm_hashtab.c2
-rw-r--r--drivers/char/drm/drm_hashtab.h2
-rw-r--r--drivers/char/drm/drm_lock.c6
-rw-r--r--drivers/char/drm/drm_mm.c2
-rw-r--r--drivers/char/drm/drm_os_linux.h2
-rw-r--r--drivers/char/drm/drm_pci.c4
-rw-r--r--drivers/char/drm/drm_sarea.h2
-rw-r--r--drivers/char/drm/drm_sman.c2
-rw-r--r--drivers/char/drm/drm_sman.h2
-rw-r--r--drivers/char/drm/i810_dma.c2
-rw-r--r--drivers/char/drm/i830_dma.c2
-rw-r--r--drivers/char/drm/r128_drv.h2
-rw-r--r--drivers/char/drm/radeon_irq.c2
-rw-r--r--drivers/char/drm/radeon_state.c2
-rw-r--r--drivers/char/drm/sis_mm.c2
-rw-r--r--drivers/char/drm/via_mm.c2
-rw-r--r--drivers/char/drm/via_verifier.h2
-rw-r--r--drivers/char/esp.c4
-rw-r--r--drivers/char/hw_random/omap-rng.c2
-rw-r--r--drivers/char/i8k.c14
-rw-r--r--drivers/char/keyboard.c48
-rw-r--r--drivers/char/mxser.c2
-rw-r--r--drivers/char/mxser_new.c2
-rw-r--r--drivers/char/n_tty.c4
-rw-r--r--drivers/char/rocket.c2
-rw-r--r--drivers/char/sonypi.c10
-rw-r--r--drivers/char/sx.c2
-rw-r--r--drivers/char/sysrq.c2
-rw-r--r--drivers/char/tty_io.c25
-rw-r--r--drivers/char/tty_ioctl.c2
-rw-r--r--drivers/char/vt.c45
-rw-r--r--drivers/cpuidle/Kconfig20
-rw-r--r--drivers/cpuidle/Makefile5
-rw-r--r--drivers/cpuidle/cpuidle.c295
-rw-r--r--drivers/cpuidle/cpuidle.h33
-rw-r--r--drivers/cpuidle/driver.c56
-rw-r--r--drivers/cpuidle/governor.c141
-rw-r--r--drivers/cpuidle/governors/Makefile6
-rw-r--r--drivers/cpuidle/governors/ladder.c166
-rw-r--r--drivers/cpuidle/governors/menu.c137
-rw-r--r--drivers/cpuidle/sysfs.c361
-rw-r--r--drivers/edac/edac_core.h2
-rw-r--r--drivers/edac/pasemi_edac.c1
-rw-r--r--drivers/firewire/fw-ohci.c13
-rw-r--r--drivers/firewire/fw-transaction.c2
-rw-r--r--drivers/firmware/dcdbas.h1
-rw-r--r--drivers/hid/hidraw.c4
-rw-r--r--drivers/hid/usbhid/hid-ff.c2
-rw-r--r--drivers/hid/usbhid/usbkbd.c7
-rw-r--r--drivers/hid/usbhid/usbmouse.c12
-rw-r--r--drivers/hwmon/applesmc.c2
-rw-r--r--drivers/hwmon/coretemp.c6
-rw-r--r--drivers/hwmon/gl520sm.c4
-rw-r--r--drivers/hwmon/hdaps.c2
-rw-r--r--drivers/hwmon/hwmon-vid.c2
-rw-r--r--drivers/hwmon/sis5595.c2
-rw-r--r--drivers/hwmon/via686a.c4
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-pca.c2
-rw-r--r--drivers/i2c/algos/i2c-algo-pcf.c2
-rw-r--r--drivers/i2c/busses/Kconfig10
-rw-r--r--drivers/i2c/busses/i2c-elektor.c2
-rw-r--r--drivers/i2c/busses/i2c-hydra.c2
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c2
-rw-r--r--drivers/i2c/busses/i2c-omap.c2
-rw-r--r--drivers/i2c/busses/i2c-parport-light.c2
-rw-r--r--drivers/i2c/busses/i2c-parport.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c54
-rw-r--r--drivers/i2c/busses/i2c-via.c4
-rw-r--r--drivers/i2c/busses/i2c-viapro.c2
-rw-r--r--drivers/i2c/i2c-core.c2
-rw-r--r--drivers/ide/Kconfig3
-rw-r--r--drivers/ide/arm/bast-ide.c2
-rw-r--r--drivers/ide/arm/icside.c62
-rw-r--r--drivers/ide/arm/ide_arm.c2
-rw-r--r--drivers/ide/arm/rapide.c37
-rw-r--r--drivers/ide/cris/ide-cris.c6
-rw-r--r--drivers/ide/h8300/ide-h8300.c3
-rw-r--r--drivers/ide/ide-acpi.c2
-rw-r--r--drivers/ide/ide-cd.c6
-rw-r--r--drivers/ide/ide-disk.c24
-rw-r--r--drivers/ide/ide-dma.c32
-rw-r--r--drivers/ide/ide-io.c61
-rw-r--r--drivers/ide/ide-iops.c26
-rw-r--r--drivers/ide/ide-pnp.c3
-rw-r--r--drivers/ide/ide-probe.c91
-rw-r--r--drivers/ide/ide-proc.c2
-rw-r--r--drivers/ide/ide-tape.c3
-rw-r--r--drivers/ide/ide-taskfile.c39
-rw-r--r--drivers/ide/ide.c73
-rw-r--r--drivers/ide/legacy/ali14xx.c13
-rw-r--r--drivers/ide/legacy/buddha.c4
-rw-r--r--drivers/ide/legacy/dtc2278.c16
-rw-r--r--drivers/ide/legacy/falconide.c2
-rw-r--r--drivers/ide/legacy/gayle.c2
-rw-r--r--drivers/ide/legacy/ht6560b.c33
-rw-r--r--drivers/ide/legacy/ide-cs.c2
-rw-r--r--drivers/ide/legacy/ide_platform.c43
-rw-r--r--drivers/ide/legacy/macide.c6
-rw-r--r--drivers/ide/legacy/q40ide.c7
-rw-r--r--drivers/ide/legacy/qd65xx.c64
-rw-r--r--drivers/ide/legacy/umc8672.c9
-rw-r--r--drivers/ide/mips/au1xxx-ide.c25
-rw-r--r--drivers/ide/mips/swarm.c14
-rw-r--r--drivers/ide/pci/aec62xx.c25
-rw-r--r--drivers/ide/pci/alim15x3.c109
-rw-r--r--drivers/ide/pci/amd74xx.c29
-rw-r--r--drivers/ide/pci/atiixp.c3
-rw-r--r--drivers/ide/pci/cmd640.c42
-rw-r--r--drivers/ide/pci/cmd64x.c6
-rw-r--r--drivers/ide/pci/cs5520.c26
-rw-r--r--drivers/ide/pci/cs5530.c10
-rw-r--r--drivers/ide/pci/cs5535.c2
-rw-r--r--drivers/ide/pci/cy82c693.c4
-rw-r--r--drivers/ide/pci/delkin_cb.c2
-rw-r--r--drivers/ide/pci/generic.c31
-rw-r--r--drivers/ide/pci/hpt34x.c4
-rw-r--r--drivers/ide/pci/hpt366.c4
-rw-r--r--drivers/ide/pci/it8213.c2
-rw-r--r--drivers/ide/pci/it821x.c6
-rw-r--r--drivers/ide/pci/jmicron.c2
-rw-r--r--drivers/ide/pci/ns87415.c2
-rw-r--r--drivers/ide/pci/opti621.c10
-rw-r--r--drivers/ide/pci/pdc202xx_new.c4
-rw-r--r--drivers/ide/pci/pdc202xx_old.c22
-rw-r--r--drivers/ide/pci/piix.c6
-rw-r--r--drivers/ide/pci/rz1000.c7
-rw-r--r--drivers/ide/pci/sc1200.c2
-rw-r--r--drivers/ide/pci/scc_pata.c11
-rw-r--r--drivers/ide/pci/serverworks.c11
-rw-r--r--drivers/ide/pci/sgiioc4.c16
-rw-r--r--drivers/ide/pci/siimage.c94
-rw-r--r--drivers/ide/pci/sis5513.c4
-rw-r--r--drivers/ide/pci/sl82c105.c14
-rw-r--r--drivers/ide/pci/slc90e66.c10
-rw-r--r--drivers/ide/pci/tc86c001.c2
-rw-r--r--drivers/ide/pci/triflex.c2
-rw-r--r--drivers/ide/pci/trm290.c4
-rw-r--r--drivers/ide/pci/via82cxxx.c81
-rw-r--r--drivers/ide/ppc/mpc8xx.c4
-rw-r--r--drivers/ide/ppc/pmac.c12
-rw-r--r--drivers/ide/setup-pci.c202
-rw-r--r--drivers/ieee1394/dma.c2
-rw-r--r--drivers/ieee1394/sbp2.c2
-rw-r--r--drivers/infiniband/core/cma.c5
-rw-r--r--drivers/infiniband/core/umem.c11
-rw-r--r--drivers/infiniband/hw/ipath/ipath_dma.c4
-rw-r--r--drivers/infiniband/hw/ipath/ipath_mr.c2
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c24
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c8
-rw-r--r--drivers/input/evdev.c12
-rw-r--r--drivers/input/fixp-arith.h2
-rw-r--r--drivers/input/gameport/gameport.c3
-rw-r--r--drivers/input/input.c10
-rw-r--r--drivers/input/joydev.c16
-rw-r--r--drivers/input/joystick/a3d.c28
-rw-r--r--drivers/input/joystick/adi.c2
-rw-r--r--drivers/input/joystick/amijoy.c7
-rw-r--r--drivers/input/joystick/analog.c2
-rw-r--r--drivers/input/joystick/cobra.c2
-rw-r--r--drivers/input/joystick/db9.c4
-rw-r--r--drivers/input/joystick/gamecon.c4
-rw-r--r--drivers/input/joystick/gf2k.c2
-rw-r--r--drivers/input/joystick/grip.c2
-rw-r--r--drivers/input/joystick/grip_mp.c2
-rw-r--r--drivers/input/joystick/guillemot.c2
-rw-r--r--drivers/input/joystick/iforce/Makefile2
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c3
-rw-r--r--drivers/input/joystick/iforce/iforce.h4
-rw-r--r--drivers/input/joystick/interact.c2
-rw-r--r--drivers/input/joystick/magellan.c2
-rw-r--r--drivers/input/joystick/sidewinder.c2
-rw-r--r--drivers/input/joystick/spaceball.c17
-rw-r--r--drivers/input/joystick/spaceorb.c2
-rw-r--r--drivers/input/joystick/stinger.c9
-rw-r--r--drivers/input/joystick/tmdc.c2
-rw-r--r--drivers/input/joystick/turbografx.c2
-rw-r--r--drivers/input/joystick/twidjoy.c2
-rw-r--r--drivers/input/joystick/warrior.c8
-rw-r--r--drivers/input/joystick/xpad.c2
-rw-r--r--drivers/input/keyboard/aaed2000_kbd.c2
-rw-r--r--drivers/input/keyboard/amikbd.c2
-rw-r--r--drivers/input/keyboard/atakbd.c2
-rw-r--r--drivers/input/keyboard/atkbd.c21
-rw-r--r--drivers/input/keyboard/bf54x-keys.c1
-rw-r--r--drivers/input/keyboard/corgikbd.c3
-rw-r--r--drivers/input/keyboard/gpio_keys.c2
-rw-r--r--drivers/input/keyboard/hil_kbd.c5
-rw-r--r--drivers/input/keyboard/hilkbd.c5
-rw-r--r--drivers/input/keyboard/locomokbd.c2
-rw-r--r--drivers/input/keyboard/newtonkbd.c2
-rw-r--r--drivers/input/keyboard/omap-keypad.c4
-rw-r--r--drivers/input/keyboard/pxa27x_keyboard.c5
-rw-r--r--drivers/input/keyboard/spitzkbd.c3
-rw-r--r--drivers/input/keyboard/stowaway.c2
-rw-r--r--drivers/input/keyboard/sunkbd.c8
-rw-r--r--drivers/input/keyboard/xtkbd.c2
-rw-r--r--drivers/input/misc/Kconfig4
-rw-r--r--drivers/input/misc/ati_remote.c8
-rw-r--r--drivers/input/misc/ati_remote2.c7
-rw-r--r--drivers/input/misc/atlas_btns.c2
-rw-r--r--drivers/input/misc/cobalt_btns.c2
-rw-r--r--drivers/input/misc/ixp4xx-beeper.c4
-rw-r--r--drivers/input/misc/keyspan_remote.c2
-rw-r--r--drivers/input/misc/m68kspkr.c4
-rw-r--r--drivers/input/misc/pcspkr.c4
-rw-r--r--drivers/input/misc/powermate.c9
-rw-r--r--drivers/input/misc/sparcspkr.c4
-rw-r--r--drivers/input/misc/yealink.c2
-rw-r--r--drivers/input/mouse/alps.c26
-rw-r--r--drivers/input/mouse/amimouse.c7
-rw-r--r--drivers/input/mouse/appletouch.c25
-rw-r--r--drivers/input/mouse/atarimouse.c7
-rw-r--r--drivers/input/mouse/hil_ptr.c6
-rw-r--r--drivers/input/mouse/inport.c7
-rw-r--r--drivers/input/mouse/lifebook.c11
-rw-r--r--drivers/input/mouse/logibm.c7
-rw-r--r--drivers/input/mouse/pc110pad.c6
-rw-r--r--drivers/input/mouse/psmouse-base.c9
-rw-r--r--drivers/input/mouse/rpcmouse.c7
-rw-r--r--drivers/input/mouse/sermouse.c7
-rw-r--r--drivers/input/mouse/touchkit_ps2.c2
-rw-r--r--drivers/input/mouse/vsxxxaa.c2
-rw-r--r--drivers/input/mousedev.c26
-rw-r--r--drivers/input/serio/i8042.c4
-rw-r--r--drivers/input/serio/i8042.h22
-rw-r--r--drivers/input/tablet/acecad.c12
-rw-r--r--drivers/input/tablet/gtco.c6
-rw-r--r--drivers/input/tablet/kbtab.c11
-rw-r--r--drivers/input/tablet/wacom_sys.c58
-rw-r--r--drivers/input/touchscreen/Kconfig6
-rw-r--r--drivers/input/touchscreen/ads7846.c4
-rw-r--r--drivers/input/touchscreen/corgi_ts.c4
-rw-r--r--drivers/input/touchscreen/elo.c4
-rw-r--r--drivers/input/touchscreen/fujitsu_ts.c4
-rw-r--r--drivers/input/touchscreen/gunze.c4
-rw-r--r--drivers/input/touchscreen/h3600_ts_input.c5
-rw-r--r--drivers/input/touchscreen/hp680_ts_input.c4
-rw-r--r--drivers/input/touchscreen/mk712.c4
-rw-r--r--drivers/input/touchscreen/mtouch.c4
-rw-r--r--drivers/input/touchscreen/penmount.c4
-rw-r--r--drivers/input/touchscreen/touchright.c4
-rw-r--r--drivers/input/touchscreen/touchwin.c4
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c40
-rw-r--r--drivers/isdn/act2000/act2000_isa.c2
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c28
-rw-r--r--drivers/isdn/hardware/avm/c4.c2
-rw-r--r--drivers/isdn/hardware/avm/t1isa.c28
-rw-r--r--drivers/isdn/hardware/eicon/capifunc.c4
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c2
-rw-r--r--drivers/isdn/hisax/enternow_pci.c18
-rw-r--r--drivers/isdn/hisax/hfc_pci.c2
-rw-r--r--drivers/isdn/hisax/isdnhdlc.c4
-rw-r--r--drivers/isdn/hisax/isdnhdlc.h2
-rw-r--r--drivers/isdn/hisax/jade.c2
-rw-r--r--drivers/isdn/pcbit/capi.c4
-rw-r--r--drivers/isdn/sc/debug.h19
-rw-r--r--drivers/isdn/sc/includes.h1
-rw-r--r--drivers/isdn/sc/init.c2
-rw-r--r--drivers/kvm/kvm_main.c37
-rw-r--r--drivers/kvm/lapic.c38
-rw-r--r--drivers/kvm/mmu.c3
-rw-r--r--drivers/kvm/vmx.c16
-rw-r--r--drivers/kvm/x86_emulate.c77
-rw-r--r--drivers/leds/leds-s3c24xx.c2
-rw-r--r--drivers/macintosh/adbhid.c19
-rw-r--r--drivers/macintosh/mac_hid.c7
-rw-r--r--drivers/macintosh/mediabay.c2
-rw-r--r--drivers/macintosh/via-pmu.c2
-rw-r--r--drivers/md/Kconfig12
-rw-r--r--drivers/md/Makefile6
-rw-r--r--drivers/md/dm-bio-list.h5
-rw-r--r--drivers/md/dm-crypt.c193
-rw-r--r--drivers/md/dm-delay.c23
-rw-r--r--drivers/md/dm-emc.c8
-rw-r--r--drivers/md/dm-hw-handler.c6
-rw-r--r--drivers/md/dm-hw-handler.h1
-rw-r--r--drivers/md/dm-ioctl.c40
-rw-r--r--drivers/md/dm-log.c2
-rw-r--r--drivers/md/dm-log.h3
-rw-r--r--drivers/md/dm-mpath-hp-sw.c248
-rw-r--r--drivers/md/dm-mpath-rdac.c15
-rw-r--r--drivers/md/dm-mpath.c88
-rw-r--r--drivers/md/dm-path-selector.c6
-rw-r--r--drivers/md/dm-raid1.c35
-rw-r--r--drivers/md/dm-snap.c3
-rw-r--r--drivers/md/dm-stripe.c3
-rw-r--r--drivers/md/dm-table.c3
-rw-r--r--drivers/md/dm-target.c6
-rw-r--r--drivers/md/dm-uevent.c222
-rw-r--r--drivers/md/dm-uevent.h59
-rw-r--r--drivers/md/dm.c79
-rw-r--r--drivers/md/kcopyd.c8
-rw-r--r--drivers/md/md.c2
-rw-r--r--drivers/md/raid1.c2
-rw-r--r--drivers/media/common/ir-keymaps.c70
-rw-r--r--drivers/media/common/saa7146_core.c3
-rw-r--r--drivers/media/common/saa7146_hlp.c2
-rw-r--r--drivers/media/dvb/bt8xx/bt878.c2
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c46
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_ir.c2
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c2
-rw-r--r--drivers/media/dvb/ttusb-dec/ttusb_dec.c2
-rw-r--r--drivers/media/radio/miropcm20-radio.c1
-rw-r--r--drivers/media/radio/radio-gemtek.c1
-rw-r--r--drivers/media/video/arv.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c26
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c3
-rw-r--r--drivers/media/video/bw-qcam.c1
-rw-r--r--drivers/media/video/c-qcam.c1
-rw-r--r--drivers/media/video/cpia.c5
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c5
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c6
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c86
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c57
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c3
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c133
-rw-r--r--drivers/media/video/cx88/cx88-video.c1
-rw-r--r--drivers/media/video/cx88/cx88-vp3054-i2c.c16
-rw-r--r--drivers/media/video/cx88/cx88.h24
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c1
-rw-r--r--drivers/media/video/ir-kbd-i2c.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c13
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c116
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c160
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.h1
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c92
-rw-r--r--drivers/media/video/meye.c3
-rw-r--r--drivers/media/video/meye.h2
-rw-r--r--drivers/media/video/ov511.c1
-rw-r--r--drivers/media/video/planb.c1
-rw-r--r--drivers/media/video/pms.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h11
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c3
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c3
-rw-r--r--drivers/media/video/pwc/pwc-if.c1
-rw-r--r--drivers/media/video/saa5246a.c4
-rw-r--r--drivers/media/video/saa5249.c4
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c111
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c44
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c12
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c29
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c32
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c28
-rw-r--r--drivers/media/video/saa7134/saa7134.h7
-rw-r--r--drivers/media/video/se401.c1
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c1
-rw-r--r--drivers/media/video/stradis.c1
-rw-r--r--drivers/media/video/stv680.c1
-rw-r--r--drivers/media/video/tuner-core.c2
-rw-r--r--drivers/media/video/usbvideo/konicawc.c4
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c4
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c1
-rw-r--r--drivers/media/video/usbvideo/vicam.c3
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c3
-rw-r--r--drivers/media/video/v4l2-common.c4
-rw-r--r--drivers/media/video/videobuf-core.c2
-rw-r--r--drivers/media/video/videobuf-dma-sg.c8
-rw-r--r--drivers/media/video/videocodec.c4
-rw-r--r--drivers/media/video/videodev.c42
-rw-r--r--drivers/media/video/vivi.c1
-rw-r--r--drivers/media/video/w9966.c1
-rw-r--r--drivers/media/video/w9968cf.c1
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c1
-rw-r--r--drivers/media/video/zoran_card.c10
-rw-r--r--drivers/media/video/zoran_driver.c6
-rw-r--r--drivers/message/i2o/README4
-rw-r--r--drivers/message/i2o/exec-osm.c4
-rw-r--r--drivers/message/i2o/i2o_config.c6
-rw-r--r--drivers/message/i2o/i2o_proc.c4
-rw-r--r--drivers/message/i2o/iop.c4
-rw-r--r--drivers/message/i2o/pci.c4
-rw-r--r--drivers/mfd/Kconfig4
-rw-r--r--drivers/misc/Kconfig21
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/fujitsu-laptop.c358
-rw-r--r--drivers/misc/ibmasm/remote.c10
-rw-r--r--drivers/misc/phantom.c97
-rw-r--r--drivers/misc/sony-laptop.c214
-rw-r--r--drivers/misc/thinkpad_acpi.c207
-rw-r--r--drivers/misc/thinkpad_acpi.h37
-rw-r--r--drivers/mmc/card/queue.c15
-rw-r--r--drivers/mmc/host/at91_mci.c8
-rw-r--r--drivers/mmc/host/au1xmmc.c11
-rw-r--r--drivers/mmc/host/imxmmc.c2
-rw-r--r--drivers/mmc/host/mmc_spi.c8
-rw-r--r--drivers/mmc/host/omap.c4
-rw-r--r--drivers/mmc/host/sdhci.c2
-rw-r--r--drivers/mmc/host/tifm_sd.c8
-rw-r--r--drivers/mmc/host/wbsd.c6
-rw-r--r--drivers/mtd/maps/Kconfig10
-rw-r--r--drivers/mtd/ubi/wl.c2
-rw-r--r--drivers/net/8139too.c2
-rw-r--r--drivers/net/Kconfig43
-rw-r--r--drivers/net/amd8111e.c2
-rw-r--r--drivers/net/ariadne.c2
-rw-r--r--drivers/net/ariadne.h2
-rw-r--r--drivers/net/au1000_eth.c2
-rw-r--r--drivers/net/bnx2.c2
-rw-r--r--drivers/net/bonding/bond_3ad.c32
-rw-r--r--drivers/net/bonding/bond_3ad.h12
-rw-r--r--drivers/net/bonding/bond_sysfs.c2
-rw-r--r--drivers/net/cpmac.c2
-rw-r--r--drivers/net/cris/eth_v10.c2
-rw-r--r--drivers/net/cxgb3/adapter.h2
-rw-r--r--drivers/net/dm9000.c6
-rw-r--r--drivers/net/e100.c2
-rw-r--r--drivers/net/e1000/e1000_main.c2
-rw-r--r--drivers/net/eth16i.c1
-rw-r--r--drivers/net/fealnx.c1
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/Kconfig2
-rw-r--r--drivers/net/hamradio/dmascc.c2
-rw-r--r--drivers/net/irda/actisys-sir.c2
-rw-r--r--drivers/net/irda/actisys.c2
-rw-r--r--drivers/net/irda/donauboe.c2
-rw-r--r--drivers/net/irda/girbil-sir.c2
-rw-r--r--drivers/net/irda/girbil.c2
-rw-r--r--drivers/net/irda/irport.h2
-rw-r--r--drivers/net/irda/irtty-sir.c2
-rw-r--r--drivers/net/irda/nsc-ircc.c2
-rw-r--r--drivers/net/irda/nsc-ircc.h2
-rw-r--r--drivers/net/irda/tekram-sir.c2
-rw-r--r--drivers/net/irda/tekram.c2
-rw-r--r--drivers/net/irda/w83977af_ir.h2
-rw-r--r--drivers/net/mac89x0.c2
-rw-r--r--drivers/net/meth.h3
-rw-r--r--drivers/net/mlx4/icm.c14
-rw-r--r--drivers/net/natsemi.c2
-rw-r--r--drivers/net/niu.c34
-rw-r--r--drivers/net/phy/mdio-bitbang.c2
-rw-r--r--drivers/net/ppp_mppe.c6
-rw-r--r--drivers/net/s2io-regs.h632
-rw-r--r--drivers/net/s2io.c16
-rw-r--r--drivers/net/s2io.h84
-rw-r--r--drivers/net/smc911x.c2
-rw-r--r--drivers/net/spider_net.c4
-rw-r--r--drivers/net/tc35815.c4
-rw-r--r--drivers/net/tg3.c95
-rw-r--r--drivers/net/tg3.h11
-rw-r--r--drivers/net/tsi108_eth.c2
-rw-r--r--drivers/net/tulip/Kconfig14
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/tulip/winbond-840.c2
-rw-r--r--drivers/net/usb/Kconfig2
-rw-r--r--drivers/net/via-velocity.c2
-rw-r--r--drivers/net/wireless/b43/main.c5
-rw-r--r--drivers/net/wireless/b43legacy/main.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_leds.c2
-rw-r--r--drivers/net/wireless/bcm43xx/bcm43xx_xmit.h2
-rw-r--r--drivers/net/wireless/hostap/hostap_common.h3
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c2
-rw-r--r--drivers/net/wireless/ipw2100.c72
-rw-r--r--drivers/net/wireless/ipw2100.h6
-rw-r--r--drivers/net/wireless/ipw2200.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwlwifi.h7
-rw-r--r--drivers/net/wireless/netwave_cs.c8
-rw-r--r--drivers/net/wireless/p54common.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rtl8187_dev.c35
-rw-r--r--drivers/net/wireless/zd1201.c4
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c7
-rw-r--r--drivers/parisc/lba_pci.c51
-rw-r--r--drivers/parisc/pdc_stable.c11
-rw-r--r--drivers/parisc/sba_iommu.c4
-rw-r--r--drivers/parisc/superio.c4
-rw-r--r--drivers/pci/Makefile3
-rw-r--r--drivers/pci/dmar.c329
-rw-r--r--drivers/pci/intel-iommu.c2271
-rw-r--r--drivers/pci/intel-iommu.h325
-rw-r--r--drivers/pci/iova.c394
-rw-r--r--drivers/pci/iova.h63
-rw-r--r--drivers/pci/pci.h1
-rw-r--r--drivers/pci/probe.c14
-rw-r--r--drivers/pci/search.c34
-rw-r--r--drivers/pcmcia/m32r_pcc.c2
-rw-r--r--drivers/pcmcia/m8xx_pcmcia.c2
-rw-r--r--drivers/power/apm_power.c141
-rw-r--r--drivers/ps3/ps3av.c6
-rw-r--r--drivers/ps3/vuart.c2
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/rtc/rtc-sa1100.c2
-rw-r--r--drivers/s390/block/dasd_3990_erp.c4
-rw-r--r--drivers/s390/char/raw3270.c26
-rw-r--r--drivers/s390/char/sclp_cpi.c2
-rw-r--r--drivers/s390/char/tape_class.c19
-rw-r--r--drivers/s390/char/tape_class.h4
-rw-r--r--drivers/s390/char/vmlogrdr.c15
-rw-r--r--drivers/s390/cio/chp.c12
-rw-r--r--drivers/s390/cio/cmf.c2
-rw-r--r--drivers/s390/cio/css.c9
-rw-r--r--drivers/s390/cio/idset.c2
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/ctcmain.c10
-rw-r--r--drivers/s390/net/qeth_main.c3
-rw-r--r--drivers/sbus/char/vfc_dev.c2
-rw-r--r--drivers/scsi/3w-9xxx.c4
-rw-r--r--drivers/scsi/3w-xxxx.c2
-rw-r--r--drivers/scsi/FlashPoint.c83
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/NCR5380.c6
-rw-r--r--drivers/scsi/NCR53C9x.c4
-rw-r--r--drivers/scsi/NCR53c406a.c6
-rw-r--r--drivers/scsi/aacraid/aachba.c2
-rw-r--r--drivers/scsi/aacraid/aacraid.h2
-rw-r--r--drivers/scsi/aha152x.c8
-rw-r--r--drivers/scsi/aha1542.c8
-rw-r--r--drivers/scsi/aic7xxx/cam.h2
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c4
-rw-r--r--drivers/scsi/atari_NCR5380.c6
-rw-r--r--drivers/scsi/dc395x.c6
-rw-r--r--drivers/scsi/eata_pio.c4
-rw-r--r--drivers/scsi/fd_mcs.c6
-rw-r--r--drivers/scsi/fdomain.c7
-rw-r--r--drivers/scsi/gdth.c6
-rw-r--r--drivers/scsi/ibmmca.c2
-rw-r--r--drivers/scsi/ide-scsi.c14
-rw-r--r--drivers/scsi/imm.c8
-rw-r--r--drivers/scsi/in2000.c4
-rw-r--r--drivers/scsi/ipr.c19
-rw-r--r--drivers/scsi/ips.c6
-rw-r--r--drivers/scsi/iscsi_tcp.c15
-rw-r--r--drivers/scsi/libsas/sas_discover.c8
-rw-r--r--drivers/scsi/megaraid.c8
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c14
-rw-r--r--drivers/scsi/nsp32.h5
-rw-r--r--drivers/scsi/oktagon_esp.c6
-rw-r--r--drivers/scsi/osst.c32
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h3
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c6
-rw-r--r--drivers/scsi/ppa.c7
-rw-r--r--drivers/scsi/ps3rom.c6
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_iocb.c2
-rw-r--r--drivers/scsi/qlogicfas408.c2
-rw-r--r--drivers/scsi/scsi_debug.c4
-rw-r--r--drivers/scsi/scsi_lib.c13
-rw-r--r--drivers/scsi/sd.c2
-rw-r--r--drivers/scsi/seagate.c8
-rw-r--r--drivers/scsi/sg.c30
-rw-r--r--drivers/scsi/st.c8
-rw-r--r--drivers/scsi/sun3_NCR5380.c5
-rw-r--r--drivers/scsi/sym53c416.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_fw2.h2
-rw-r--r--drivers/scsi/tmscsim.c5
-rw-r--r--drivers/scsi/ultrastor.c2
-rw-r--r--drivers/scsi/wd33c93.c6
-rw-r--r--drivers/scsi/wd33c93.h2
-rw-r--r--drivers/scsi/wd7000.c2
-rw-r--r--drivers/serial/Kconfig8
-rw-r--r--drivers/serial/amba-pl011.c26
-rw-r--r--drivers/serial/crisv10.c2
-rw-r--r--drivers/serial/s3c2410.c4
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/message.c6
-rw-r--r--drivers/usb/gadget/file_storage.c2
-rw-r--r--drivers/usb/gadget/lh7a40x_udc.c2
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/sl811-hcd.c2
-rw-r--r--drivers/usb/image/Kconfig2
-rw-r--r--drivers/usb/image/microtek.c5
-rw-r--r--drivers/usb/misc/cytherm.c2
-rw-r--r--drivers/usb/misc/emi26.c4
-rw-r--r--drivers/usb/misc/emi62.c4
-rw-r--r--drivers/usb/misc/usbtest.c4
-rw-r--r--drivers/usb/serial/ChangeLog.history2
-rw-r--r--drivers/usb/serial/Kconfig2
-rw-r--r--drivers/usb/serial/ftdi_sio.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.h6
-rw-r--r--drivers/usb/serial/ipaq.c4
-rw-r--r--drivers/usb/storage/isd200.c2
-rw-r--r--drivers/usb/storage/protocol.c2
-rw-r--r--drivers/usb/storage/unusual_devs.h4
-rw-r--r--drivers/video/Kconfig6
-rw-r--r--drivers/video/amifb.c14
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/cyber2000fb.c236
-rw-r--r--drivers/video/geode/video_gx.c2
-rw-r--r--drivers/video/intelfb/intelfbdrv.c2
-rw-r--r--drivers/video/intelfb/intelfbhw.c2
-rw-r--r--drivers/video/omap/Kconfig2
-rw-r--r--drivers/video/pnx4008/sdum.h3
-rw-r--r--drivers/video/s3c2410fb.c4
-rw-r--r--drivers/video/vermilion/vermilion.c4
-rw-r--r--drivers/video/vermilion/vermilion.h2
-rw-r--r--drivers/watchdog/at91rm9200_wdt.c2
-rw-r--r--drivers/watchdog/i6300esb.c6
-rw-r--r--drivers/watchdog/iTCO_vendor_support.c2
-rw-r--r--drivers/watchdog/ks8695_wdt.c2
-rw-r--r--drivers/watchdog/mpc5200_wdt.c3
-rw-r--r--drivers/watchdog/omap_wdt.c2
-rw-r--r--drivers/watchdog/sa1100_wdt.c2
-rw-r--r--drivers/watchdog/w83697hf_wdt.c2
-rw-r--r--drivers/zorro/zorro.ids2
-rw-r--r--fs/Kconfig10
-rw-r--r--fs/autofs/inode.c2
-rw-r--r--fs/autofs/root.c6
-rw-r--r--fs/autofs4/autofs_i.h2
-rw-r--r--fs/autofs4/inode.c4
-rw-r--r--fs/autofs4/root.c4
-rw-r--r--fs/binfmt_elf.c16
-rw-r--r--fs/binfmt_elf_fdpic.c16
-rw-r--r--fs/binfmt_em86.c2
-rw-r--r--fs/binfmt_misc.c2
-rw-r--r--fs/binfmt_script.c2
-rw-r--r--fs/buffer.c3
-rw-r--r--fs/cifs/CHANGES21
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/asn1.c10
-rw-r--r--fs/cifs/cifs_debug.c28
-rw-r--r--fs/cifs/cifsacl.c333
-rw-r--r--fs/cifs/cifsacl.h64
-rw-r--r--fs/cifs/cifsencrypt.c5
-rw-r--r--fs/cifs/cifsfs.c38
-rw-r--r--fs/cifs/cifsfs.h11
-rw-r--r--fs/cifs/cifsglob.h31
-rw-r--r--fs/cifs/cifspdu.h20
-rw-r--r--fs/cifs/cifsproto.h8
-rw-r--r--fs/cifs/cifssmb.c158
-rw-r--r--fs/cifs/connect.c264
-rw-r--r--fs/cifs/dir.c9
-rw-r--r--fs/cifs/export.c3
-rw-r--r--fs/cifs/file.c86
-rw-r--r--fs/cifs/inode.c52
-rw-r--r--fs/cifs/link.c2
-rw-r--r--fs/cifs/misc.c1
-rw-r--r--fs/cifs/netmisc.c33
-rw-r--r--fs/cifs/readdir.c8
-rw-r--r--fs/cifs/sess.c103
-rw-r--r--fs/cifs/smberr.h5
-rw-r--r--fs/cifs/transport.c34
-rw-r--r--fs/cifs/xattr.c19
-rw-r--r--fs/coda/upcall.c2
-rw-r--r--fs/dcache.c4
-rw-r--r--fs/debugfs/inode.c2
-rw-r--r--fs/dlm/user.c2
-rw-r--r--fs/ecryptfs/crypto.c16
-rw-r--r--fs/ecryptfs/keystore.c3
-rw-r--r--fs/efs/namei.c36
-rw-r--r--fs/efs/super.c5
-rw-r--r--fs/eventpoll.c5
-rw-r--r--fs/exec.c16
-rw-r--r--fs/exportfs/expfs.c360
-rw-r--r--fs/ext2/dir.c44
-rw-r--r--fs/ext2/super.c36
-rw-r--r--fs/ext3/inode.c2
-rw-r--r--fs/ext3/super.c37
-rw-r--r--fs/ext3/xattr.c3
-rw-r--r--fs/ext4/super.c37
-rw-r--r--fs/fat/inode.c26
-rw-r--r--fs/fcntl.c5
-rw-r--r--fs/file_table.c5
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/gfs2/ops_export.c83
-rw-r--r--fs/gfs2/ops_fstype.h2
-rw-r--r--fs/inotify.c43
-rw-r--r--fs/ioprio.c9
-rw-r--r--fs/isofs/export.c69
-rw-r--r--fs/isofs/inode.c2
-rw-r--r--fs/isofs/isofs.h2
-rw-r--r--fs/jbd/commit.c8
-rw-r--r--fs/jbd/journal.c67
-rw-r--r--fs/jbd/recovery.c6
-rw-r--r--fs/jbd/transaction.c3
-rw-r--r--fs/jffs2/debug.h8
-rw-r--r--fs/jfs/jfs_dtree.c2
-rw-r--r--fs/jfs/jfs_inode.h7
-rw-r--r--fs/jfs/namei.c35
-rw-r--r--fs/jfs/super.c7
-rw-r--r--fs/libfs.c88
-rw-r--r--fs/namei.c10
-rw-r--r--fs/namespace.c24
-rw-r--r--fs/nfs/delegation.c3
-rw-r--r--fs/nfs/dir.c14
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/inode.c25
-rw-r--r--fs/nfs/nfs4_fs.h4
-rw-r--r--fs/nfs/nfs4proc.c19
-rw-r--r--fs/nfs/nfs4state.c14
-rw-r--r--fs/nfs/nfsroot.c2
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/unlink.c117
-rw-r--r--fs/nfs/write.c17
-rw-r--r--fs/nfsd/export.c8
-rw-r--r--fs/nfsd/nfs4recover.c8
-rw-r--r--fs/nfsd/nfsfh.c67
-rw-r--r--fs/nfsd/vfs.c6
-rw-r--r--fs/ntfs/ChangeLog4
-rw-r--r--fs/ntfs/namei.c77
-rw-r--r--fs/ntfs/ntfs.h2
-rw-r--r--fs/ntfs/sysctl.c2
-rw-r--r--fs/ntfs/sysctl.h2
-rw-r--r--fs/ocfs2/cluster/heartbeat.c2
-rw-r--r--fs/ocfs2/cluster/masklog.h2
-rw-r--r--fs/ocfs2/dcache.c2
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c10
-rw-r--r--fs/ocfs2/export.c67
-rw-r--r--fs/ocfs2/export.h2
-rw-r--r--fs/open.c4
-rw-r--r--fs/pnode.h1
-rw-r--r--fs/proc/array.c32
-rw-r--r--fs/proc/base.c242
-rw-r--r--fs/proc/inode.c2
-rw-r--r--fs/proc/proc_misc.c3
-rw-r--r--fs/proc/root.c83
-rw-r--r--fs/reiserfs/bitmap.c111
-rw-r--r--fs/reiserfs/inode.c70
-rw-r--r--fs/reiserfs/journal.c24
-rw-r--r--fs/reiserfs/prints.c10
-rw-r--r--fs/reiserfs/resize.c15
-rw-r--r--fs/reiserfs/stree.c6
-rw-r--r--fs/reiserfs/super.c23
-rw-r--r--fs/reiserfs/xattr.c5
-rw-r--r--fs/select.c5
-rw-r--r--fs/super.c38
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--fs/xattr.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c206
-rw-r--r--fs/xfs/linux-2.6/xfs_export.h50
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c24
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h2
-rw-r--r--fs/xfs/xfs_dmops.c21
-rw-r--r--fs/xfs/xfs_fs.h29
-rw-r--r--fs/xfs/xfs_qmops.c22
-rw-r--r--fs/xfs/xfs_vfsops.c9
-rw-r--r--fs/xfs/xfs_vfsops.h4
-rw-r--r--fs/xfs/xfs_vnodeops.c13
-rw-r--r--fs/xfs/xfs_vnodeops.h2
-rw-r--r--include/acpi/achware.h4
-rw-r--r--include/acpi/acpi_bus.h2
-rw-r--r--include/acpi/acpixf.h2
-rw-r--r--include/acpi/actbl1.h27
-rw-r--r--include/acpi/processor.h5
-rw-r--r--include/asm-alpha/bitops.h4
-rw-r--r--include/asm-alpha/ide.h1
-rw-r--r--include/asm-alpha/scatterlist.h5
-rw-r--r--include/asm-alpha/tlbflush.h11
-rw-r--r--include/asm-arm/arch-aaec2000/aaec2000.h4
-rw-r--r--include/asm-arm/arch-ixp4xx/io.h3
-rw-r--r--include/asm-arm/bitops.h4
-rw-r--r--include/asm-arm/dma-mapping.h2
-rw-r--r--include/asm-arm/ide.h1
-rw-r--r--include/asm-arm/scatterlist.h5
-rw-r--r--include/asm-arm/tlbflush.h5
-rw-r--r--include/asm-avr32/bitops.h4
-rw-r--r--include/asm-avr32/scatterlist.h5
-rw-r--r--include/asm-avr32/tlbflush.h7
-rw-r--r--include/asm-blackfin/bf5xx_timers.h209
-rw-r--r--include/asm-blackfin/bfin-global.h4
-rw-r--r--include/asm-blackfin/bitops.h4
-rw-r--r--include/asm-blackfin/dma.h7
-rw-r--r--include/asm-blackfin/gpio.h3
-rw-r--r--include/asm-blackfin/gptimers.h210
-rw-r--r--include/asm-blackfin/ide.h1
-rw-r--r--include/asm-blackfin/mach-bf527/anomaly.h8
-rw-r--r--include/asm-blackfin/mach-bf527/bf527.h127
-rw-r--r--include/asm-blackfin/mach-bf527/bfin_serial_5xx.h152
-rw-r--r--include/asm-blackfin/mach-bf527/blackfin.h78
-rw-r--r--include/asm-blackfin/mach-bf527/cdefBF52x_base.h19
-rw-r--r--include/asm-blackfin/mach-bf527/defBF527.h4
-rw-r--r--include/asm-blackfin/mach-bf527/defBF52x_base.h9
-rw-r--r--include/asm-blackfin/mach-bf527/dma.h60
-rw-r--r--include/asm-blackfin/mach-bf527/irq.h263
-rw-r--r--include/asm-blackfin/mach-bf527/mem_init.h337
-rw-r--r--include/asm-blackfin/mach-bf527/mem_map.h98
-rw-r--r--include/asm-blackfin/mach-bf527/portmux.h205
-rw-r--r--include/asm-blackfin/mach-bf548/defBF549.h2
-rw-r--r--include/asm-blackfin/mach-bf548/defBF54x_base.h6
-rw-r--r--include/asm-blackfin/mach-bf548/dma.h2
-rw-r--r--include/asm-blackfin/scatterlist.h5
-rw-r--r--include/asm-blackfin/system.h4
-rw-r--r--include/asm-blackfin/tlbflush.h6
-rw-r--r--include/asm-cris/arch-v32/ide.h2
-rw-r--r--include/asm-cris/bitops.h4
-rw-r--r--include/asm-cris/posix_types.h2
-rw-r--r--include/asm-cris/scatterlist.h5
-rw-r--r--include/asm-cris/tlbflush.h7
-rw-r--r--include/asm-frv/bitops.h4
-rw-r--r--include/asm-frv/scatterlist.h5
-rw-r--r--include/asm-frv/tlbflush.h2
-rw-r--r--include/asm-generic/bitops.h4
-rw-r--r--include/asm-generic/bitops/atomic.h27
-rw-r--r--include/asm-generic/bitops/non-atomic.h29
-rw-r--r--include/asm-generic/vmlinux.lds.h7
-rw-r--r--include/asm-h8300/bitops.h5
-rw-r--r--include/asm-h8300/scatterlist.h5
-rw-r--r--include/asm-h8300/system.h3
-rw-r--r--include/asm-h8300/tlbflush.h6
-rw-r--r--include/asm-ia64/bitops.h4
-rw-r--r--include/asm-ia64/cacheflush.h2
-rw-r--r--include/asm-ia64/ide.h1
-rw-r--r--include/asm-ia64/meminit.h2
-rw-r--r--include/asm-ia64/pgtable.h2
-rw-r--r--include/asm-ia64/scatterlist.h5
-rw-r--r--include/asm-ia64/smp.h2
-rw-r--r--include/asm-ia64/spinlock.h2
-rw-r--r--include/asm-ia64/tlbflush.h13
-rw-r--r--include/asm-m32r/bitops.h4
-rw-r--r--include/asm-m32r/ide.h1
-rw-r--r--include/asm-m32r/pgtable.h2
-rw-r--r--include/asm-m32r/scatterlist.h5
-rw-r--r--include/asm-m32r/tlbflush.h3
-rw-r--r--include/asm-m68k/bitops.h4
-rw-r--r--include/asm-m68k/ide.h2
-rw-r--r--include/asm-m68k/scatterlist.h5
-rw-r--r--include/asm-m68k/tlbflush.h10
-rw-r--r--include/asm-m68knommu/bitops.h4
-rw-r--r--include/asm-m68knommu/scatterlist.h5
-rw-r--r--include/asm-m68knommu/system.h3
-rw-r--r--include/asm-m68knommu/tlbflush.h6
-rw-r--r--include/asm-mips/bitops.h4
-rw-r--r--include/asm-mips/fpu.h2
-rw-r--r--include/asm-mips/gt64120.h5
-rw-r--r--include/asm-mips/i8253.h6
-rw-r--r--include/asm-mips/ip32/crime.h3
-rw-r--r--include/asm-mips/ip32/mace.h3
-rw-r--r--include/asm-mips/mach-generic/ide.h1
-rw-r--r--include/asm-mips/pci/bridge.h2
-rw-r--r--include/asm-mips/scatterlist.h5
-rw-r--r--include/asm-mips/sibyte/sb1250.h2
-rw-r--r--include/asm-mips/sni.h2
-rw-r--r--include/asm-mips/time.h5
-rw-r--r--include/asm-mips/tlbflush.h7
-rw-r--r--include/asm-parisc/Kbuild2
-rw-r--r--include/asm-parisc/bitops.h4
-rw-r--r--include/asm-parisc/ide.h1
-rw-r--r--include/asm-parisc/io.h2
-rw-r--r--include/asm-parisc/page.h4
-rw-r--r--include/asm-parisc/pci.h2
-rw-r--r--include/asm-parisc/pdc.h308
-rw-r--r--include/asm-parisc/pgtable.h42
-rw-r--r--include/asm-parisc/prefetch.h4
-rw-r--r--include/asm-parisc/rtc.h4
-rw-r--r--include/asm-parisc/scatterlist.h5
-rw-r--r--include/asm-parisc/semaphore.h10
-rw-r--r--include/asm-parisc/tlbflush.h4
-rw-r--r--include/asm-parisc/unistd.h3
-rw-r--r--include/asm-powerpc/bitops.h4
-rw-r--r--include/asm-powerpc/ide.h3
-rw-r--r--include/asm-powerpc/io.h2
-rw-r--r--include/asm-powerpc/iommu.h2
-rw-r--r--include/asm-powerpc/mmu_context.h2
-rw-r--r--include/asm-powerpc/mpc52xx.h9
-rw-r--r--include/asm-powerpc/paca.h2
-rw-r--r--include/asm-powerpc/scatterlist.h5
-rw-r--r--include/asm-powerpc/tlbflush.h11
-rw-r--r--include/asm-ppc/mmu_context.h3
-rw-r--r--include/asm-ppc/system.h1
-rw-r--r--include/asm-s390/bitops.h4
-rw-r--r--include/asm-s390/cpu.h25
-rw-r--r--include/asm-s390/mmu_context.h50
-rw-r--r--include/asm-s390/page.h4
-rw-r--r--include/asm-s390/pgalloc.h250
-rw-r--r--include/asm-s390/pgtable.h429
-rw-r--r--include/asm-s390/processor.h20
-rw-r--r--include/asm-s390/scatterlist.h5
-rw-r--r--include/asm-s390/tlb.h129
-rw-r--r--include/asm-s390/tlbflush.h159
-rw-r--r--include/asm-sh/bitops.h5
-rw-r--r--include/asm-sh/scatterlist.h5
-rw-r--r--include/asm-sh/se7751.h2
-rw-r--r--include/asm-sh/systemh7751.h2
-rw-r--r--include/asm-sh/tlbflush.h6
-rw-r--r--include/asm-sh64/bitops.h5
-rw-r--r--include/asm-sh64/ide.h1
-rw-r--r--include/asm-sh64/scatterlist.h5
-rw-r--r--include/asm-sh64/system.h3
-rw-r--r--include/asm-sh64/tlbflush.h4
-rw-r--r--include/asm-sparc/bitops.h4
-rw-r--r--include/asm-sparc/ide.h1
-rw-r--r--include/asm-sparc/scatterlist.h5
-rw-r--r--include/asm-sparc/tlbflush.h6
-rw-r--r--include/asm-sparc64/bitops.h4
-rw-r--r--include/asm-sparc64/ide.h1
-rw-r--r--include/asm-sparc64/scatterlist.h5
-rw-r--r--include/asm-sparc64/smp.h2
-rw-r--r--include/asm-sparc64/tlbflush.h7
-rw-r--r--include/asm-um/bitops.h4
-rw-r--r--include/asm-um/tlbflush.h6
-rw-r--r--include/asm-v850/bitops.h3
-rw-r--r--include/asm-v850/scatterlist.h5
-rw-r--r--include/asm-v850/system.h3
-rw-r--r--include/asm-v850/tlbflush.h6
-rw-r--r--include/asm-x86/acpi_32.h6
-rw-r--r--include/asm-x86/bitops_32.h4
-rw-r--r--include/asm-x86/bitops_64.h4
-rw-r--r--include/asm-x86/bootparam.h9
-rw-r--r--include/asm-x86/cacheflush.h1
-rw-r--r--include/asm-x86/compat.h6
-rw-r--r--include/asm-x86/desc_64.h30
-rw-r--r--include/asm-x86/device.h3
-rw-r--r--include/asm-x86/dma-mapping_32.h4
-rw-r--r--include/asm-x86/geode.h2
-rw-r--r--include/asm-x86/hpet.h7
-rw-r--r--include/asm-x86/ide.h1
-rw-r--r--include/asm-x86/io_apic_64.h2
-rw-r--r--include/asm-x86/ipi.h2
-rw-r--r--include/asm-x86/irq_32.h3
-rw-r--r--include/asm-x86/msr-index.h36
-rw-r--r--include/asm-x86/pgtable_32.h5
-rw-r--r--include/asm-x86/pgtable_64.h2
-rw-r--r--include/asm-x86/processor_32.h16
-rw-r--r--include/asm-x86/processor_64.h16
-rw-r--r--include/asm-x86/proto.h2
-rw-r--r--include/asm-x86/ptrace_32.h2
-rw-r--r--include/asm-x86/ptrace_64.h2
-rw-r--r--include/asm-x86/scatterlist_32.h5
-rw-r--r--include/asm-x86/scatterlist_64.h5
-rw-r--r--include/asm-x86/smp_32.h8
-rw-r--r--include/asm-x86/smp_64.h11
-rw-r--r--include/asm-x86/system_32.h1
-rw-r--r--include/asm-x86/tlbflush_32.h7
-rw-r--r--include/asm-x86/tlbflush_64.h9
-rw-r--r--include/asm-x86/topology_32.h4
-rw-r--r--include/asm-x86/topology_64.h6
-rw-r--r--include/asm-xtensa/bitops.h4
-rw-r--r--include/asm-xtensa/scatterlist.h5
-rw-r--r--include/asm-xtensa/tlbflush.h11
-rw-r--r--include/linux/Kbuild1
-rw-r--r--include/linux/acpi.h26
-rw-r--r--include/linux/audit.h19
-rw-r--r--include/linux/bitmap.h1
-rw-r--r--include/linux/bitops.h8
-rw-r--r--include/linux/capability.h6
-rw-r--r--include/linux/cdrom.h6
-rw-r--r--include/linux/cgroup.h327
-rw-r--r--include/linux/cgroup_subsys.h38
-rw-r--r--include/linux/cgroupstats.h70
-rw-r--r--include/linux/cpu_acct.h14
-rw-r--r--include/linux/cpuidle.h180
-rw-r--r--include/linux/cpuset.h17
-rw-r--r--include/linux/crypto.h2
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/delayacct.h13
-rw-r--r--include/linux/device-mapper.h3
-rw-r--r--include/linux/dm-ioctl.h5
-rw-r--r--include/linux/dmar.h86
-rw-r--r--include/linux/efi.h2
-rw-r--r--include/linux/efs_fs.h6
-rw-r--r--include/linux/exportfs.h141
-rw-r--r--include/linux/ext2_fs.h1
-rw-r--r--include/linux/fs.h12
-rw-r--r--include/linux/fsnotify.h9
-rw-r--r--include/linux/hid.h4
-rw-r--r--include/linux/i8042.h35
-rw-r--r--include/linux/ide.h111
-rw-r--r--include/linux/init_task.h12
-rw-r--r--include/linux/inotify.h2
-rw-r--r--include/linux/input.h47
-rw-r--r--include/linux/ipc.h3
-rw-r--r--include/linux/ipmi_smi.h2
-rw-r--r--include/linux/jbd.h18
-rw-r--r--include/linux/kexec.h2
-rw-r--r--include/linux/keyboard.h11
-rw-r--r--include/linux/linkage.h6
-rw-r--r--include/linux/list.h3
-rw-r--r--include/linux/lockdep.h8
-rw-r--r--include/linux/magic.h1
-rw-r--r--include/linux/marker.h129
-rw-r--r--include/linux/memory.h31
-rw-r--r--include/linux/mempolicy.h12
-rw-r--r--include/linux/module.h12
-rw-r--r--include/linux/msg.h1
-rw-r--r--include/linux/net.h4
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--include/linux/nfs_fs.h8
-rw-r--r--include/linux/notifier.h17
-rw-r--r--include/linux/nsproxy.h50
-rw-r--r--include/linux/of.h2
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--include/linux/phantom.h6
-rw-r--r--include/linux/pid.h61
-rw-r--r--include/linux/pid_namespace.h26
-rw-r--r--include/linux/prefetch.h9
-rw-r--r--include/linux/prio_heap.h58
-rw-r--r--include/linux/proc_fs.h19
-rw-r--r--include/linux/reiserfs_fs.h40
-rw-r--r--include/linux/reiserfs_fs_sb.h4
-rw-r--r--include/linux/scatterlist.h202
-rw-r--r--include/linux/sched.h171
-rw-r--r--include/linux/security.h17
-rw-r--r--include/linux/sem.h1
-rw-r--r--include/linux/shm.h1
-rw-r--r--include/linux/skbuff.h15
-rw-r--r--include/linux/socket.h1
-rw-r--r--include/linux/tick.h9
-rw-r--r--include/linux/types.h3
-rw-r--r--include/linux/uinput.h4
-rw-r--r--include/linux/videodev.h42
-rw-r--r--include/linux/videodev2.h92
-rw-r--r--include/linux/vt.h12
-rw-r--r--include/linux/workqueue.h49
-rw-r--r--include/media/v4l2-dev.h5
-rw-r--r--include/net/9p/9p.h4
-rw-r--r--include/net/bluetooth/hci.h604
-rw-r--r--include/net/bluetooth/hci_core.h13
-rw-r--r--include/net/bluetooth/l2cap.h37
-rw-r--r--include/net/irda/irttp.h4
-rw-r--r--include/net/scm.h4
-rw-r--r--include/video/sstfb.h1
-rw-r--r--include/video/tdfx.h2
-rw-r--r--init/Kconfig55
-rw-r--r--init/main.c13
-rw-r--r--ipc/mqueue.c15
-rw-r--r--ipc/msg.c253
-rw-r--r--ipc/sem.c308
-rw-r--r--ipc/shm.c316
-rw-r--r--ipc/util.c506
-rw-r--r--ipc/util.h168
-rw-r--r--kernel/Kconfig.instrumentation49
-rw-r--r--kernel/Makefile11
-rw-r--r--kernel/audit.c87
-rw-r--r--kernel/audit.h34
-rw-r--r--kernel/audit_tree.c903
-rw-r--r--kernel/auditfilter.c64
-rw-r--r--kernel/auditsc.c229
-rw-r--r--kernel/capability.c15
-rw-r--r--kernel/cgroup.c2805
-rw-r--r--kernel/cgroup_debug.c97
-rw-r--r--kernel/cpu.c12
-rw-r--r--kernel/cpu_acct.c186
-rw-r--r--kernel/cpuset.c1601
-rw-r--r--kernel/die_notifier.c38
-rw-r--r--kernel/exit.c157
-rw-r--r--kernel/fork.c133
-rw-r--r--kernel/futex.c26
-rw-r--r--kernel/futex_compat.c3
-rw-r--r--kernel/hrtimer.c4
-rw-r--r--kernel/kexec.c168
-rw-r--r--kernel/lockdep.c24
-rw-r--r--kernel/marker.c525
-rw-r--r--kernel/module.c30
-rw-r--r--kernel/notifier.c539
-rw-r--r--kernel/ns_cgroup.c100
-rw-r--r--kernel/nsproxy.c62
-rw-r--r--kernel/panic.c2
-rw-r--r--kernel/pid.c353
-rw-r--r--kernel/posix-cpu-timers.c12
-rw-r--r--kernel/posix-timers.c4
-rw-r--r--kernel/power/snapshot.c9
-rw-r--r--kernel/ptrace.c5
-rw-r--r--kernel/rtmutex-debug.c15
-rw-r--r--kernel/rtmutex.c2
-rw-r--r--kernel/sched.c275
-rw-r--r--kernel/signal.c66
-rw-r--r--kernel/softlockup.c2
-rw-r--r--kernel/sys.c586
-rw-r--r--kernel/sysctl.c4
-rw-r--r--kernel/sysctl_check.c2
-rw-r--r--kernel/taskstats.c69
-rw-r--r--kernel/time/clocksource.c22
-rw-r--r--kernel/time/tick-sched.c16
-rw-r--r--kernel/timer.c7
-rw-r--r--kernel/workqueue.c38
-rw-r--r--lib/Kconfig.debug12
-rw-r--r--lib/Makefile2
-rw-r--r--lib/argv_split.c3
-rw-r--r--lib/hweight.c2
-rw-r--r--lib/kernel_lock.c2
-rw-r--r--lib/kobject_uevent.c2
-rw-r--r--lib/percpu_counter.c5
-rw-r--r--lib/prio_heap.c70
-rw-r--r--lib/spinlock_debug.c8
-rw-r--r--lib/swiotlb.c2
-rw-r--r--mm/Kconfig2
-rw-r--r--mm/filemap.c2
-rw-r--r--mm/hugetlb.c2
-rw-r--r--mm/memory.c5
-rw-r--r--mm/memory_hotplug.c50
-rw-r--r--mm/mempolicy.c5
-rw-r--r--mm/mempool.c2
-rw-r--r--mm/migrate.c5
-rw-r--r--mm/mmap.c11
-rw-r--r--mm/mprotect.c6
-rw-r--r--mm/nommu.c3
-rw-r--r--mm/oom_kill.c17
-rw-r--r--mm/page-writeback.c2
-rw-r--r--mm/page_alloc.c8
-rw-r--r--mm/prio_tree.c2
-rw-r--r--mm/shmem.c37
-rw-r--r--mm/slab.c6
-rw-r--r--mm/slub.c118
-rw-r--r--mm/swap.c2
-rw-r--r--mm/vmalloc.c6
-rw-r--r--mm/vmscan.c2
-rw-r--r--net/9p/Kconfig2
-rw-r--r--net/ax25/ax25_ds_in.c2
-rw-r--r--net/ax25/ax25_ds_subr.c2
-rw-r--r--net/bluetooth/bnep/core.c2
-rw-r--r--net/bluetooth/bnep/netdev.c2
-rw-r--r--net/bluetooth/hci_conn.c82
-rw-r--r--net/bluetooth/hci_core.c70
-rw-r--r--net/bluetooth/hci_event.c1651
-rw-r--r--net/bluetooth/hci_sock.c2
-rw-r--r--net/bluetooth/hci_sysfs.c37
-rw-r--r--net/bluetooth/hidp/core.c14
-rw-r--r--net/bluetooth/l2cap.c306
-rw-r--r--net/bluetooth/rfcomm/core.c60
-rw-r--r--net/bluetooth/rfcomm/tty.c25
-rw-r--r--net/bluetooth/sco.c12
-rw-r--r--net/bridge/netfilter/ebtables.c2
-rw-r--r--net/core/dev.c6
-rw-r--r--net/core/filter.c3
-rw-r--r--net/core/gen_estimator.c2
-rw-r--r--net/core/neighbour.c3
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/core/pktgen.c18
-rw-r--r--net/core/rtnetlink.c8
-rw-r--r--net/core/scm.c4
-rw-r--r--net/core/skbuff.c4
-rw-r--r--net/core/sock.c2
-rw-r--r--net/dccp/diag.c1
-rw-r--r--net/dccp/ipv4.c4
-rw-r--r--net/dccp/ipv6.c4
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c13
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c8
-rw-r--r--net/ieee80211/ieee80211_wx.c2
-rw-r--r--net/ipv4/Kconfig2
-rw-r--r--net/ipv4/fib_trie.c2
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/inet_diag.c7
-rw-r--r--net/ipv4/inet_hashtables.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c6
-rw-r--r--net/ipv4/sysctl_net_ipv4.c4
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_diag.c1
-rw-r--r--net/ipv4/udp.c5
-rw-r--r--net/ipv6/ah6.c1
-rw-r--r--net/ipv6/esp6.c1
-rw-r--r--net/ipv6/inet6_hashtables.c2
-rw-r--r--net/irda/discovery.c2
-rw-r--r--net/irda/iriap.c2
-rw-r--r--net/irda/iriap_event.c2
-rw-r--r--net/irda/irias_object.c2
-rw-r--r--net/irda/irlan/irlan_client.c2
-rw-r--r--net/irda/irlan/irlan_client_event.c2
-rw-r--r--net/irda/irlan/irlan_common.c2
-rw-r--r--net/irda/irlan/irlan_eth.c2
-rw-r--r--net/irda/irlan/irlan_event.c2
-rw-r--r--net/irda/irlan/irlan_filter.c2
-rw-r--r--net/irda/irlan/irlan_provider.c2
-rw-r--r--net/irda/irlan/irlan_provider_event.c2
-rw-r--r--net/irda/irlap_event.c2
-rw-r--r--net/irda/irlap_frame.c2
-rw-r--r--net/irda/irlmp.c2
-rw-r--r--net/irda/irlmp_event.c2
-rw-r--r--net/irda/irlmp_frame.c2
-rw-r--r--net/irda/irmod.c2
-rw-r--r--net/irda/irqueue.c2
-rw-r--r--net/irda/irsysctl.c2
-rw-r--r--net/irda/irttp.c2
-rw-r--r--net/irda/timer.c2
-rw-r--r--net/irda/wrapper.c2
-rw-r--r--net/iucv/iucv.c2
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/ieee80211_sta.c55
-rw-r--r--net/mac80211/wep.c8
-rw-r--r--net/netfilter/xt_CONNMARK.c2
-rw-r--r--net/netfilter/xt_connbytes.c2
-rw-r--r--net/netfilter/xt_connmark.c2
-rw-r--r--net/netfilter/xt_limit.c4
-rw-r--r--net/packet/af_packet.c5
-rw-r--r--net/rfkill/rfkill-input.c12
-rw-r--r--net/sched/Kconfig10
-rw-r--r--net/sched/em_meta.c2
-rw-r--r--net/sched/sch_generic.c26
-rw-r--r--net/sched/sch_teql.c6
-rw-r--r--net/sctp/auth.c3
-rw-r--r--net/sctp/sm_make_chunk.c6
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c10
-rw-r--r--net/sunrpc/sched.c2
-rw-r--r--net/sunrpc/xdr.c2
-rw-r--r--net/unix/af_unix.c6
-rw-r--r--net/xfrm/xfrm_algo.c4
-rw-r--r--samples/Kconfig16
-rw-r--r--samples/Makefile3
-rw-r--r--samples/markers/Makefile4
-rw-r--r--samples/markers/marker-example.c54
-rw-r--r--samples/markers/probe-example.c98
-rw-r--r--scripts/Kbuild.include11
-rw-r--r--scripts/basic/docproc.c11
-rwxr-xr-xscripts/checkstack.pl5
-rw-r--r--scripts/kconfig/Makefile2
-rw-r--r--scripts/kconfig/menu.c35
-rw-r--r--scripts/kconfig/qconf.cc4
-rw-r--r--scripts/mod/modpost.c3
-rw-r--r--scripts/package/builddeb2
-rw-r--r--security/commoncap.c26
-rw-r--r--sound/core/seq/seq_midi_emul.c8
-rw-r--r--sound/drivers/opl3/opl3_midi.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c1
-rw-r--r--sound/isa/es18xx.c4
-rw-r--r--sound/mips/au1x00.c8
-rw-r--r--sound/pci/au88x0/au88x0.c2
-rw-r--r--sound/ppc/beep.c4
-rw-r--r--sound/soc/soc-core.c2
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/synth/emux/emux_synth.c2
-rw-r--r--sound/usb/caiaq/caiaq-input.c9
1890 files changed, 46493 insertions, 19438 deletions
diff --git a/.gitignore b/.gitignore
index 22fb8fa9bc3..8d14531846b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
*.s
*.ko
*.so
+*.so.dbg
*.mod.c
*.i
*.lst
diff --git a/CREDITS b/CREDITS
index 99566b1a6ee..ee909f2cc49 100644
--- a/CREDITS
+++ b/CREDITS
@@ -959,7 +959,7 @@ S: 2037 Walnut #6
S: Boulder, Colorado 80302
S: USA
-N: Heiko Eissfeldt
+N: Heiko Eißfeldt
E: heiko@colossus.escape.de heiko@unifix.de
D: verify_area stuff, generic SCSI fixes
D: SCSI Programming HOWTO
@@ -1988,8 +1988,8 @@ N: Volker Lendecke
E: vl@kki.org
D: Kernel smbfs (to mount WfW, NT and OS/2 network drives.)
D: NCP filesystem support (to mount NetWare volumes)
-S: Von Ossietzky Str. 12
-S: 37085 Goettingen
+S: Von-Ossietzky-Str. 12
+S: 37085 Göttingen
S: Germany
N: Kevin Lentin
@@ -2431,11 +2431,11 @@ S: 12725 SW Millikan Way, Suite 400
S: Beaverton, Oregon 97005
S: USA
-N: Eberhard Moenkeberg
+N: Eberhard Mönkeberg
E: emoenke@gwdg.de
D: CDROM driver "sbpcd" (Matsushita/Panasonic/Soundblaster)
-S: Ruhstrathoehe 2 b.
-S: D-37085 Goettingen
+S: Ruhstrathöhe 2 b.
+S: D-37085 Göttingen
S: Germany
N: Thomas Molina
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 1a7f53068ec..054a7ecf64c 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -165,7 +165,7 @@ quiet_cmd_db2man = MAN $@
@touch $@
###
-# Rules to generate postscripts and PNG imgages from .fig format files
+# Rules to generate postscripts and PNG images from .fig format files
quiet_cmd_fig2eps = FIG2EPS $@
cmd_fig2eps = fig2dev -Leps $< $@
diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl
index d3290c46af5..aa38cc5692a 100644
--- a/Documentation/DocBook/kernel-api.tmpl
+++ b/Documentation/DocBook/kernel-api.tmpl
@@ -46,7 +46,7 @@
<sect1><title>Atomic and pointer manipulation</title>
!Iinclude/asm-x86/atomic_32.h
-!Iinclude/asm-x86/unaligned_32.h
+!Iinclude/asm-x86/unaligned.h
</sect1>
<sect1><title>Delaying, scheduling, and timer routines</title>
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl
index 6fbc41d98c1..957cf5c2683 100644
--- a/Documentation/DocBook/mtdnand.tmpl
+++ b/Documentation/DocBook/mtdnand.tmpl
@@ -282,7 +282,7 @@ int __init board_init (void)
goto out;
}
- /* map physical adress */
+ /* map physical address */
baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
if(!baseaddr){
printk("Ioremap to access NAND chip failed\n");
@@ -306,7 +306,7 @@ int __init board_init (void)
this->dev_ready = board_dev_ready;
this->eccmode = NAND_ECC_SOFT;
- /* Scan to find existance of the device */
+ /* Scan to find existence of the device */
if (nand_scan (board_mtd, 1)) {
err = -ENXIO;
goto out_ior;
@@ -340,7 +340,7 @@ static void __exit board_cleanup (void)
/* Release resources, unregister device */
nand_release (board_mtd);
- /* unmap physical adress */
+ /* unmap physical address */
iounmap((void *)baseaddr);
/* Free the MTD device structure */
diff --git a/Documentation/Intel-IOMMU.txt b/Documentation/Intel-IOMMU.txt
new file mode 100644
index 00000000000..c2321903aa0
--- /dev/null
+++ b/Documentation/Intel-IOMMU.txt
@@ -0,0 +1,115 @@
+Linux IOMMU Support
+===================
+
+The architecture spec can be obtained from the below location.
+
+http://www.intel.com/technology/virtualization/
+
+This guide gives a quick cheat sheet for some basic understanding.
+
+Some Keywords
+
+DMAR - DMA remapping
+DRHD - DMA Engine Reporting Structure
+RMRR - Reserved memory Region Reporting Structure
+ZLR - Zero length reads from PCI devices
+IOVA - IO Virtual address.
+
+Basic stuff
+-----------
+
+ACPI enumerates and lists the different DMA engines in the platform, and
+device scope relationships between PCI devices and which DMA engine controls
+them.
+
+What is RMRR?
+-------------
+
+There are some devices the BIOS controls, for e.g USB devices to perform
+PS2 emulation. The regions of memory used for these devices are marked
+reserved in the e820 map. When we turn on DMA translation, DMA to those
+regions will fail. Hence BIOS uses RMRR to specify these regions along with
+devices that need to access these regions. OS is expected to setup
+unity mappings for these regions for these devices to access these regions.
+
+How is IOVA generated?
+---------------------
+
+Well behaved drivers call pci_map_*() calls before sending command to device
+that needs to perform DMA. Once DMA is completed and mapping is no longer
+required, device performs a pci_unmap_*() calls to unmap the region.
+
+The Intel IOMMU driver allocates a virtual address per domain. Each PCIE
+device has its own domain (hence protection). Devices under p2p bridges
+share the virtual address with all devices under the p2p bridge due to
+transaction id aliasing for p2p bridges.
+
+IOVA generation is pretty generic. We used the same technique as vmalloc()
+but these are not global address spaces, but separate for each domain.
+Different DMA engines may support different number of domains.
+
+We also allocate gaurd pages with each mapping, so we can attempt to catch
+any overflow that might happen.
+
+
+Graphics Problems?
+------------------
+If you encounter issues with graphics devices, you can try adding
+option intel_iommu=igfx_off to turn off the integrated graphics engine.
+
+If it happens to be a PCI device included in the INCLUDE_ALL Engine,
+then try enabling CONFIG_DMAR_GFX_WA to setup a 1-1 map. We hear
+graphics drivers may be in process of using DMA api's in the near
+future and at that time this option can be yanked out.
+
+Some exceptions to IOVA
+-----------------------
+Interrupt ranges are not address translated, (0xfee00000 - 0xfeefffff).
+The same is true for peer to peer transactions. Hence we reserve the
+address from PCI MMIO ranges so they are not allocated for IOVA addresses.
+
+
+Fault reporting
+---------------
+When errors are reported, the DMA engine signals via an interrupt. The fault
+reason and device that caused it with fault reason is printed on console.
+
+See below for sample.
+
+
+Boot Message Sample
+-------------------
+
+Something like this gets printed indicating presence of DMAR tables
+in ACPI.
+
+ACPI: DMAR (v001 A M I OEMDMAR 0x00000001 MSFT 0x00000097) @ 0x000000007f5b5ef0
+
+When DMAR is being processed and initialized by ACPI, prints DMAR locations
+and any RMRR's processed.
+
+ACPI DMAR:Host address width 36
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed90000
+ACPI DMAR:DRHD (flags: 0x00000000)base: 0x00000000fed91000
+ACPI DMAR:DRHD (flags: 0x00000001)base: 0x00000000fed93000
+ACPI DMAR:RMRR base: 0x00000000000ed000 end: 0x00000000000effff
+ACPI DMAR:RMRR base: 0x000000007f600000 end: 0x000000007fffffff
+
+When DMAR is enabled for use, you will notice..
+
+PCI-DMA: Using DMAR IOMMU
+
+Fault reporting
+---------------
+
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+DMAR:[DMA Write] Request device [00:02.0] fault addr 6df084000
+DMAR:[fault reason 05] PTE Write access is not set
+
+TBD
+----
+
+- For compatibility testing, could use unity map domain for all devices, just
+ provide a 1-1 for all useful memory under a single domain for all devices.
+- API for paravirt ops for abstracting functionlity for VMM folks.
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 19e7f65c269..34e06d2f194 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -67,7 +67,7 @@ kernel patches.
20: Check that it all passes `make headers_check'.
21: Has been checked with injection of at least slab and page-allocation
- fauilures. See Documentation/fault-injection/.
+ failures. See Documentation/fault-injection/.
If the new code is substantial, addition of subsystem-specific fault
injection might be appropriate.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index d7e26427e42..24f2eb40cae 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -36,8 +36,7 @@ Linux 2.4:
If the code area has a general maintainer then please submit it to
the maintainer listed in MAINTAINERS in the kernel file. If the
maintainer does not respond or you cannot find the appropriate
- maintainer then please contact Marcelo Tosatti
- <marcelo.tosatti@cyclades.com>.
+ maintainer then please contact Willy Tarreau <w@1wt.eu>.
Linux 2.6:
The same rules apply as 2.4 except that you should follow linux-kernel
diff --git a/Documentation/accounting/cgroupstats.txt b/Documentation/accounting/cgroupstats.txt
new file mode 100644
index 00000000000..eda40fd39ca
--- /dev/null
+++ b/Documentation/accounting/cgroupstats.txt
@@ -0,0 +1,27 @@
+Control Groupstats is inspired by the discussion at
+http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as
+suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263.
+
+Per cgroup statistics infrastructure re-uses code from the taskstats
+interface. A new set of cgroup operations are registered with commands
+and attributes specific to cgroups. It should be very easy to
+extend per cgroup statistics, by adding members to the cgroupstats
+structure.
+
+The current model for cgroupstats is a pull, a push model (to post
+statistics on interesting events), should be very easy to add. Currently
+user space requests for statistics by passing the cgroup path.
+Statistics about the state of all the tasks in the cgroup is returned to
+user space.
+
+NOTE: We currently rely on delay accounting for extracting information
+about tasks blocked on I/O. If CONFIG_TASK_DELAY_ACCT is disabled, this
+information will not be available.
+
+To extract cgroup statistics a utility very similar to getdelays.c
+has been developed, the sample output of the utility is shown below
+
+~/balbir/cgroupstats # ./getdelays -C "/cgroup/a"
+sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0
+~/balbir/cgroupstats # ./getdelays -C "/cgroup"
+sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2
diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
index 37f4edcc5d8..3ed82383efe 100644
--- a/Documentation/arm/Samsung-S3C24XX/DMA.txt
+++ b/Documentation/arm/Samsung-S3C24XX/DMA.txt
@@ -5,7 +5,7 @@ Introduction
------------
The kernel provides an interface to manage DMA transfers
- using the DMA channels in the cpu, so that the central
+ using the DMA channels in the CPU, so that the central
duty of managing channel mappings, and programming the
channel generators is in one place.
@@ -17,24 +17,24 @@ DMA Channel Ordering
channels to all sources, which means that some devices
have a restricted number of channels that can be used.
- To allow flexibilty for each cpu type and board, the
- dma code can be given an dma ordering structure which
+ To allow flexibility for each CPU type and board, the
+ DMA code can be given a DMA ordering structure which
allows the order of channel search to be specified, as
well as allowing the prohibition of certain claims.
struct s3c24xx_dma_order has a list of channels, and
- each channel within has a slot for a list of dma
- channel numbers. The slots are searched in order, for
- the presence of a dma channel number with DMA_CH_VALID
- orred in.
+ each channel within has a slot for a list of DMA
+ channel numbers. The slots are searched in order for
+ the presence of a DMA channel number with DMA_CH_VALID
+ or-ed in.
If the order has the flag DMA_CH_NEVER set, then after
checking the channel list, the system will return no
found channel, thus denying the request.
A board support file can call s3c24xx_dma_order_set()
- to register an complete ordering set. The routine will
- copy the data, so the original can be discared with
+ to register a complete ordering set. The routine will
+ copy the data, so the original can be discarded with
__initdata.
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index 552cabac060..da42ab414c4 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -87,30 +87,7 @@ changes occur:
This is used primarily during fault processing.
-5) void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-
- The software page tables for address space 'mm' for virtual
- addresses in the range 'start' to 'end-1' are being torn down.
-
- Some platforms cache the lowest level of the software page tables
- in a linear virtually mapped array, to make TLB miss processing
- more efficient. On such platforms, since the TLB is caching the
- software page table structure, it needs to be flushed when parts
- of the software page table tree are unlinked/freed.
-
- Sparc64 is one example of a platform which does this.
-
- Usually, when munmap()'ing an area of user virtual address
- space, the kernel leaves the page table parts around and just
- marks the individual pte's as invalid. However, if very large
- portions of the address space are unmapped, the kernel frees up
- those portions of the software page tables to prevent potential
- excessive kernel memory usage caused by erratic mmap/mmunmap
- sequences. It is at these times that flush_tlb_pgtables will
- be invoked.
-
-6) void update_mmu_cache(struct vm_area_struct *vma,
+5) void update_mmu_cache(struct vm_area_struct *vma,
unsigned long address, pte_t pte)
At the end of every page fault, this routine is invoked to
@@ -123,7 +100,7 @@ changes occur:
translations for software managed TLB configurations.
The sparc64 port currently does this.
-7) void tlb_migrate_finish(struct mm_struct *mm)
+6) void tlb_migrate_finish(struct mm_struct *mm)
This interface is called at the end of an explicit
process migration. This interface provides a hook
diff --git a/Documentation/cdrom/cdrom-standard.tex b/Documentation/cdrom/cdrom-standard.tex
index 92f94e59758..c713aeb020c 100644
--- a/Documentation/cdrom/cdrom-standard.tex
+++ b/Documentation/cdrom/cdrom-standard.tex
@@ -1009,7 +1009,7 @@ taken over the torch in maintaining \cdromc\ and integrating much
\cdrom-related code in the 2.1-kernel. Thanks to Scott Snyder and
Gerd Knorr, who were the first to implement this interface for SCSI
and IDE-CD drivers and added many ideas for extension of the data
-structures relative to kernel~2.0. Further thanks to Heiko Eissfeldt,
+structures relative to kernel~2.0. Further thanks to Heiko Ei{\sz}feldt,
Thomas Quinot, Jon Tombs, Ken Pizzini, Eberhard M\"onkeberg and Andrew
Kroll, the \linux\ \cdrom\ device driver developers who were kind
enough to give suggestions and criticisms during the writing. Finally
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups.txt
new file mode 100644
index 00000000000..98a26f81fa7
--- /dev/null
+++ b/Documentation/cgroups.txt
@@ -0,0 +1,545 @@
+ CGROUPS
+ -------
+
+Written by Paul Menage <menage@google.com> based on Documentation/cpusets.txt
+
+Original copyright statements from cpusets.txt:
+Portions Copyright (C) 2004 BULL SA.
+Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
+Modified by Paul Jackson <pj@sgi.com>
+Modified by Christoph Lameter <clameter@sgi.com>
+
+CONTENTS:
+=========
+
+1. Control Groups
+ 1.1 What are cgroups ?
+ 1.2 Why are cgroups needed ?
+ 1.3 How are cgroups implemented ?
+ 1.4 What does notify_on_release do ?
+ 1.5 How do I use cgroups ?
+2. Usage Examples and Syntax
+ 2.1 Basic Usage
+ 2.2 Attaching processes
+3. Kernel API
+ 3.1 Overview
+ 3.2 Synchronization
+ 3.3 Subsystem API
+4. Questions
+
+1. Control Groups
+==========
+
+1.1 What are cgroups ?
+----------------------
+
+Control Groups provide a mechanism for aggregating/partitioning sets of
+tasks, and all their future children, into hierarchical groups with
+specialized behaviour.
+
+Definitions:
+
+A *cgroup* associates a set of tasks with a set of parameters for one
+or more subsystems.
+
+A *subsystem* is a module that makes use of the task grouping
+facilities provided by cgroups to treat groups of tasks in
+particular ways. A subsystem is typically a "resource controller" that
+schedules a resource or applies per-cgroup limits, but it may be
+anything that wants to act on a group of processes, e.g. a
+virtualization subsystem.
+
+A *hierarchy* is a set of cgroups arranged in a tree, such that
+every task in the system is in exactly one of the cgroups in the
+hierarchy, and a set of subsystems; each subsystem has system-specific
+state attached to each cgroup in the hierarchy. Each hierarchy has
+an instance of the cgroup virtual filesystem associated with it.
+
+At any one time there may be multiple active hierachies of task
+cgroups. Each hierarchy is a partition of all tasks in the system.
+
+User level code may create and destroy cgroups by name in an
+instance of the cgroup virtual file system, specify and query to
+which cgroup a task is assigned, and list the task pids assigned to
+a cgroup. Those creations and assignments only affect the hierarchy
+associated with that instance of the cgroup file system.
+
+On their own, the only use for cgroups is for simple job
+tracking. The intention is that other subsystems hook into the generic
+cgroup support to provide new attributes for cgroups, such as
+accounting/limiting the resources which processes in a cgroup can
+access. For example, cpusets (see Documentation/cpusets.txt) allows
+you to associate a set of CPUs and a set of memory nodes with the
+tasks in each cgroup.
+
+1.2 Why are cgroups needed ?
+----------------------------
+
+There are multiple efforts to provide process aggregations in the
+Linux kernel, mainly for resource tracking purposes. Such efforts
+include cpusets, CKRM/ResGroups, UserBeanCounters, and virtual server
+namespaces. These all require the basic notion of a
+grouping/partitioning of processes, with newly forked processes ending
+in the same group (cgroup) as their parent process.
+
+The kernel cgroup patch provides the minimum essential kernel
+mechanisms required to efficiently implement such groups. It has
+minimal impact on the system fast paths, and provides hooks for
+specific subsystems such as cpusets to provide additional behaviour as
+desired.
+
+Multiple hierarchy support is provided to allow for situations where
+the division of tasks into cgroups is distinctly different for
+different subsystems - having parallel hierarchies allows each
+hierarchy to be a natural division of tasks, without having to handle
+complex combinations of tasks that would be present if several
+unrelated subsystems needed to be forced into the same tree of
+cgroups.
+
+At one extreme, each resource controller or subsystem could be in a
+separate hierarchy; at the other extreme, all subsystems
+would be attached to the same hierarchy.
+
+As an example of a scenario (originally proposed by vatsa@in.ibm.com)
+that can benefit from multiple hierarchies, consider a large
+university server with various users - students, professors, system
+tasks etc. The resource planning for this server could be along the
+following lines:
+
+ CPU : Top cpuset
+ / \
+ CPUSet1 CPUSet2
+ | |
+ (Profs) (Students)
+
+ In addition (system tasks) are attached to topcpuset (so
+ that they can run anywhere) with a limit of 20%
+
+ Memory : Professors (50%), students (30%), system (20%)
+
+ Disk : Prof (50%), students (30%), system (20%)
+
+ Network : WWW browsing (20%), Network File System (60%), others (20%)
+ / \
+ Prof (15%) students (5%)
+
+Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go
+into NFS network class.
+
+At the same time firefox/lynx will share an appropriate CPU/Memory class
+depending on who launched it (prof/student).
+
+With the ability to classify tasks differently for different resources
+(by putting those resource subsystems in different hierarchies) then
+the admin can easily set up a script which receives exec notifications
+and depending on who is launching the browser he can
+
+ # echo browser_pid > /mnt/<restype>/<userclass>/tasks
+
+With only a single hierarchy, he now would potentially have to create
+a separate cgroup for every browser launched and associate it with
+approp network and other resource class. This may lead to
+proliferation of such cgroups.
+
+Also lets say that the administrator would like to give enhanced network
+access temporarily to a student's browser (since it is night and the user
+wants to do online gaming :) OR give one of the students simulation
+apps enhanced CPU power,
+
+With ability to write pids directly to resource classes, its just a
+matter of :
+
+ # echo pid > /mnt/network/<new_class>/tasks
+ (after some time)
+ # echo pid > /mnt/network/<orig_class>/tasks
+
+Without this ability, he would have to split the cgroup into
+multiple separate ones and then associate the new cgroups with the
+new resource classes.
+
+
+
+1.3 How are cgroups implemented ?
+---------------------------------
+
+Control Groups extends the kernel as follows:
+
+ - Each task in the system has a reference-counted pointer to a
+ css_set.
+
+ - A css_set contains a set of reference-counted pointers to
+ cgroup_subsys_state objects, one for each cgroup subsystem
+ registered in the system. There is no direct link from a task to
+ the cgroup of which it's a member in each hierarchy, but this
+ can be determined by following pointers through the
+ cgroup_subsys_state objects. This is because accessing the
+ subsystem state is something that's expected to happen frequently
+ and in performance-critical code, whereas operations that require a
+ task's actual cgroup assignments (in particular, moving between
+ cgroups) are less common. A linked list runs through the cg_list
+ field of each task_struct using the css_set, anchored at
+ css_set->tasks.
+
+ - A cgroup hierarchy filesystem can be mounted for browsing and
+ manipulation from user space.
+
+ - You can list all the tasks (by pid) attached to any cgroup.
+
+The implementation of cgroups requires a few, simple hooks
+into the rest of the kernel, none in performance critical paths:
+
+ - in init/main.c, to initialize the root cgroups and initial
+ css_set at system boot.
+
+ - in fork and exit, to attach and detach a task from its css_set.
+
+In addition a new file system, of type "cgroup" may be mounted, to
+enable browsing and modifying the cgroups presently known to the
+kernel. When mounting a cgroup hierarchy, you may specify a
+comma-separated list of subsystems to mount as the filesystem mount
+options. By default, mounting the cgroup filesystem attempts to
+mount a hierarchy containing all registered subsystems.
+
+If an active hierarchy with exactly the same set of subsystems already
+exists, it will be reused for the new mount. If no existing hierarchy
+matches, and any of the requested subsystems are in use in an existing
+hierarchy, the mount will fail with -EBUSY. Otherwise, a new hierarchy
+is activated, associated with the requested subsystems.
+
+It's not currently possible to bind a new subsystem to an active
+cgroup hierarchy, or to unbind a subsystem from an active cgroup
+hierarchy. This may be possible in future, but is fraught with nasty
+error-recovery issues.
+
+When a cgroup filesystem is unmounted, if there are any
+child cgroups created below the top-level cgroup, that hierarchy
+will remain active even though unmounted; if there are no
+child cgroups then the hierarchy will be deactivated.
+
+No new system calls are added for cgroups - all support for
+querying and modifying cgroups is via this cgroup file system.
+
+Each task under /proc has an added file named 'cgroup' displaying,
+for each active hierarchy, the subsystem names and the cgroup name
+as the path relative to the root of the cgroup file system.
+
+Each cgroup is represented by a directory in the cgroup file system
+containing the following files describing that cgroup:
+
+ - tasks: list of tasks (by pid) attached to that cgroup
+ - notify_on_release flag: run /sbin/cgroup_release_agent on exit?
+
+Other subsystems such as cpusets may add additional files in each
+cgroup dir
+
+New cgroups are created using the mkdir system call or shell
+command. The properties of a cgroup, such as its flags, are
+modified by writing to the appropriate file in that cgroups
+directory, as listed above.
+
+The named hierarchical structure of nested cgroups allows partitioning
+a large system into nested, dynamically changeable, "soft-partitions".
+
+The attachment of each task, automatically inherited at fork by any
+children of that task, to a cgroup allows organizing the work load
+on a system into related sets of tasks. A task may be re-attached to
+any other cgroup, if allowed by the permissions on the necessary
+cgroup file system directories.
+
+When a task is moved from one cgroup to another, it gets a new
+css_set pointer - if there's an already existing css_set with the
+desired collection of cgroups then that group is reused, else a new
+css_set is allocated. Note that the current implementation uses a
+linear search to locate an appropriate existing css_set, so isn't
+very efficient. A future version will use a hash table for better
+performance.
+
+To allow access from a cgroup to the css_sets (and hence tasks)
+that comprise it, a set of cg_cgroup_link objects form a lattice;
+each cg_cgroup_link is linked into a list of cg_cgroup_links for
+a single cgroup on its cont_link_list field, and a list of
+cg_cgroup_links for a single css_set on its cg_link_list.
+
+Thus the set of tasks in a cgroup can be listed by iterating over
+each css_set that references the cgroup, and sub-iterating over
+each css_set's task set.
+
+The use of a Linux virtual file system (vfs) to represent the
+cgroup hierarchy provides for a familiar permission and name space
+for cgroups, with a minimum of additional kernel code.
+
+1.4 What does notify_on_release do ?
+------------------------------------
+
+*** notify_on_release is disabled in the current patch set. It will be
+*** reactivated in a future patch in a less-intrusive manner
+
+If the notify_on_release flag is enabled (1) in a cgroup, then
+whenever the last task in the cgroup leaves (exits or attaches to
+some other cgroup) and the last child cgroup of that cgroup
+is removed, then the kernel runs the command specified by the contents
+of the "release_agent" file in that hierarchy's root directory,
+supplying the pathname (relative to the mount point of the cgroup
+file system) of the abandoned cgroup. This enables automatic
+removal of abandoned cgroups. The default value of
+notify_on_release in the root cgroup at system boot is disabled
+(0). The default value of other cgroups at creation is the current
+value of their parents notify_on_release setting. The default value of
+a cgroup hierarchy's release_agent path is empty.
+
+1.5 How do I use cgroups ?
+--------------------------
+
+To start a new job that is to be contained within a cgroup, using
+the "cpuset" cgroup subsystem, the steps are something like:
+
+ 1) mkdir /dev/cgroup
+ 2) mount -t cgroup -ocpuset cpuset /dev/cgroup
+ 3) Create the new cgroup by doing mkdir's and write's (or echo's) in
+ the /dev/cgroup virtual file system.
+ 4) Start a task that will be the "founding father" of the new job.
+ 5) Attach that task to the new cgroup by writing its pid to the
+ /dev/cgroup tasks file for that cgroup.
+ 6) fork, exec or clone the job tasks from this founding father task.
+
+For example, the following sequence of commands will setup a cgroup
+named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
+and then start a subshell 'sh' in that cgroup:
+
+ mount -t cgroup cpuset -ocpuset /dev/cgroup
+ cd /dev/cgroup
+ mkdir Charlie
+ cd Charlie
+ /bin/echo 2-3 > cpus
+ /bin/echo 1 > mems
+ /bin/echo $$ > tasks
+ sh
+ # The subshell 'sh' is now running in cgroup Charlie
+ # The next line should display '/Charlie'
+ cat /proc/self/cgroup
+
+2. Usage Examples and Syntax
+============================
+
+2.1 Basic Usage
+---------------
+
+Creating, modifying, using the cgroups can be done through the cgroup
+virtual filesystem.
+
+To mount a cgroup hierarchy will all available subsystems, type:
+# mount -t cgroup xxx /dev/cgroup
+
+The "xxx" is not interpreted by the cgroup code, but will appear in
+/proc/mounts so may be any useful identifying string that you like.
+
+To mount a cgroup hierarchy with just the cpuset and numtasks
+subsystems, type:
+# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup
+
+To change the set of subsystems bound to a mounted hierarchy, just
+remount with different options:
+
+# mount -o remount,cpuset,ns /dev/cgroup
+
+Note that changing the set of subsystems is currently only supported
+when the hierarchy consists of a single (root) cgroup. Supporting
+the ability to arbitrarily bind/unbind subsystems from an existing
+cgroup hierarchy is intended to be implemented in the future.
+
+Then under /dev/cgroup you can find a tree that corresponds to the
+tree of the cgroups in the system. For instance, /dev/cgroup
+is the cgroup that holds the whole system.
+
+If you want to create a new cgroup under /dev/cgroup:
+# cd /dev/cgroup
+# mkdir my_cgroup
+
+Now you want to do something with this cgroup.
+# cd my_cgroup
+
+In this directory you can find several files:
+# ls
+notify_on_release release_agent tasks
+(plus whatever files are added by the attached subsystems)
+
+Now attach your shell to this cgroup:
+# /bin/echo $$ > tasks
+
+You can also create cgroups inside your cgroup by using mkdir in this
+directory.
+# mkdir my_sub_cs
+
+To remove a cgroup, just use rmdir:
+# rmdir my_sub_cs
+
+This will fail if the cgroup is in use (has cgroups inside, or
+has processes attached, or is held alive by other subsystem-specific
+reference).
+
+2.2 Attaching processes
+-----------------------
+
+# /bin/echo PID > tasks
+
+Note that it is PID, not PIDs. You can only attach ONE task at a time.
+If you have several tasks to attach, you have to do it one after another:
+
+# /bin/echo PID1 > tasks
+# /bin/echo PID2 > tasks
+ ...
+# /bin/echo PIDn > tasks
+
+3. Kernel API
+=============
+
+3.1 Overview
+------------
+
+Each kernel subsystem that wants to hook into the generic cgroup
+system needs to create a cgroup_subsys object. This contains
+various methods, which are callbacks from the cgroup system, along
+with a subsystem id which will be assigned by the cgroup system.
+
+Other fields in the cgroup_subsys object include:
+
+- subsys_id: a unique array index for the subsystem, indicating which
+ entry in cgroup->subsys[] this subsystem should be
+ managing. Initialized by cgroup_register_subsys(); prior to this
+ it should be initialized to -1
+
+- hierarchy: an index indicating which hierarchy, if any, this
+ subsystem is currently attached to. If this is -1, then the
+ subsystem is not attached to any hierarchy, and all tasks should be
+ considered to be members of the subsystem's top_cgroup. It should
+ be initialized to -1.
+
+- name: should be initialized to a unique subsystem name prior to
+ calling cgroup_register_subsystem. Should be no longer than
+ MAX_CGROUP_TYPE_NAMELEN
+
+Each cgroup object created by the system has an array of pointers,
+indexed by subsystem id; this pointer is entirely managed by the
+subsystem; the generic cgroup code will never touch this pointer.
+
+3.2 Synchronization
+-------------------
+
+There is a global mutex, cgroup_mutex, used by the cgroup
+system. This should be taken by anything that wants to modify a
+cgroup. It may also be taken to prevent cgroups from being
+modified, but more specific locks may be more appropriate in that
+situation.
+
+See kernel/cgroup.c for more details.
+
+Subsystems can take/release the cgroup_mutex via the functions
+cgroup_lock()/cgroup_unlock(), and can
+take/release the callback_mutex via the functions
+cgroup_lock()/cgroup_unlock().
+
+Accessing a task's cgroup pointer may be done in the following ways:
+- while holding cgroup_mutex
+- while holding the task's alloc_lock (via task_lock())
+- inside an rcu_read_lock() section via rcu_dereference()
+
+3.3 Subsystem API
+--------------------------
+
+Each subsystem should:
+
+- add an entry in linux/cgroup_subsys.h
+- define a cgroup_subsys object called <name>_subsys
+
+Each subsystem may export the following methods. The only mandatory
+methods are create/destroy. Any others that are null are presumed to
+be successful no-ops.
+
+struct cgroup_subsys_state *create(struct cgroup *cont)
+LL=cgroup_mutex
+
+Called to create a subsystem state object for a cgroup. The
+subsystem should allocate its subsystem state object for the passed
+cgroup, returning a pointer to the new object on success or a
+negative error code. On success, the subsystem pointer should point to
+a structure of type cgroup_subsys_state (typically embedded in a
+larger subsystem-specific object), which will be initialized by the
+cgroup system. Note that this will be called at initialization to
+create the root subsystem state for this subsystem; this case can be
+identified by the passed cgroup object having a NULL parent (since
+it's the root of the hierarchy) and may be an appropriate place for
+initialization code.
+
+void destroy(struct cgroup *cont)
+LL=cgroup_mutex
+
+The cgroup system is about to destroy the passed cgroup; the
+subsystem should do any necessary cleanup
+
+int can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+ struct task_struct *task)
+LL=cgroup_mutex
+
+Called prior to moving a task into a cgroup; if the subsystem
+returns an error, this will abort the attach operation. If a NULL
+task is passed, then a successful result indicates that *any*
+unspecified task can be moved into the cgroup. Note that this isn't
+called on a fork. If this method returns 0 (success) then this should
+remain valid while the caller holds cgroup_mutex.
+
+void attach(struct cgroup_subsys *ss, struct cgroup *cont,
+ struct cgroup *old_cont, struct task_struct *task)
+LL=cgroup_mutex
+
+
+Called after the task has been attached to the cgroup, to allow any
+post-attachment activity that requires memory allocations or blocking.
+
+void fork(struct cgroup_subsy *ss, struct task_struct *task)
+LL=callback_mutex, maybe read_lock(tasklist_lock)
+
+Called when a task is forked into a cgroup. Also called during
+registration for all existing tasks.
+
+void exit(struct cgroup_subsys *ss, struct task_struct *task)
+LL=callback_mutex
+
+Called during task exit
+
+int populate(struct cgroup_subsys *ss, struct cgroup *cont)
+LL=none
+
+Called after creation of a cgroup to allow a subsystem to populate
+the cgroup directory with file entries. The subsystem should make
+calls to cgroup_add_file() with objects of type cftype (see
+include/linux/cgroup.h for details). Note that although this
+method can return an error code, the error code is currently not
+always handled well.
+
+void post_clone(struct cgroup_subsys *ss, struct cgroup *cont)
+
+Called at the end of cgroup_clone() to do any paramater
+initialization which might be required before a task could attach. For
+example in cpusets, no task may attach before 'cpus' and 'mems' are set
+up.
+
+void bind(struct cgroup_subsys *ss, struct cgroup *root)
+LL=callback_mutex
+
+Called when a cgroup subsystem is rebound to a different hierarchy
+and root cgroup. Currently this will only involve movement between
+the default hierarchy (which never has sub-cgroups) and a hierarchy
+that is being created/destroyed (and hence has no sub-cgroups).
+
+4. Questions
+============
+
+Q: what's up with this '/bin/echo' ?
+A: bash's builtin 'echo' command does not check calls to write() against
+ errors. If you use it in the cgroup file system, you won't be
+ able to tell whether a command succeeded or failed.
+
+Q: When I attach processes, only the first of the line gets really attached !
+A: We can only return one error code per call to write(). So you should also
+ put only ONE pid.
+
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt
index b6d24c22274..a741f658a3c 100644
--- a/Documentation/cpu-hotplug.txt
+++ b/Documentation/cpu-hotplug.txt
@@ -220,7 +220,9 @@ A: The following happen, listed in no particular order :-)
CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the
CPU is being offlined while tasks are frozen due to a suspend operation in
progress
-- All process is migrated away from this outgoing CPU to a new CPU
+- All processes are migrated away from this outgoing CPU to new CPUs.
+ The new CPU is chosen from each process' current cpuset, which may be
+ a subset of all online CPUs.
- All interrupts targeted to this CPU is migrated to a new CPU
- timers/bottom half/task lets are also migrated to a new CPU
- Once all services are migrated, kernel calls an arch specific routine
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index ec9de6917f0..141bef1c859 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -7,6 +7,7 @@ Written by Simon.Derr@bull.net
Portions Copyright (c) 2004-2006 Silicon Graphics, Inc.
Modified by Paul Jackson <pj@sgi.com>
Modified by Christoph Lameter <clameter@sgi.com>
+Modified by Paul Menage <menage@google.com>
CONTENTS:
=========
@@ -16,9 +17,9 @@ CONTENTS:
1.2 Why are cpusets needed ?
1.3 How are cpusets implemented ?
1.4 What are exclusive cpusets ?
- 1.5 What does notify_on_release do ?
- 1.6 What is memory_pressure ?
- 1.7 What is memory spread ?
+ 1.5 What is memory_pressure ?
+ 1.6 What is memory spread ?
+ 1.7 What is sched_load_balance ?
1.8 How do I use cpusets ?
2. Usage Examples and Syntax
2.1 Basic Usage
@@ -44,18 +45,19 @@ hierarchy visible in a virtual file system. These are the essential
hooks, beyond what is already present, required to manage dynamic
job placement on large systems.
-Each task has a pointer to a cpuset. Multiple tasks may reference
-the same cpuset. Requests by a task, using the sched_setaffinity(2)
-system call to include CPUs in its CPU affinity mask, and using the
-mbind(2) and set_mempolicy(2) system calls to include Memory Nodes
-in its memory policy, are both filtered through that tasks cpuset,
-filtering out any CPUs or Memory Nodes not in that cpuset. The
-scheduler will not schedule a task on a CPU that is not allowed in
-its cpus_allowed vector, and the kernel page allocator will not
-allocate a page on a node that is not allowed in the requesting tasks
-mems_allowed vector.
-
-User level code may create and destroy cpusets by name in the cpuset
+Cpusets use the generic cgroup subsystem described in
+Documentation/cgroup.txt.
+
+Requests by a task, using the sched_setaffinity(2) system call to
+include CPUs in its CPU affinity mask, and using the mbind(2) and
+set_mempolicy(2) system calls to include Memory Nodes in its memory
+policy, are both filtered through that tasks cpuset, filtering out any
+CPUs or Memory Nodes not in that cpuset. The scheduler will not
+schedule a task on a CPU that is not allowed in its cpus_allowed
+vector, and the kernel page allocator will not allocate a page on a
+node that is not allowed in the requesting tasks mems_allowed vector.
+
+User level code may create and destroy cpusets by name in the cgroup
virtual file system, manage the attributes and permissions of these
cpusets and which CPUs and Memory Nodes are assigned to each cpuset,
specify and query to which cpuset a task is assigned, and list the
@@ -115,7 +117,7 @@ Cpusets extends these two mechanisms as follows:
- Cpusets are sets of allowed CPUs and Memory Nodes, known to the
kernel.
- Each task in the system is attached to a cpuset, via a pointer
- in the task structure to a reference counted cpuset structure.
+ in the task structure to a reference counted cgroup structure.
- Calls to sched_setaffinity are filtered to just those CPUs
allowed in that tasks cpuset.
- Calls to mbind and set_mempolicy are filtered to just
@@ -145,15 +147,10 @@ into the rest of the kernel, none in performance critical paths:
- in page_alloc.c, to restrict memory to allowed nodes.
- in vmscan.c, to restrict page recovery to the current cpuset.
-In addition a new file system, of type "cpuset" may be mounted,
-typically at /dev/cpuset, to enable browsing and modifying the cpusets
-presently known to the kernel. No new system calls are added for
-cpusets - all support for querying and modifying cpusets is via
-this cpuset file system.
-
-Each task under /proc has an added file named 'cpuset', displaying
-the cpuset name, as the path relative to the root of the cpuset file
-system.
+You should mount the "cgroup" filesystem type in order to enable
+browsing and modifying the cpusets presently known to the kernel. No
+new system calls are added for cpusets - all support for querying and
+modifying cpusets is via this cpuset file system.
The /proc/<pid>/status file for each task has two added lines,
displaying the tasks cpus_allowed (on which CPUs it may be scheduled)
@@ -163,16 +160,15 @@ in the format seen in the following example:
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Mems_allowed: ffffffff,ffffffff
-Each cpuset is represented by a directory in the cpuset file system
-containing the following files describing that cpuset:
+Each cpuset is represented by a directory in the cgroup file system
+containing (on top of the standard cgroup files) the following
+files describing that cpuset:
- cpus: list of CPUs in that cpuset
- mems: list of Memory Nodes in that cpuset
- memory_migrate flag: if set, move pages to cpusets nodes
- cpu_exclusive flag: is cpu placement exclusive?
- mem_exclusive flag: is memory placement exclusive?
- - tasks: list of tasks (by pid) attached to that cpuset
- - notify_on_release flag: run /sbin/cpuset_release_agent on exit?
- memory_pressure: measure of how much paging pressure in cpuset
In addition, the root cpuset only has the following file:
@@ -237,21 +233,7 @@ such as requests from interrupt handlers, is allowed to be taken
outside even a mem_exclusive cpuset.
-1.5 What does notify_on_release do ?
-------------------------------------
-
-If the notify_on_release flag is enabled (1) in a cpuset, then whenever
-the last task in the cpuset leaves (exits or attaches to some other
-cpuset) and the last child cpuset of that cpuset is removed, then
-the kernel runs the command /sbin/cpuset_release_agent, supplying the
-pathname (relative to the mount point of the cpuset file system) of the
-abandoned cpuset. This enables automatic removal of abandoned cpusets.
-The default value of notify_on_release in the root cpuset at system
-boot is disabled (0). The default value of other cpusets at creation
-is the current value of their parents notify_on_release setting.
-
-
-1.6 What is memory_pressure ?
+1.5 What is memory_pressure ?
-----------------------------
The memory_pressure of a cpuset provides a simple per-cpuset metric
of the rate that the tasks in a cpuset are attempting to free up in
@@ -308,7 +290,7 @@ the tasks in the cpuset, in units of reclaims attempted per second,
times 1000.
-1.7 What is memory spread ?
+1.6 What is memory spread ?
---------------------------
There are two boolean flag files per cpuset that control where the
kernel allocates pages for the file system buffers and related in
@@ -378,6 +360,142 @@ policy, especially for jobs that might have one thread reading in the
data set, the memory allocation across the nodes in the jobs cpuset
can become very uneven.
+1.7 What is sched_load_balance ?
+--------------------------------
+
+The kernel scheduler (kernel/sched.c) automatically load balances
+tasks. If one CPU is underutilized, kernel code running on that
+CPU will look for tasks on other more overloaded CPUs and move those
+tasks to itself, within the constraints of such placement mechanisms
+as cpusets and sched_setaffinity.
+
+The algorithmic cost of load balancing and its impact on key shared
+kernel data structures such as the task list increases more than
+linearly with the number of CPUs being balanced. So the scheduler
+has support to partition the systems CPUs into a number of sched
+domains such that it only load balances within each sched domain.
+Each sched domain covers some subset of the CPUs in the system;
+no two sched domains overlap; some CPUs might not be in any sched
+domain and hence won't be load balanced.
+
+Put simply, it costs less to balance between two smaller sched domains
+than one big one, but doing so means that overloads in one of the
+two domains won't be load balanced to the other one.
+
+By default, there is one sched domain covering all CPUs, except those
+marked isolated using the kernel boot time "isolcpus=" argument.
+
+This default load balancing across all CPUs is not well suited for
+the following two situations:
+ 1) On large systems, load balancing across many CPUs is expensive.
+ If the system is managed using cpusets to place independent jobs
+ on separate sets of CPUs, full load balancing is unnecessary.
+ 2) Systems supporting realtime on some CPUs need to minimize
+ system overhead on those CPUs, including avoiding task load
+ balancing if that is not needed.
+
+When the per-cpuset flag "sched_load_balance" is enabled (the default
+setting), it requests that all the CPUs in that cpusets allowed 'cpus'
+be contained in a single sched domain, ensuring that load balancing
+can move a task (not otherwised pinned, as by sched_setaffinity)
+from any CPU in that cpuset to any other.
+
+When the per-cpuset flag "sched_load_balance" is disabled, then the
+scheduler will avoid load balancing across the CPUs in that cpuset,
+--except-- in so far as is necessary because some overlapping cpuset
+has "sched_load_balance" enabled.
+
+So, for example, if the top cpuset has the flag "sched_load_balance"
+enabled, then the scheduler will have one sched domain covering all
+CPUs, and the setting of the "sched_load_balance" flag in any other
+cpusets won't matter, as we're already fully load balancing.
+
+Therefore in the above two situations, the top cpuset flag
+"sched_load_balance" should be disabled, and only some of the smaller,
+child cpusets have this flag enabled.
+
+When doing this, you don't usually want to leave any unpinned tasks in
+the top cpuset that might use non-trivial amounts of CPU, as such tasks
+may be artificially constrained to some subset of CPUs, depending on
+the particulars of this flag setting in descendent cpusets. Even if
+such a task could use spare CPU cycles in some other CPUs, the kernel
+scheduler might not consider the possibility of load balancing that
+task to that underused CPU.
+
+Of course, tasks pinned to a particular CPU can be left in a cpuset
+that disables "sched_load_balance" as those tasks aren't going anywhere
+else anyway.
+
+There is an impedance mismatch here, between cpusets and sched domains.
+Cpusets are hierarchical and nest. Sched domains are flat; they don't
+overlap and each CPU is in at most one sched domain.
+
+It is necessary for sched domains to be flat because load balancing
+across partially overlapping sets of CPUs would risk unstable dynamics
+that would be beyond our understanding. So if each of two partially
+overlapping cpusets enables the flag 'sched_load_balance', then we
+form a single sched domain that is a superset of both. We won't move
+a task to a CPU outside it cpuset, but the scheduler load balancing
+code might waste some compute cycles considering that possibility.
+
+This mismatch is why there is not a simple one-to-one relation
+between which cpusets have the flag "sched_load_balance" enabled,
+and the sched domain configuration. If a cpuset enables the flag, it
+will get balancing across all its CPUs, but if it disables the flag,
+it will only be assured of no load balancing if no other overlapping
+cpuset enables the flag.
+
+If two cpusets have partially overlapping 'cpus' allowed, and only
+one of them has this flag enabled, then the other may find its
+tasks only partially load balanced, just on the overlapping CPUs.
+This is just the general case of the top_cpuset example given a few
+paragraphs above. In the general case, as in the top cpuset case,
+don't leave tasks that might use non-trivial amounts of CPU in
+such partially load balanced cpusets, as they may be artificially
+constrained to some subset of the CPUs allowed to them, for lack of
+load balancing to the other CPUs.
+
+1.7.1 sched_load_balance implementation details.
+------------------------------------------------
+
+The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary
+to most cpuset flags.) When enabled for a cpuset, the kernel will
+ensure that it can load balance across all the CPUs in that cpuset
+(makes sure that all the CPUs in the cpus_allowed of that cpuset are
+in the same sched domain.)
+
+If two overlapping cpusets both have 'sched_load_balance' enabled,
+then they will be (must be) both in the same sched domain.
+
+If, as is the default, the top cpuset has 'sched_load_balance' enabled,
+then by the above that means there is a single sched domain covering
+the whole system, regardless of any other cpuset settings.
+
+The kernel commits to user space that it will avoid load balancing
+where it can. It will pick as fine a granularity partition of sched
+domains as it can while still providing load balancing for any set
+of CPUs allowed to a cpuset having 'sched_load_balance' enabled.
+
+The internal kernel cpuset to scheduler interface passes from the
+cpuset code to the scheduler code a partition of the load balanced
+CPUs in the system. This partition is a set of subsets (represented
+as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all
+the CPUs that must be load balanced.
+
+Whenever the 'sched_load_balance' flag changes, or CPUs come or go
+from a cpuset with this flag enabled, or a cpuset with this flag
+enabled is removed, the cpuset code builds a new such partition and
+passes it to the scheduler sched domain setup code, to have the sched
+domains rebuilt as necessary.
+
+This partition exactly defines what sched domains the scheduler should
+setup - one sched domain for each element (cpumask_t) in the partition.
+
+The scheduler remembers the currently active sched domain partitions.
+When the scheduler routine partition_sched_domains() is invoked from
+the cpuset code to update these sched domains, it compares the new
+partition requested with the current, and updates its sched domains,
+removing the old and adding the new, for each change.
1.8 How do I use cpusets ?
--------------------------
@@ -469,7 +587,7 @@ than stress the kernel.
To start a new job that is to be contained within a cpuset, the steps are:
1) mkdir /dev/cpuset
- 2) mount -t cpuset none /dev/cpuset
+ 2) mount -t cgroup -ocpuset cpuset /dev/cpuset
3) Create the new cpuset by doing mkdir's and write's (or echo's) in
the /dev/cpuset virtual file system.
4) Start a task that will be the "founding father" of the new job.
@@ -481,7 +599,7 @@ For example, the following sequence of commands will setup a cpuset
named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
and then start a subshell 'sh' in that cpuset:
- mount -t cpuset none /dev/cpuset
+ mount -t cgroup -ocpuset cpuset /dev/cpuset
cd /dev/cpuset
mkdir Charlie
cd Charlie
@@ -513,7 +631,7 @@ Creating, modifying, using the cpusets can be done through the cpuset
virtual filesystem.
To mount it, type:
-# mount -t cpuset none /dev/cpuset
+# mount -t cgroup -o cpuset cpuset /dev/cpuset
Then under /dev/cpuset you can find a tree that corresponds to the
tree of the cpusets in the system. For instance, /dev/cpuset
@@ -556,6 +674,18 @@ To remove a cpuset, just use rmdir:
This will fail if the cpuset is in use (has cpusets inside, or has
processes attached).
+Note that for legacy reasons, the "cpuset" filesystem exists as a
+wrapper around the cgroup filesystem.
+
+The command
+
+mount -t cpuset X /dev/cpuset
+
+is equivalent to
+
+mount -t cgroup -ocpuset X /dev/cpuset
+echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
+
2.2 Adding/removing cpus
------------------------
diff --git a/Documentation/device-mapper/dm-uevent.txt b/Documentation/device-mapper/dm-uevent.txt
new file mode 100644
index 00000000000..07edbd85c71
--- /dev/null
+++ b/Documentation/device-mapper/dm-uevent.txt
@@ -0,0 +1,97 @@
+The device-mapper uevent code adds the capability to device-mapper to create
+and send kobject uevents (uevents). Previously device-mapper events were only
+available through the ioctl interface. The advantage of the uevents interface
+is the event contains environment attributes providing increased context for
+the event avoiding the need to query the state of the device-mapper device after
+the event is received.
+
+There are two functions currently for device-mapper events. The first function
+listed creates the event and the second function sends the event(s).
+
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+ const char *path, unsigned nr_valid_paths)
+
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+
+
+The variables added to the uevent environment are:
+
+Variable Name: DM_TARGET
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Name of device-mapper target that generated the event.
+
+Variable Name: DM_ACTION
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description:
+Value: Device-mapper specific action that caused the uevent action.
+ PATH_FAILED - A path has failed.
+ PATH_REINSTATED - A path has been reinstated.
+
+Variable Name: DM_SEQNUM
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description: A sequence number for this specific device-mapper device.
+Value: Valid unsigned integer range.
+
+Variable Name: DM_PATH
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Major and minor number of the path device pertaining to this
+event.
+Value: Path name in the form of "Major:Minor"
+
+Variable Name: DM_NR_VALID_PATHS
+Uevent Action(s): KOBJ_CHANGE
+Type: unsigned integer
+Description:
+Value: Valid unsigned integer range.
+
+Variable Name: DM_NAME
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: Name of the device-mapper device.
+Value: Name
+
+Variable Name: DM_UUID
+Uevent Action(s): KOBJ_CHANGE
+Type: string
+Description: UUID of the device-mapper device.
+Value: UUID. (Empty string if there isn't one.)
+
+An example of the uevents generated as captured by udevmonitor is shown
+below.
+
+1.) Path failure.
+UEVENT[1192521009.711215] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_FAILED
+DM_SEQNUM=1
+DM_PATH=8:32
+DM_NR_VALID_PATHS=0
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1130
+
+2.) Path reinstate.
+UEVENT[1192521132.989927] change@/block/dm-3
+ACTION=change
+DEVPATH=/block/dm-3
+SUBSYSTEM=block
+DM_TARGET=multipath
+DM_ACTION=PATH_REINSTATED
+DM_SEQNUM=2
+DM_PATH=8:32
+DM_NR_VALID_PATHS=1
+DM_NAME=mpath2
+DM_UUID=mpath-35333333000002328
+MINOR=3
+MAJOR=253
+SEQNUM=1131
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 6c46730c631..e6244cde26e 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2188,7 +2188,7 @@ Your cooperation is appreciated.
136-143 char Unix98 PTY slaves
0 = /dev/pts/0 First Unix98 pseudo-TTY
- 1 = /dev/pts/1 Second Unix98 pesudo-TTY
+ 1 = /dev/pts/1 Second Unix98 pseudo-TTY
...
These device nodes are automatically generated with
diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt
index 8569072fa38..387b8a720f4 100644
--- a/Documentation/driver-model/devres.txt
+++ b/Documentation/driver-model/devres.txt
@@ -32,7 +32,7 @@ braindamaged document, if it's finally working, well, it's working.
For one reason or another, low level drivers don't receive as much
attention or testing as core code, and bugs on driver detach or
-initilaization failure doesn't happen often enough to be noticeable.
+initialization failure don't happen often enough to be noticeable.
Init failure path is worse because it's much less travelled while
needs to handle multiple entry points.
@@ -160,7 +160,7 @@ resources on failure. For example,
devres_release_group(dev, NULL);
return err_code;
-As resource acquision failure usually means probe failure, constructs
+As resource acquisition failure usually means probe failure, constructs
like above are usually useful in midlayer driver (e.g. libata core
layer) where interface function shouldn't have side effect on failure.
For LLDs, just returning error code suffices in most cases.
diff --git a/Documentation/fb/deferred_io.txt b/Documentation/fb/deferred_io.txt
index 73cf9fb7cf6..63883a89212 100644
--- a/Documentation/fb/deferred_io.txt
+++ b/Documentation/fb/deferred_io.txt
@@ -3,7 +3,7 @@ Deferred IO
Deferred IO is a way to delay and repurpose IO. It uses host memory as a
buffer and the MMU pagefault as a pretrigger for when to perform the device
-IO. The following example may be a useful explaination of how one such setup
+IO. The following example may be a useful explanation of how one such setup
works:
- userspace app like Xfbdev mmaps framebuffer
@@ -28,7 +28,7 @@ a relatively more expensive operation.
For some types of nonvolatile high latency displays, the desired image is
the final image rather than the intermediate stages which is why it's okay
-to not update for each write that is occuring.
+to not update for each write that is occurring.
It may be the case that this is useful in other scenarios as well. Paul Mundt
has mentioned a case where it is beneficial to use the page count to decide
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 6b0f963f537..6bb9be54ab7 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -14,18 +14,6 @@ Who: Jiri Slaby <jirislaby@gmail.com>
---------------------------
-What: V4L2 VIDIOC_G_MPEGCOMP and VIDIOC_S_MPEGCOMP
-When: October 2007
-Why: Broken attempt to set MPEG compression parameters. These ioctls are
- not able to implement the wide variety of parameters that can be set
- by hardware MPEG encoders. A new MPEG control mechanism was created
- in kernel 2.6.18 that replaces these ioctls. See the V4L2 specification
- (section 1.9: Extended controls) for more information on this topic.
-Who: Hans Verkuil <hverkuil@xs4all.nl> and
- Mauro Carvalho Chehab <mchehab@infradead.org>
-
----------------------------
-
What: dev->power.power_state
When: July 2007
Why: Broken design for runtime control over driver power states, confusing
@@ -49,10 +37,10 @@ Who: David Miller <davem@davemloft.net>
---------------------------
What: Video4Linux API 1 ioctls and video_decoder.h from Video devices.
-When: December 2006
-Files: include/linux/video_decoder.h
-Check: include/linux/video_decoder.h
-Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
+When: December 2008
+Files: include/linux/video_decoder.h include/linux/videodev.h
+Check: include/linux/video_decoder.h include/linux/videodev.h
+Why: V4L1 AP1 was replaced by V4L2 API during migration from 2.4 to 2.6
series. The old API have lots of drawbacks and don't provide enough
means to work with all video and audio standards. The newer API is
already available on the main drivers and should be used instead.
@@ -61,7 +49,9 @@ Why: V4L1 AP1 was replaced by V4L2 API. during migration from 2.4 to 2.6
Decoder iocts are using internally to allow video drivers to
communicate with video decoders. This should also be improved to allow
V4L2 calls being translated into compatible internal ioctls.
-Who: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
+ Compatibility ioctls will be provided, for a while, via
+ v4l1-compat module.
+Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
diff --git a/Documentation/filesystems/9p.txt b/Documentation/filesystems/9p.txt
index d6fd6c6e424..b90f537af35 100644
--- a/Documentation/filesystems/9p.txt
+++ b/Documentation/filesystems/9p.txt
@@ -54,7 +54,7 @@ OPTIONS
aname=name aname specifies the file tree to access when the server is
offering several exported file systems.
- cache=mode specifies a cacheing policy. By default, no caches are used.
+ cache=mode specifies a caching policy. By default, no caches are used.
loose = no attempts are made at consistency,
intended for exclusive, read-only mounts
diff --git a/Documentation/filesystems/Exporting b/Documentation/filesystems/Exporting
index 31047e0fe14..87019d2b598 100644
--- a/Documentation/filesystems/Exporting
+++ b/Documentation/filesystems/Exporting
@@ -2,9 +2,12 @@
Making Filesystems Exportable
=============================
-Most filesystem operations require a dentry (or two) as a starting
+Overview
+--------
+
+All filesystem operations require a dentry (or two) as a starting
point. Local applications have a reference-counted hold on suitable
-dentrys via open file descriptors or cwd/root. However remote
+dentries via open file descriptors or cwd/root. However remote
applications that access a filesystem via a remote filesystem protocol
such as NFS may not be able to hold such a reference, and so need a
different way to refer to a particular dentry. As the alternative
@@ -13,14 +16,14 @@ server-reboot (among other things, though these tend to be the most
problematic), there is no simple answer like 'filename'.
The mechanism discussed here allows each filesystem implementation to
-specify how to generate an opaque (out side of the filesystem) byte
+specify how to generate an opaque (outside of the filesystem) byte
string for any dentry, and how to find an appropriate dentry for any
given opaque byte string.
This byte string will be called a "filehandle fragment" as it
corresponds to part of an NFS filehandle.
A filesystem which supports the mapping between filehandle fragments
-and dentrys will be termed "exportable".
+and dentries will be termed "exportable".
@@ -89,11 +92,9 @@ For a filesystem to be exportable it must:
1/ provide the filehandle fragment routines described below.
2/ make sure that d_splice_alias is used rather than d_add
when ->lookup finds an inode for a given parent and name.
- Typically the ->lookup routine will end:
- if (inode)
- return d_splice(inode, dentry);
- d_add(dentry, inode);
- return NULL;
+ Typically the ->lookup routine will end with a:
+
+ return d_splice_alias(inode, dentry);
}
@@ -101,67 +102,39 @@ For a filesystem to be exportable it must:
A file system implementation declares that instances of the filesystem
are exportable by setting the s_export_op field in the struct
super_block. This field must point to a "struct export_operations"
-struct which could potentially be full of NULLs, though normally at
-least get_parent will be set.
-
- The primary operations are decode_fh and encode_fh.
-decode_fh takes a filehandle fragment and tries to find or create a
-dentry for the object referred to by the filehandle.
-encode_fh takes a dentry and creates a filehandle fragment which can
-later be used to find/create a dentry for the same object.
-
-decode_fh will probably make use of "find_exported_dentry".
-This function lives in the "exportfs" module which a filesystem does
-not need unless it is being exported. So rather that calling
-find_exported_dentry directly, each filesystem should call it through
-the find_exported_dentry pointer in it's export_operations table.
-This field is set correctly by the exporting agent (e.g. nfsd) when a
-filesystem is exported, and before any export operations are called.
-
-find_exported_dentry needs three support functions from the
-filesystem:
- get_name. When given a parent dentry and a child dentry, this
- should find a name in the directory identified by the parent
- dentry, which leads to the object identified by the child dentry.
- If no get_name function is supplied, a default implementation is
- provided which uses vfs_readdir to find potential names, and
- matches inode numbers to find the correct match.
-
- get_parent. When given a dentry for a directory, this should return
- a dentry for the parent. Quite possibly the parent dentry will
- have been allocated by d_alloc_anon.
- The default get_parent function just returns an error so any
- filehandle lookup that requires finding a parent will fail.
- ->lookup("..") is *not* used as a default as it can leave ".."
- entries in the dcache which are too messy to work with.
-
- get_dentry. When given an opaque datum, this should find the
- implied object and create a dentry for it (possibly with
- d_alloc_anon).
- The opaque datum is whatever is passed down by the decode_fh
- function, and is often simply a fragment of the filehandle
- fragment.
- decode_fh passes two datums through find_exported_dentry. One that
- should be used to identify the target object, and one that can be
- used to identify the object's parent, should that be necessary.
- The default get_dentry function assumes that the datum contains an
- inode number and a generation number, and it attempts to get the
- inode using "iget" and check it's validity by matching the
- generation number. A filesystem should only depend on the default
- if iget can safely be used this way.
-
-If decode_fh and/or encode_fh are left as NULL, then default
-implementations are used. These defaults are suitable for ext2 and
-extremely similar filesystems (like ext3).
-
-The default encode_fh creates a filehandle fragment from the inode
-number and generation number of the target together with the inode
-number and generation number of the parent (if the parent is
-required).
-
-The default decode_fh extract the target and parent datums from the
-filehandle assuming the format used by the default encode_fh and
-passed them to find_exported_dentry.
+struct which has the following members:
+
+ encode_fh (optional)
+ Takes a dentry and creates a filehandle fragment which can later be used
+ to find or create a dentry for the same object. The default
+ implementation creates a filehandle fragment that encodes a 32bit inode
+ and generation number for the inode encoded, and if necessary the
+ same information for the parent.
+
+ fh_to_dentry (mandatory)
+ Given a filehandle fragment, this should find the implied object and
+ create a dentry for it (possibly with d_alloc_anon).
+
+ fh_to_parent (optional but strongly recommended)
+ Given a filehandle fragment, this should find the parent of the
+ implied object and create a dentry for it (possibly with d_alloc_anon).
+ May fail if the filehandle fragment is too small.
+
+ get_parent (optional but strongly recommended)
+ When given a dentry for a directory, this should return a dentry for
+ the parent. Quite possibly the parent dentry will have been allocated
+ by d_alloc_anon. The default get_parent function just returns an error
+ so any filehandle lookup that requires finding a parent will fail.
+ ->lookup("..") is *not* used as a default as it can leave ".." entries
+ in the dcache which are too messy to work with.
+
+ get_name (optional)
+ When given a parent dentry and a child dentry, this should find a name
+ in the directory identified by the parent dentry, which leads to the
+ object identified by the child dentry. If no get_name function is
+ supplied, a default implementation is provided which uses vfs_readdir
+ to find potential names, and matches inode numbers to find the correct
+ match.
A filehandle fragment consists of an array of 1 or more 4byte words,
@@ -172,5 +145,3 @@ generated by encode_fh, in which case it will have been padded with
nuls. Rather, the encode_fh routine should choose a "type" which
indicates the decode_fh how much of the filehandle is valid, and how
it should be interpreted.
-
-
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index fe26cc97852..37c10cba717 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -224,7 +224,7 @@ against the page the filesystem should redirty the page with
redirty_page_for_writepage(), then unlock the page and return zero.
This may also be done to avoid internal deadlocks, but rarely.
-If the filesytem is called for sync then it must wait on any
+If the filesystem is called for sync then it must wait on any
in-progress I/O and then start new I/O.
The filesystem should unlock the page synchronously, before returning to the
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index 4aecc9bdb27..b45f3c1b8b4 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -130,12 +130,12 @@ Device layer.
Journaling Block Device layer
-----------------------------
-The Journaling Block Device layer (JBD) isn't ext3 specific. It was design to
-add journaling capabilities on a block device. The ext3 filesystem code will
-inform the JBD of modifications it is performing (called a transaction). The
-journal supports the transactions start and stop, and in case of crash, the
-journal can replayed the transactions to put the partition back in a
-consistent state fast.
+The Journaling Block Device layer (JBD) isn't ext3 specific. It was designed
+to add journaling capabilities to a block device. The ext3 filesystem code
+will inform the JBD of modifications it is performing (called a transaction).
+The journal supports the transactions start and stop, and in case of a crash,
+the journal can replay the transactions to quickly put the partition back into
+a consistent state.
Handles represent a single atomic update to a filesystem. JBD can handle an
external journal on a block device.
@@ -164,7 +164,7 @@ written to the journal first, and then to its final location.
In the event of a crash, the journal can be replayed, bringing both data and
metadata into a consistent state. This mode is the slowest except when data
needs to be read from and written to disk at the same time where it
-outperforms all others modes.
+outperforms all other modes.
Compatibility
-------------
diff --git a/Documentation/filesystems/files.txt b/Documentation/filesystems/files.txt
index 133e213ebb7..bb0142f6108 100644
--- a/Documentation/filesystems/files.txt
+++ b/Documentation/filesystems/files.txt
@@ -76,13 +76,13 @@ the fdtable structure -
5. Handling of the file structures is special. Since the look-up
of the fd (fget()/fget_light()) are lock-free, it is possible
that look-up may race with the last put() operation on the
- file structure. This is avoided using the rcuref APIs
+ file structure. This is avoided using atomic_inc_not_zero()
on ->f_count :
rcu_read_lock();
file = fcheck_files(files, fd);
if (file) {
- if (rcuref_inc_lf(&file->f_count))
+ if (atomic_inc_not_zero(&file->f_count))
*fput_needed = 1;
else
/* Didn't get the reference, someone's freed */
@@ -92,7 +92,7 @@ the fdtable structure -
....
return file;
- rcuref_inc_lf() detects if refcounts is already zero or
+ atomic_inc_not_zero() detects if refcounts is already zero or
goes to zero during increment. If it does, we fail
fget()/fget_light().
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index e5c1df52a87..dec99455321 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -813,9 +813,9 @@ Various pieces of information about kernel activity are available in the
since the system first booted. For a quick look, simply cat the file:
> cat /proc/stat
- cpu 2255 34 2290 22625563 6290 127 456
- cpu0 1132 34 1441 11311718 3675 127 438
- cpu1 1123 0 849 11313845 2614 0 18
+ cpu 2255 34 2290 22625563 6290 127 456 0
+ cpu0 1132 34 1441 11311718 3675 127 438 0
+ cpu1 1123 0 849 11313845 2614 0 18 0
intr 114930548 113199788 3 0 5 263 0 4 [... lots more numbers ...]
ctxt 1990473
btime 1062191376
@@ -835,6 +835,7 @@ second). The meanings of the columns are as follows, from left to right:
- iowait: waiting for I/O to complete
- irq: servicing interrupts
- softirq: servicing softirqs
+- steal: involuntary wait
The "intr" line gives counts of interrupts serviced since boot time, for each
of the possible system interrupts. The first column is the total of all
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt
index 4b5ca26e504..4598ef7b622 100644
--- a/Documentation/filesystems/sysfs.txt
+++ b/Documentation/filesystems/sysfs.txt
@@ -51,7 +51,7 @@ for the attributes, providing a means to read and write kernel
attributes.
Attributes should be ASCII text files, preferably with only one value
-per file. It is noted that it may not be efficient to contain only
+per file. It is noted that it may not be efficient to contain only one
value per file, so it is socially acceptable to express an array of
values of the same type.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 6f8e16e3d6c..9d019d35728 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -706,7 +706,7 @@ struct address_space_operations {
wants to make it a free page. If ->releasepage succeeds, the
page will be removed from the address_space and become free.
- The second case if when a request has been made to invalidate
+ The second case is when a request has been made to invalidate
some or all pages in an address_space. This can happen
through the fadvice(POSIX_FADV_DONTNEED) system call or by the
filesystem explicitly requesting it as nfs and 9fs do (when
diff --git a/Documentation/i2c/i2c-protocol b/Documentation/i2c/i2c-protocol
index 579b92d5f3a..10518dd5881 100644
--- a/Documentation/i2c/i2c-protocol
+++ b/Documentation/i2c/i2c-protocol
@@ -68,7 +68,7 @@ We have found some I2C devices that needs the following modifications:
Flags I2C_M_IGNORE_NAK
Normally message is interrupted immediately if there is [NA] from the
- client. Setting this flag treats any [NA] as [A], and all of
+ client. Setting this flag treats any [NA] as [A], and all of
message is sent.
These messages may still fail to SCL lo->hi timeout.
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index 35985b34d5a..2f75e750e4f 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -168,6 +168,8 @@ Offset Proto Name Meaning
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
0235/3 N/A pad2 Unused
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
+023C/4 2.07+ hardware_subarch Hardware subarchitecture
+0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
(1) For backwards compatibility, if the setup_sects field contains 0, the
real value is 4.
@@ -204,7 +206,7 @@ boot loaders can ignore those fields.
The byte order of all fields is littleendian (this is x86, after all.)
-Field name: setup_secs
+Field name: setup_sects
Type: read
Offset/size: 0x1f1/1
Protocol: ALL
@@ -356,6 +358,13 @@ Protocol: 2.00+
- If 0, the protected-mode code is loaded at 0x10000.
- If 1, the protected-mode code is loaded at 0x100000.
+ Bit 6 (write): KEEP_SEGMENTS
+ Protocol: 2.07+
+ - if 0, reload the segment registers in the 32bit entry point.
+ - if 1, do not reload the segment registers in the 32bit entry point.
+ Assume that %cs %ds %ss %es are all set to flat segments with
+ a base of 0 (or the equivalent for their environment).
+
Bit 7 (write): CAN_USE_HEAP
Set this bit to 1 to indicate that the value entered in the
heap_end_ptr is valid. If this field is clear, some setup code
@@ -480,6 +489,29 @@ Protocol: 2.06+
cmdline_size characters. With protocol version 2.05 and earlier, the
maximum size was 255.
+Field name: hardware_subarch
+Type: write
+Offset/size: 0x23c/4
+Protocol: 2.07+
+
+ In a paravirtualized environment the hardware low level architectural
+ pieces such as interrupt handling, page table handling, and
+ accessing process control registers needs to be done differently.
+
+ This field allows the bootloader to inform the kernel we are in one
+ one of those environments.
+
+ 0x00000000 The default x86/PC environment
+ 0x00000001 lguest
+ 0x00000002 Xen
+
+Field name: hardware_subarch_data
+Type: write
+Offset/size: 0x240/8
+Protocol: 2.07+
+
+ A pointer to data that is specific to hardware subarch
+
**** THE KERNEL COMMAND LINE
diff --git a/Documentation/ia64/err_inject.txt b/Documentation/ia64/err_inject.txt
index 6449a7090db..223e4f0582d 100644
--- a/Documentation/ia64/err_inject.txt
+++ b/Documentation/ia64/err_inject.txt
@@ -21,10 +21,10 @@ software test suits to do stressful testing on IPF.
Below is a sample application as part of the whole tool. The sample
can be used as a working test tool. Or it can be expanded to include
-more features. It also can be a integrated into a libary or other user
+more features. It also can be a integrated into a library or other user
application to have more thorough test.
-The sample application takes err.conf as error configuation input. Gcc
+The sample application takes err.conf as error configuration input. GCC
compiles the code. After you install err_inject driver, you can run
this sample application to inject errors.
@@ -809,7 +809,7 @@ int err_inj()
}
/* Create semaphore: If one_lock, one semaphore for all processors.
- Otherwise, one sempaphore for each processor. */
+ Otherwise, one semaphore for each processor. */
if (one_lock) {
if (create_sem(0)) {
printf("Can not create semaphore...exit\n");
diff --git a/Documentation/input/atarikbd.txt b/Documentation/input/atarikbd.txt
index ab050621e20..f3a3ba8847b 100644
--- a/Documentation/input/atarikbd.txt
+++ b/Documentation/input/atarikbd.txt
@@ -170,7 +170,7 @@ major controller faults (ROM checksum and RAM test) and such things as stuck
keys. Any keys down at power-up are presumed to be stuck, and their BREAK
(sic) code is returned (which without the preceding MAKE code is a flag for a
keyboard error). If the controller self-test completes without error, the code
-0xF0 is returned. (This code will be used to indicate the version/rlease of
+0xF0 is returned. (This code will be used to indicate the version/release of
the ikbd controller. The first release of the ikbd is version 0xF0, should
there be a second release it will be 0xF1, and so on.)
The ikbd defaults to a mouse position reporting with threshold of 1 unit in
@@ -413,7 +413,7 @@ INTERROGATION MODE.
%nnnnmmmm ; where m is JOYSTICK1 state
; and n is JOYSTICK0 state
-Sets the ikbd to do nothing but monitor the serial command lne, maintain the
+Sets the ikbd to do nothing but monitor the serial command line, maintain the
time-of-day clock, and monitor the joystick. The rate sets the interval
between joystick samples.
N.B. The user should not set the rate higher than the serial communications
@@ -446,10 +446,10 @@ The sample interval should be as constant as possible.
; until vertical cursor key is generated before RY
; has elapsed
VX ; length (in tenths of seconds) of joystick closure
- ; until horizontal cursor keystokes are generated
+ ; until horizontal cursor keystrokes are generated
; after RX has elapsed
VY ; length (in tenths of seconds) of joystick closure
- ; until vertical cursor keystokes are generated
+ ; until vertical cursor keystrokes are generated
; after RY has elapsed
In this mode, joystick 0 is scanned in a way that simulates cursor keystrokes.
diff --git a/Documentation/input/ff.txt b/Documentation/input/ff.txt
index 085eb15b45b..ded4d5f5310 100644
--- a/Documentation/input/ff.txt
+++ b/Documentation/input/ff.txt
@@ -1,5 +1,5 @@
Force feedback for Linux.
-By Johann Deneux <deneux@ifrance.com> on 2001/04/22.
+By Johann Deneux <johann.deneux@gmail.com> on 2001/04/22.
Updated by Anssi Hannula <anssi.hannula@gmail.com> on 2006/04/09.
You may redistribute this file. Please remember to include shape.fig and
interactive.fig as well.
diff --git a/Documentation/input/iforce-protocol.txt b/Documentation/input/iforce-protocol.txt
index 8777d2d321e..3ac92413c87 100644
--- a/Documentation/input/iforce-protocol.txt
+++ b/Documentation/input/iforce-protocol.txt
@@ -4,10 +4,10 @@ specify force effects to I-Force 2.0 devices. None of this information comes
from Immerse. That's why you should not trust what is written in this
document. This document is intended to help understanding the protocol.
This is not a reference. Comments and corrections are welcome. To contact me,
-send an email to: deneux@ifrance.com
+send an email to: johann.deneux@gmail.com
** WARNING **
-I may not be held responsible for any dammage or harm caused if you try to
+I shall not be held responsible for any damage or harm caused if you try to
send data to your I-Force device based on what you read in this document.
** Preliminary Notes:
@@ -151,13 +151,13 @@ OP= ff
Query command. Length varies according to the query type.
The general format of this packet is:
ff 01 QUERY [INDEX] CHECKSUM
-reponses are of the same form:
+responses are of the same form:
FF LEN QUERY VALUE_QUERIED CHECKSUM2
where LEN = 1 + length(VALUE_QUERIED)
**** Query ram size ****
QUERY = 42 ('B'uffer size)
-The device should reply with the same packet plus two additionnal bytes
+The device should reply with the same packet plus two additional bytes
containing the size of the memory:
ff 03 42 03 e8 CS would mean that the device has 1000 bytes of ram available.
@@ -234,19 +234,23 @@ is the amount of memory apparently needed for every set of parameters:
** Appendix: How to study the protocol ? **
-1. Generate effects using the force editor provided with the DirectX SDK, or use Immersion Studio (freely available at their web site in the developer section: www.immersion.com)
-2. Start a soft spying RS232 or USB (depending on where you connected your joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
+1. Generate effects using the force editor provided with the DirectX SDK, or
+use Immersion Studio (freely available at their web site in the developer section:
+www.immersion.com)
+2. Start a soft spying RS232 or USB (depending on where you connected your
+joystick/wheel). I used ComPortSpy from fCoder (alpha version!)
3. Play the effect, and watch what happens on the spy screen.
A few words about ComPortSpy:
-At first glance, this soft seems, hum, well... buggy. In fact, data appear with a few seconds latency. Personnaly, I restart it every time I play an effect.
+At first glance, this software seems, hum, well... buggy. In fact, data appear with a
+few seconds latency. Personally, I restart it every time I play an effect.
Remember it's free (as in free beer) and alpha!
** URLS **
Check www.immerse.com for Immersion Studio, and www.fcoder.com for ComPortSpy.
** Author of this document **
-Johann Deneux <deneux@ifrance.com>
+Johann Deneux <johann.deneux@gmail.com>
Home page at http://www.esil.univ-mrs.fr/~jdeneux/projects/ff/
Additions by Vojtech Pavlik.
diff --git a/Documentation/input/input-programming.txt b/Documentation/input/input-programming.txt
index d9d523099bb..47fc86830cd 100644
--- a/Documentation/input/input-programming.txt
+++ b/Documentation/input/input-programming.txt
@@ -42,8 +42,8 @@ static int __init button_init(void)
goto err_free_irq;
}
- button_dev->evbit[0] = BIT(EV_KEY);
- button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+ button_dev->evbit[0] = BIT_MASK(EV_KEY);
+ button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
error = input_register_device(button_dev);
if (error) {
@@ -79,7 +79,7 @@ In the _init function, which is called either upon module load or when
booting the kernel, it grabs the required resources (it should also check
for the presence of the device).
-Then it allocates a new input device structure with input_aloocate_device()
+Then it allocates a new input device structure with input_allocate_device()
and sets up input bitfields. This way the device driver tells the other
parts of the input systems what it is - what events can be generated or
accepted by this input device. Our example device can only generate EV_KEY
@@ -217,14 +217,15 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean
that the thing is precise and always returns to exactly the center position
(if it has any).
-1.4 NBITS(), LONG(), BIT()
+1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK()
~~~~~~~~~~~~~~~~~~~~~~~~~~
-These three macros from input.h help some bitfield computations:
+These three macros from bitops.h help some bitfield computations:
- NBITS(x) - returns the length of a bitfield array in longs for x bits
- LONG(x) - returns the index in the array in longs for bit x
- BIT(x) - returns the index in a long for bit x
+ BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for
+ x bits
+ BIT_WORD(x) - returns the index in the array in longs for bit x
+ BIT_MASK(x) - returns the index in a long for bit x
1.5 The id* and name fields
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/isdn/CREDITS b/Documentation/isdn/CREDITS
index 7c17c837064..8cac6c2f23e 100644
--- a/Documentation/isdn/CREDITS
+++ b/Documentation/isdn/CREDITS
@@ -40,7 +40,7 @@ Andreas Kool (akool@Kool.f.EUnet.de)
Pedro Roque Marques (roque@di.fc.ul.pt)
For lot of new ideas and the pcbit driver.
-Eberhard Moenkeberg (emoenke@gwdg.de)
+Eberhard Mönkeberg (emoenke@gwdg.de)
For testing and help to get into kernel.
Thomas Neumann (tn@ruhr.de)
diff --git a/Documentation/isdn/README.concap b/Documentation/isdn/README.concap
index 2f114babe4b..a76d74845a4 100644
--- a/Documentation/isdn/README.concap
+++ b/Documentation/isdn/README.concap
@@ -111,7 +111,7 @@ struct concap_proto_ops{
struct concap_proto * (*proto_new) (void);
/* delete encapsulation protocol instance and free all its resources.
- cprot may no loger be referenced after calling this */
+ cprot may no longer be referenced after calling this */
void (*proto_del)(struct concap_proto *cprot);
/* initialize the protocol's data. To be called at interface startup
diff --git a/Documentation/java.txt b/Documentation/java.txt
index 3cce3fbb664..e6a72328154 100644
--- a/Documentation/java.txt
+++ b/Documentation/java.txt
@@ -37,7 +37,7 @@ other program after you have done the following:
or the following, if you want to be more selective:
':Applet:M::<!--applet::/usr/bin/appletviewer:'
- Of cause you have to fix the path names. Given path/file names in this
+ Of course you have to fix the path names. The path/file names given in this
document match the Debian 2.1 system. (i.e. jdk installed in /usr,
custom wrappers from this document in /usr/local)
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index fe8b0c4892c..616043a6da9 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -77,7 +77,12 @@ applicable everywhere (see syntax).
Optionally, dependencies only for this default value can be added with
"if".
-- dependencies: "depends on"/"requires" <expr>
+- type definition + default value:
+ "def_bool"/"def_tristate" <expr> ["if" <expr>]
+ This is a shorthand notation for a type definition plus a value.
+ Optionally dependencies for this default value can be added with "if".
+
+- dependencies: "depends on" <expr>
This defines a dependency for this menu entry. If multiple
dependencies are defined, they are connected with '&&'. Dependencies
are applied to all other options within this menu entry (which also
@@ -289,3 +294,10 @@ source:
"source" <prompt>
This reads the specified configuration file. This file is always parsed.
+
+mainmenu:
+
+ "mainmenu" <prompt>
+
+This sets the config program's title bar if the config program chooses
+to use it.
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index f099b814d38..7a7753321a2 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -518,6 +518,28 @@ more details, with real examples.
In this example for a specific GCC version the build will error out explaining
to the user why it stops.
+ cc-cross-prefix
+ cc-cross-prefix is used to check if there exists a $(CC) in path with
+ one of the listed prefixes. The first prefix where there exist a
+ prefix$(CC) in the PATH is returned - and if no prefix$(CC) is found
+ then nothing is returned.
+ Additional prefixes are separated by a single space in the
+ call of cc-cross-prefix.
+ This functionality is useful for architecture Makefiles that try
+ to set CROSS_COMPILE to well-known values but may have several
+ values to select between.
+ It is recommended only to try to set CROSS_COMPILE if it is a cross
+ build (host arch is different from target arch). And if CROSS_COMPILE
+ is already set then leave it with the old value.
+
+ Example:
+ #arch/m68k/Makefile
+ ifneq ($(SUBARCH),$(ARCH))
+ ifeq ($(CROSS_COMPILE),)
+ CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu-)
+ endif
+ endif
+
=== 4 Host Program support
Kbuild supports building executables on the host for use during the
diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt
index 1b37b28cc23..d0ac72cc19f 100644
--- a/Documentation/kdump/kdump.txt
+++ b/Documentation/kdump/kdump.txt
@@ -231,6 +231,32 @@ Dump-capture kernel config options (Arch Dependent, ia64)
any space below the alignment point will be wasted.
+Extended crashkernel syntax
+===========================
+
+While the "crashkernel=size[@offset]" syntax is sufficient for most
+configurations, sometimes it's handy to have the reserved memory dependent
+on the value of System RAM -- that's mostly for distributors that pre-setup
+the kernel command line to avoid a unbootable system after some memory has
+been removed from the machine.
+
+The syntax is:
+
+ crashkernel=<range1>:<size1>[,<range2>:<size2>,...][@offset]
+ range=start-[end]
+
+For example:
+
+ crashkernel=512M-2G:64M,2G-:128M
+
+This would mean:
+
+ 1) if the RAM is smaller than 512M, then don't reserve anything
+ (this is the "rescue" case)
+ 2) if the RAM size is between 512M and 2G, then reserve 64M
+ 3) if the RAM size is larger than 2G, then reserve 128M
+
+
Boot into System Kernel
=======================
diff --git a/Documentation/kernel-docs.txt b/Documentation/kernel-docs.txt
index d9e3b199929..5a4ef48224a 100644
--- a/Documentation/kernel-docs.txt
+++ b/Documentation/kernel-docs.txt
@@ -76,9 +76,9 @@
* Title: "Conceptual Architecture of the Linux Kernel"
Author: Ivan T. Bowman.
URL: http://plg.uwaterloo.ca/~itbowman/papers/CS746G-a1.html
- Keywords: conceptual software arquitecture, extracted design,
+ Keywords: conceptual software architecture, extracted design,
reverse engineering, system structure.
- Description: Conceptual software arquitecture of the Linux kernel,
+ Description: Conceptual software architecture of the Linux kernel,
automatically extracted from the source code. Very detailed. Good
figures. Gives good overall kernel understanding.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 189df0bcab9..b2361667839 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -222,9 +222,6 @@ and is between 256 and 4096 characters. It is defined in the file
Warning: Many of these options can produce a lot of
output and make your system unusable. Be very careful.
-
- acpi_fake_ecdt [HW,ACPI] Workaround failure due to BIOS lacking ECDT
-
acpi_pm_good [X86-32,X86-64]
Override the pmtimer bug detection: force the kernel
to assume that this machine's pmtimer latches its value
@@ -297,9 +294,6 @@ and is between 256 and 4096 characters. It is defined in the file
apm= [APM] Advanced Power Management
See header of arch/i386/kernel/apm.c.
- applicom= [HW]
- Format: <mem>,<irq>
-
arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards
Format: <io>,<irq>,<nodeID>
@@ -345,12 +339,6 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <io>,<irq>,<mode>
See header of drivers/net/hamradio/baycom_ser_hdx.c.
- blkmtd_device= [HW,MTD]
- blkmtd_erasesz=
- blkmtd_ro=
- blkmtd_bs=
- blkmtd_count=
-
boot_delay= Milliseconds to delay each printk during boot.
Values larger than 10 seconds (10000) are changed to
no delay (0).
@@ -431,8 +419,10 @@ and is between 256 and 4096 characters. It is defined in the file
over the 8254 in addition to over the IO-APIC. The
kernel tries to set a sensible default.
- hpet= [X86-32,HPET] option to disable HPET and use PIT.
- Format: disable
+ hpet= [X86-32,HPET] option to control HPET usage
+ Format: { enable (default) | disable | force }
+ disable: disable HPET and use PIT instead
+ force: allow force enabled of undocumented chips (ICH4, VIA)
com20020= [HW,NET] ARCnet - COM20020 chipset
Format:
@@ -497,6 +487,13 @@ and is between 256 and 4096 characters. It is defined in the file
[KNL] Reserve a chunk of physical memory to
hold a kernel to switch to with kexec on panic.
+ crashkernel=range1:size1[,range2:size2,...][@offset]
+ [KNL] Same as above, but depends on the memory
+ in the running system. The syntax of range is
+ start-[end] where start and end are both
+ a memory unit (amount[KMG]). See also
+ Documentation/kdump/kdump.txt for a example.
+
cs4232= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>
@@ -506,8 +503,6 @@ and is between 256 and 4096 characters. It is defined in the file
cs89x0_media= [HW,NET]
Format: { rj45 | aui | bnc }
- cyclades= [HW,SERIAL] Cyclades multi-serial port adapter.
-
dasd= [HW,NET]
See header of drivers/s390/block/dasd_devmap.c.
@@ -565,10 +560,6 @@ and is between 256 and 4096 characters. It is defined in the file
See drivers/char/README.epca and
Documentation/digiepca.txt.
- dmascc= [HW,AX25,SERIAL] AX.25 Z80SCC driver with DMA
- support available.
- Format: <io_dev0>[,<io_dev1>[,..<io_dev32>]]
-
dmasound= [HW,OSS] Sound subsystem buffers
dscc4.setup= [NET]
@@ -599,17 +590,10 @@ and is between 256 and 4096 characters. It is defined in the file
0: polling mode
non-0: interrupt mode (default)
- eda= [HW,PS2]
-
- edb= [HW,PS2]
-
edd= [EDD]
Format: {"of[f]" | "sk[ipmbr]"}
See comment in arch/i386/boot/edd.S
- eicon= [HW,ISDN]
- Format: <id>,<membase>,<irq>
-
eisa_irq_edge= [PARISC,HW]
See header of drivers/parisc/eisa.c.
@@ -788,6 +772,23 @@ and is between 256 and 4096 characters. It is defined in the file
inttest= [IA64]
+ intel_iommu= [DMAR] Intel IOMMU driver (DMAR) option
+ off
+ Disable intel iommu driver.
+ igfx_off [Default Off]
+ By default, gfx is mapped as normal device. If a gfx
+ device has a dedicated DMAR unit, the DMAR unit is
+ bypassed by not enabling DMAR with this option. In
+ this case, gfx device will use physical address for
+ DMA.
+ forcedac [x86_64]
+ With this option iommu will not optimize to look
+ for io virtual address below 32 bit forcing dual
+ address cycle on pci bus for cards supporting greater
+ than 32 bit addressing. The default is to look
+ for translation below 32 bit and if not available
+ then look in the higher range.
+
io7= [HW] IO7 for Marvel based alpha systems
See comment before marvel_specify_io7 in
arch/alpha/kernel/core_marvel.c.
@@ -885,9 +886,6 @@ and is between 256 and 4096 characters. It is defined in the file
lapic_timer_c2_ok [X86-32,x86-64,APIC] trust the local apic timer in
C2 power state.
- lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip
- Format: addr:<io>,irq:<irq>
-
libata.noacpi [LIBATA] Disables use of ACPI in libata suspend/resume
when set.
Format: <int>
@@ -1135,9 +1133,6 @@ and is between 256 and 4096 characters. It is defined in the file
noapic [SMP,APIC] Tells the kernel to not make use of any
IOAPICs that may be present in the system.
- noasync [HW,M68K] Disables async and sync negotiation for
- all devices.
-
nobats [PPC] Do not use BATs for mapping kernel lowmem
on "Classic" PPC cores.
@@ -1449,6 +1444,7 @@ and is between 256 and 4096 characters. It is defined in the file
Param: <number> - step/bucket size as a power of 2 for
statistical time based profiling.
Param: "sleep" - profile D-state sleeping (millisecs)
+ Param: "kvm" - profile VM exits.
processor.max_cstate= [HW,ACPI]
Limit processor to maximum C-state
@@ -1575,9 +1571,6 @@ and is between 256 and 4096 characters. It is defined in the file
sa1100ir [NET]
See drivers/net/irda/sa1100_ir.c.
- sb= [HW,OSS]
- Format: <io>,<irq>,<dma>,<dma2>
-
sbni= [NET] Granch SBNI12 leased line adapter
sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver
@@ -1621,8 +1614,6 @@ and is between 256 and 4096 characters. It is defined in the file
serialnumber [BUGS=X86-32]
- sg_def_reserved_size= [SCSI]
-
shapers= [NET]
Maximal number of shapers.
@@ -2013,10 +2004,6 @@ and is between 256 and 4096 characters. It is defined in the file
norandmaps Don't use address space randomization
Equivalent to echo 0 > /proc/sys/kernel/randomize_va_space
- unwind_debug=N N > 0 will enable dwarf2 unwinder debugging
- This is useful to get more information why
- you got a "dwarf2 unwinder stuck"
-
______________________________________________________________________
TODO:
diff --git a/Documentation/m68k/kernel-options.txt b/Documentation/m68k/kernel-options.txt
index 8a523f6af48..248589e8bcf 100644
--- a/Documentation/m68k/kernel-options.txt
+++ b/Documentation/m68k/kernel-options.txt
@@ -890,10 +890,7 @@ Syntax: nosync:0
5.5.2) noasync
--------------
-Syntax: noasync:0
-
- Disables async and sync negotiation for all devices. Any value
- after the colon is acceptable (and has the same effect).
+[OBSOLETE, REMOVED]
5.5.3) nodisconnect
-------------------
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
new file mode 100644
index 00000000000..295a71bc301
--- /dev/null
+++ b/Documentation/markers.txt
@@ -0,0 +1,81 @@
+ Using the Linux Kernel Markers
+
+ Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Markers and their use. It provides
+examples of how to insert markers in the kernel and connect probe functions to
+them and provides some examples of probe functions.
+
+
+* Purpose of markers
+
+A marker placed in code provides a hook to call a function (probe) that you can
+provide at runtime. A marker can be "on" (a probe is connected to it) or "off"
+(no probe is attached). When a marker is "off" it has no effect, except for
+adding a tiny time penalty (checking a condition for a branch) and space
+penalty (adding a few bytes for the function call at the end of the
+instrumented function and adds a data structure in a separate section). When a
+marker is "on", the function you provide is called each time the marker is
+executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the marker site).
+
+You can put markers at important locations in the code. Markers are
+lightweight hooks that can pass an arbitrary number of parameters,
+described in a printk-like format string, to the attached probe function.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+In order to use the macro trace_mark, you should include linux/marker.h.
+
+#include <linux/marker.h>
+
+And,
+
+trace_mark(subsystem_event, "%d %s", someint, somestring);
+Where :
+- subsystem_event is an identifier unique to your event
+ - subsystem is the name of your subsystem.
+ - event is the name of the event to mark.
+- "%d %s" is the formatted string for the serializer.
+- someint is an integer.
+- somestring is a char pointer.
+
+Connecting a function (probe) to a marker is done by providing a probe (function
+to call) for the specific marker through marker_probe_register() and can be
+activated by calling marker_arm(). Marker deactivation can be done by calling
+marker_disarm() as many times as marker_arm() has been called. Removing a probe
+is done through marker_probe_unregister(); it will disarm the probe and make
+sure there is no caller left using the probe when it returns. Probe removal is
+preempt-safe because preemption is disabled around the probe call. See the
+"Probe example" section below for a sample probe module.
+
+The marker mechanism supports inserting multiple instances of the same marker.
+Markers can be put in inline functions, inlined static functions, and
+unrolled loops as well as regular functions.
+
+The naming scheme "subsystem_event" is suggested here as a convention intended
+to limit collisions. Marker names are global to the kernel: they are considered
+as being the same whether they are in the core kernel image or in modules.
+Conflicting format strings for markers with the same name will cause the markers
+to be detected to have a different format string not to be armed and will output
+a printk warning which identifies the inconsistency:
+
+"Format mismatch for probe probe_name (format), marker (format)"
+
+
+* Probe / marker example
+
+See the example provided in samples/markers/src
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe marker-example (insmod order is not important)
+modprobe probe-example
+cat /proc/marker-example (returns an expected error)
+rmmod marker-example probe-example
+dmesg
diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt
index 5fbcc22c98e..168117bd6ee 100644
--- a/Documentation/memory-hotplug.txt
+++ b/Documentation/memory-hotplug.txt
@@ -2,7 +2,8 @@
Memory Hotplug
==============
-Last Updated: Jul 28 2007
+Created: Jul 28 2007
+Add description of notifier of memory hotplug Oct 11 2007
This document is about memory hotplug including how-to-use and current status.
Because Memory Hotplug is still under development, contents of this text will
@@ -24,7 +25,8 @@ be changed often.
6.1 Memory offline and ZONE_MOVABLE
6.2. How to offline memory
7. Physical memory remove
-8. Future Work List
+8. Memory hotplug event notifier
+9. Future Work List
Note(1): x86_64's has special implementation for memory hotplug.
This text does not describe it.
@@ -307,8 +309,58 @@ Need more implementation yet....
- Notification completion of remove works by OS to firmware.
- Guard from remove if not yet.
+--------------------------------
+8. Memory hotplug event notifier
+--------------------------------
+Memory hotplug has event notifer. There are 6 types of notification.
+
+MEMORY_GOING_ONLINE
+ Generated before new memory becomes available in order to be able to
+ prepare subsystems to handle memory. The page allocator is still unable
+ to allocate from the new memory.
+
+MEMORY_CANCEL_ONLINE
+ Generated if MEMORY_GOING_ONLINE fails.
+
+MEMORY_ONLINE
+ Generated when memory has succesfully brought online. The callback may
+ allocate pages from the new memory.
+
+MEMORY_GOING_OFFLINE
+ Generated to begin the process of offlining memory. Allocations are no
+ longer possible from the memory but some of the memory to be offlined
+ is still in use. The callback can be used to free memory known to a
+ subsystem from the indicated memory section.
+
+MEMORY_CANCEL_OFFLINE
+ Generated if MEMORY_GOING_OFFLINE fails. Memory is available again from
+ the section that we attempted to offline.
+
+MEMORY_OFFLINE
+ Generated after offlining memory is complete.
+
+A callback routine can be registered by
+ hotplug_memory_notifier(callback_func, priority)
+
+The second argument of callback function (action) is event types of above.
+The third argument is passed by pointer of struct memory_notify.
+
+struct memory_notify {
+ unsigned long start_pfn;
+ unsigned long nr_pages;
+ int status_cahnge_nid;
+}
+
+start_pfn is start_pfn of online/offline memory.
+nr_pages is # of pages of online/offline memory.
+status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be)
+set/clear. It means a new(memoryless) node gets new memory by online and a
+node loses all memory. If this is -1, then nodemask status is not changed.
+If status_changed_nid >= 0, callback should create/discard structures for the
+node if necessary.
+
--------------
-8. Future Work
+9. Future Work
--------------
- allowing memory hot-add to ZONE_MOVABLE. maybe we need some switch like
sysctl or new control file.
diff --git a/Documentation/mips/00-INDEX b/Documentation/mips/00-INDEX
index 9df8a2eac7b..3f13bf8043d 100644
--- a/Documentation/mips/00-INDEX
+++ b/Documentation/mips/00-INDEX
@@ -4,5 +4,3 @@ AU1xxx_IDE.README
- README for MIPS AU1XXX IDE driver.
GT64120.README
- README for dir with info on MIPS boards using GT-64120 or GT-64120A.
-time.README
- - README for MIPS time services.
diff --git a/Documentation/mips/AU1xxx_IDE.README b/Documentation/mips/AU1xxx_IDE.README
index afb31c141d9..5c8334123f4 100644
--- a/Documentation/mips/AU1xxx_IDE.README
+++ b/Documentation/mips/AU1xxx_IDE.README
@@ -59,7 +59,7 @@ Four configs variables are introduced:
CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA - enable the PIO+DBDMA mode
CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - enable the MWDMA mode
CONFIG_BLK_DEV_IDE_AU1XXX_BURSTABLE_ON - set Burstable FIFO in DBDMA
- controler
+ controller
CONFIG_BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ - maximum transfer size
per descriptor
diff --git a/Documentation/mips/time.README b/Documentation/mips/time.README
deleted file mode 100644
index a4ce603ed3b..00000000000
--- a/Documentation/mips/time.README
+++ /dev/null
@@ -1,173 +0,0 @@
-README for MIPS time services
-
-Jun Sun
-jsun@mvista.com or jsun@junsun.net
-
-
-ABOUT
------
-This file describes the new arch/mips/kernel/time.c, related files and the
-services they provide.
-
-If you are short in patience and just want to know how to use time.c for a
-new board or convert an existing board, go to the last section.
-
-
-FILES, COMPATABILITY AND CONFIGS
----------------------------------
-
-The old arch/mips/kernel/time.c is renamed to old-time.c.
-
-A new time.c is put there, together with include/asm-mips/time.h.
-
-Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C.
-So we allow boards using
-
- 1) old time.c (CONFIG_OLD_TIME_C)
- 2) new time.c (CONFIG_NEW_TIME_C)
- 3) neither (their own private time.c)
-
-However, it is expected every board will move to the new time.c in the near
-future.
-
-
-WHAT THE NEW CODE PROVIDES?
----------------------------
-
-The new time code provide the following services:
-
- a) Implements functions required by Linux common code:
- time_init
-
- b) provides an abstraction of RTC and null RTC implementation as default.
- extern unsigned long (*rtc_get_time)(void);
- extern int (*rtc_set_time)(unsigned long);
-
- c) high-level and low-level timer interrupt routines where the timer
- interrupt source may or may not be the CPU timer. The high-level
- routine is dispatched through do_IRQ() while the low-level is
- dispatched in assemably code (usually int-handler.S)
-
-
-WHAT THE NEW CODE REQUIRES?
----------------------------
-
-For the new code to work properly, each board implementation needs to supply
-the following functions or values:
-
- a) board_time_init - a function pointer. Invoked at the beginnig of
- time_init(). It is optional.
- 1. (optional) set up RTC routines
- 2. (optional) calibrate and set the mips_hpt_frequency
-
- b) plat_timer_setup - a function pointer. Invoked at the end of time_init()
- 1. (optional) over-ride any decisions made in time_init()
- 2. set up the irqaction for timer interrupt.
- 3. enable the timer interrupt
-
- c) (optional) board-specific RTC routines.
-
- d) (optional) mips_hpt_frequency - It must be definied if the board
- is using CPU counter for timer interrupt.
-
-
-PORTING GUIDE
--------------
-
-Step 1: decide how you like to implement the time services.
-
- a) does this board have a RTC? If yes, implement the two RTC funcs.
-
- b) does the CPU have counter/compare registers?
-
- If the answer is no, you need a timer to provide the timer interrupt
- at 100 HZ speed.
-
- c) The following sub steps assume your CPU has counter register.
- Do you plan to use the CPU counter register as the timer interrupt
- or use an exnternal timer?
-
- In order to use CPU counter register as the timer interrupt source, you
- must know the counter speed (mips_hpt_frequency). It is usually the
- same as the CPU speed or an integral divisor of it.
-
- d) decide on whether you want to use high-level or low-level timer
- interrupt routines. The low-level one is presumably faster, but should
- not make too mcuh difference.
-
-
-Step 2: the machine setup() function
-
- If you supply board_time_init(), set the function poointer.
-
-
-Step 3: implement rtc routines, board_time_init() and plat_timer_setup()
- if needed.
-
- board_time_init() -
- a) (optional) set up RTC routines,
- b) (optional) calibrate and set the mips_hpt_frequency
- (only needed if you intended to use cpu counter as timer interrupt
- source)
-
- plat_timer_setup() -
- a) (optional) over-write any choices made above by time_init().
- b) machine specific code should setup the timer irqaction.
- c) enable the timer interrupt
-
-
- If the RTC chip is a common chip, I suggest the routines are put under
- arch/mips/libs. For example, for DS1386 chip, one would create
- rtc-ds1386.c under arch/mips/lib directory. Add the following line to
- the arch/mips/lib/Makefile:
-
- obj-$(CONFIG_DDB5476) += rtc-ds1386.o
-
-Step 4: if you are using low-level timer interrupt, change your interrupt
- dispathcing code to check for timer interrupt and jump to
- ll_timer_interrupt() directly if one is detected.
-
-Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine.
- Modify the appropriate defconfig if applicable.
-
-Final notes:
-
-For some tricky cases, you may need to add your own wrapper functions
-for some of the functions in time.c.
-
-For example, you may define your own timer interrupt routine, which does
-some of its own processing and then calls timer_interrupt().
-
-You can also over-ride any of the built-in functions (RTC routines
-and/or timer interrupt routine).
-
-
-PORTING NOTES FOR SMP
-----------------------
-
-If you have a SMP box, things are slightly more complicated.
-
-The time service running every jiffy is logically divided into two parts:
-
- 1) the one for the whole system (defined in timer_interrupt())
- 2) the one that should run for each CPU (defined in local_timer_interrupt())
-
-You need to decide on your timer interrupt sources.
-
- case 1) - whole system has only one timer interrupt delivered to one CPU
-
- In this case, you set up timer interrupt as in UP systems. In addtion,
- you need to set emulate_local_timer_interrupt to 1 so that other
- CPUs get to call local_timer_interrupt().
-
- THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write
- one should such a need arise. You simply make a IPI call.
-
- case 2) - each CPU has a separate timer interrupt
-
- In this case, you need to set up IRQ such that each of them will
- call local_timer_interrupt(). In addition, you need to arrange
- one and only one of them to call timer_interrupt().
-
- You can also do the low-level version of those interrupt routines,
- following similar dispatching routes described above.
diff --git a/Documentation/mutex-design.txt b/Documentation/mutex-design.txt
index 51f935191ae..aa60d1f627e 100644
--- a/Documentation/mutex-design.txt
+++ b/Documentation/mutex-design.txt
@@ -133,4 +133,6 @@ the APIs of 'struct mutex' have been streamlined:
int mutex_trylock(struct mutex *lock);
void mutex_unlock(struct mutex *lock);
int mutex_is_locked(struct mutex *lock);
-
+ void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
+ int mutex_lock_interruptible_nested(struct mutex *lock,
+ unsigned int subclass);
diff --git a/Documentation/networking/bcm43xx.txt b/Documentation/networking/bcm43xx.txt
index a136721499b..d602c8d6ff3 100644
--- a/Documentation/networking/bcm43xx.txt
+++ b/Documentation/networking/bcm43xx.txt
@@ -37,7 +37,7 @@ all, distributions. There is, however, additional software that is
required. The firmware used by the chip is the intellectual property
of Broadcom and they have not given the bcm43xx team redistribution
rights to this firmware. Since we cannot legally redistribute
-the firwmare we cannot include it with the driver. Furthermore, it
+the firmware we cannot include it with the driver. Furthermore, it
cannot be placed in the downloadable archives of any distributing
organization; therefore, the user is responsible for obtaining the
firmware and placing it in the appropriate location so that the driver
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 6ae2feff308..747a5d15d52 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -293,7 +293,7 @@ tcp_no_metrics_save - BOOLEAN
when the connection closes, so that connections established in the
near future can use these to set initial conditions. Usually, this
increases overall performance, but may sometimes cause performance
- degredation. If set, TCP will not cache metrics on closing
+ degradation. If set, TCP will not cache metrics on closing
connections.
tcp_orphan_retries - INTEGER
diff --git a/Documentation/networking/rxrpc.txt b/Documentation/networking/rxrpc.txt
index c36b64b0020..c3669a3fb4a 100644
--- a/Documentation/networking/rxrpc.txt
+++ b/Documentation/networking/rxrpc.txt
@@ -689,7 +689,7 @@ such as the AFS filesystem. This permits such a utility to:
buffers manipulated directly.
To use the RxRPC facility, a kernel utility must still open an AF_RXRPC socket,
-bind an addess as appropriate and listen if it's to be a server socket, but
+bind an address as appropriate and listen if it's to be a server socket, but
then it passes this to the kernel interface functions.
The kernel interface functions are as follows:
diff --git a/Documentation/networking/udplite.txt b/Documentation/networking/udplite.txt
index 6be09ba24a3..b6409cab075 100644
--- a/Documentation/networking/udplite.txt
+++ b/Documentation/networking/udplite.txt
@@ -12,7 +12,7 @@
For in-depth information, you can consult:
o The UDP-Lite Homepage: http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/
- Fom here you can also download some example application source code.
+ From here you can also download some example application source code.
o The UDP-Lite HOWTO on
http://www.erg.abdn.ac.uk/users/gerrit/udp-lite/files/UDP-Lite-HOWTO.txt
@@ -223,7 +223,7 @@
While it is important that such cases are dealt with correctly, they
are (annoyingly) rare: UDP-Lite is designed for optimising multimedia
performance over wireless (or generally noisy) links and thus smaller
- coverage lenghts are likely to be expected.
+ coverage lengths are likely to be expected.
V) UDP-LITE RUNTIME STATISTICS AND THEIR MEANING
@@ -259,7 +259,7 @@
VI) IPTABLES
There is packet match support for UDP-Lite as well as support for the LOG target.
- If you copy and paste the following line into /etc/protcols,
+ If you copy and paste the following line into /etc/protocols,
udplite 136 UDP-Lite # UDP-Lite [RFC 3828]
diff --git a/Documentation/power/swsusp-and-swap-files.txt b/Documentation/power/swsusp-and-swap-files.txt
index 06f911a5f88..f281886de49 100644
--- a/Documentation/power/swsusp-and-swap-files.txt
+++ b/Documentation/power/swsusp-and-swap-files.txt
@@ -39,7 +39,7 @@ resume=<swap_file_partition> resume_offset=<swap_file_offset>
where <swap_file_partition> is the partition on which the swap file is located
and <swap_file_offset> is the offset of the swap header determined by the
application in 2) (of course, this step may be carried out automatically
-by the same application that determies the swap file's header offset using the
+by the same application that determines the swap file's header offset using the
FIBMAP ioctl)
OR
diff --git a/Documentation/powerpc/eeh-pci-error-recovery.txt b/Documentation/powerpc/eeh-pci-error-recovery.txt
index 4530d1bf028..df7afe43d46 100644
--- a/Documentation/powerpc/eeh-pci-error-recovery.txt
+++ b/Documentation/powerpc/eeh-pci-error-recovery.txt
@@ -36,8 +36,8 @@ Causes of EEH Errors
EEH was originally designed to guard against hardware failure, such
as PCI cards dying from heat, humidity, dust, vibration and bad
electrical connections. The vast majority of EEH errors seen in
-"real life" are due to eithr poorly seated PCI cards, or,
-unfortunately quite commonly, due device driver bugs, device firmware
+"real life" are due to either poorly seated PCI cards, or,
+unfortunately quite commonly, due to device driver bugs, device firmware
bugs, and sometimes PCI card hardware bugs.
The most common software bug, is one that causes the device to
diff --git a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
index e59fcbbe338..5e03610e186 100644
--- a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
+++ b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
@@ -17,12 +17,12 @@ passed by the boot loader to the kernel at boot time. The device tree
describes what devices are present on the board and how they are
connected. The device tree can either be passed as a binary blob (as
described in Documentation/powerpc/booting-without-of.txt), or passed
-by Open Firmare (IEEE 1275) compatible firmware using an OF compatible
+by Open Firmware (IEEE 1275) compatible firmware using an OF compatible
client interface API.
This document specifies the requirements on the device-tree for mpc5200
based boards. These requirements are above and beyond the details
-specified in either the OpenFirmware spec or booting-without-of.txt
+specified in either the Open Firmware spec or booting-without-of.txt
All new mpc5200-based boards are expected to match this document. In
cases where this document is not sufficient to support a new board port,
@@ -73,8 +73,8 @@ match on the compatible list; the 'most compatible' driver should be
selected.
The split between the MPC5200 and the MPC5200B leaves a bit of a
-connundrum. How should the compatible property be set up to provide
-maximum compatability information; but still acurately describe the
+conundrum. How should the compatible property be set up to provide
+maximum compatibility information; but still accurately describe the
chip? For the MPC5200; the answer is easy. Most of the SoC devices
originally appeared on the MPC5200. Since they didn't exist anywhere
else; the 5200 compatible properties will contain only one item;
@@ -84,7 +84,7 @@ The 5200B is almost the same as the 5200, but not quite. It fixes
silicon bugs and it adds a small number of enhancements. Most of the
devices either provide exactly the same interface as on the 5200. A few
devices have extra functions but still have a backwards compatible mode.
-To express this infomation as completely as possible, 5200B device trees
+To express this information as completely as possible, 5200B device trees
should have two items in the compatible list;
"mpc5200b-<device>\0mpc5200-<device>". It is *strongly* recommended
that 5200B device trees follow this convention (instead of only listing
@@ -185,7 +185,7 @@ bestcomm@<addr> dma-controller mpc5200-bestcomm 5200 pic also requires
Recommended soc5200 child nodes; populate as needed for your board
name device_type compatible Description
---- ----------- ---------- -----------
-gpt@<addr> gpt mpc5200-gpt General purpose timers
+gpt@<addr> gpt fsl,mpc5200-gpt General purpose timers
rtc@<addr> rtc mpc5200-rtc Real time clock
mscan@<addr> mscan mpc5200-mscan CAN bus controller
pci@<addr> pci mpc5200-pci PCI bridge
@@ -199,7 +199,7 @@ ethernet@<addr> network mpc5200-fec MPC5200 ethernet device
ata@<addr> ata mpc5200-ata IDE ATA interface
i2c@<addr> i2c mpc5200-i2c I2C controller
usb@<addr> usb-ohci-be mpc5200-ohci,ohci-be USB controller
-xlb@<addr> xlb mpc5200-xlb XLB arbritrator
+xlb@<addr> xlb mpc5200-xlb XLB arbitrator
Important child node properties
name type description
@@ -213,7 +213,7 @@ cell-index int When multiple devices are present, is the
5) General Purpose Timer nodes (child of soc5200 node)
On the mpc5200 and 5200b, GPT0 has a watchdog timer function. If the board
design supports the internal wdt, then the device node for GPT0 should
-include the empty property 'has-wdt'.
+include the empty property 'fsl,has-wdt'.
6) PSC nodes (child of soc5200 node)
PSC nodes can define the optional 'port-number' property to force assignment
diff --git a/Documentation/scsi/aic79xx.txt b/Documentation/scsi/aic79xx.txt
index 6aa9a891f3d..683ccae00ad 100644
--- a/Documentation/scsi/aic79xx.txt
+++ b/Documentation/scsi/aic79xx.txt
@@ -120,7 +120,7 @@ The following information is available in this file:
list size to avoid SCSI malloc pool fragmentation.
- Cleanup channel display in our /proc output.
- Workaround duplicate device entries in the mid-layer
- devlice list during add-single-device.
+ device list during add-single-device.
1.3.6 (March 28th, 2003)
- Correct a double free in the Domain Validation code.
diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt
index 5f34d2ba69b..b7e238cbb5a 100644
--- a/Documentation/scsi/aic7xxx.txt
+++ b/Documentation/scsi/aic7xxx.txt
@@ -159,7 +159,7 @@ The following information is available in this file:
- Add support for 2.5.X's scsi_report_device_reset().
6.2.34 (May 5th, 2003)
- - Fix locking regression instroduced in 6.2.29 that
+ - Fix locking regression introduced in 6.2.29 that
could cause a lock order reversal between the io_request_lock
and our per-softc lock. This was only possible on RH9,
SuSE, and kernel.org 2.4.X kernels.
@@ -264,7 +264,7 @@ The following information is available in this file:
Option: tag_info:{{value[,value...]}[,{value[,value...]}...]}
Definition: Set the per-target tagged queue depth on a
per controller basis. Both controllers and targets
- may be ommitted indicating that they should retain
+ may be omitted indicating that they should retain
the default tag depth.
Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}
On Controller 0
@@ -290,7 +290,7 @@ The following information is available in this file:
-----------------------------------------------------------------
Option: dv: {value[,value...]}
Definition: Set Domain Validation Policy on a per-controller basis.
- Controllers may be ommitted indicating that
+ Controllers may be omitted indicating that
they should retain the default read streaming setting.
Example: dv:{-1,0,,1,1,0}
On Controller 0 leave DV at its default setting.
diff --git a/Documentation/scsi/arcmsr_spec.txt b/Documentation/scsi/arcmsr_spec.txt
index 5e0042340fd..45d9482c151 100644
--- a/Documentation/scsi/arcmsr_spec.txt
+++ b/Documentation/scsi/arcmsr_spec.txt
@@ -3,7 +3,7 @@
*******************************************************************************
** Usage of IOP331 adapter
** (All In/Out is in IOP331's view)
-** 1. Message 0 --> InitThread message and retrun code
+** 1. Message 0 --> InitThread message and return code
** 2. Doorbell is used for RS-232 emulation
** inDoorBell : bit0 -- data in ready
** (DRIVER DATA WRITE OK)
diff --git a/Documentation/scsi/ibmmca.txt b/Documentation/scsi/ibmmca.txt
index a08e225653d..a810421f1fb 100644
--- a/Documentation/scsi/ibmmca.txt
+++ b/Documentation/scsi/ibmmca.txt
@@ -21,7 +21,7 @@
versions older than 4.0 do not work with kernels 2.4.0 or later! If you
try to compile your kernel with the wrong driver source, the
compilation is aborted and you get a corresponding error message. This is
- no bug in the driver. It prevents you from using the wrong sourcecode
+ no bug in the driver; it prevents you from using the wrong source code
with the wrong kernel version.
Authors of this Driver
@@ -58,7 +58,7 @@
5 Users' Manual
5.1 Commandline Parameters
5.2 Troubleshooting
- 5.3 Bugreports
+ 5.3 Bug reports
5.4 Support WWW-page
6 References
7 Credits to
@@ -71,13 +71,13 @@
1 Abstract
----------
- This README-file describes the IBM SCSI-subsystem low level driver for
- Linux. The descriptions which were formerly kept in the source-code have
- been taken out to this file to easify the codes' readability. The driver
+ This README-file describes the IBM SCSI-subsystem low level driver for
+ Linux. The descriptions which were formerly kept in the source code have
+ been taken out of this file to simplify the codes readability. The driver
description has been updated, as most of the former description was already
- quite outdated. The history of the driver development is also kept inside
- here. Multiple historical developments have been summarized to shorten the
- textsize a bit. At the end of this file you can find a small manual for
+ quite outdated. The history of the driver development is also kept inside
+ here. Multiple historical developments have been summarized to shorten the
+ text size a bit. At the end of this file you can find a small manual for
this driver and hints to get it running on your machine.
2 Driver Description
@@ -186,7 +186,7 @@
between 0 and 7). The IBM SCSI-2 F/W adapter offers this on up to two
busses and provides support for 30 logical devices at the same time, where
in wide-addressing mode you can have 16 puns with 32 luns on each device.
- This section dexribes you the handling of devices on non-F/W adapters.
+ This section describes the handling of devices on non-F/W adapters.
Just imagine, that you can have 16 * 32 = 512 devices on a F/W adapter
which means a lot of possible devices for such a small machine.
@@ -209,10 +209,10 @@
--------------------------------------------------------
One consequence of information hiding is that the real (pun,lun)
numbers are also hidden. The two possibilities to get around this problem
- is to offer fake pun/lun combinations to the operating system or to
+ are to offer fake pun/lun combinations to the operating system or to
delete the whole mapping of the adapter and to reassign the ldns, using
the immediate assign command of the SCSI-subsystem for probing through
- all possible pun/lun combinations. a ldn is a "logical device number"
+ all possible pun/lun combinations. An ldn is a "logical device number"
which is used by IBM SCSI-subsystems to access some valid SCSI-device.
At the beginning of the development of this driver, the following approach
was used:
@@ -251,9 +251,9 @@
lun>0 or to non-existing devices, in order to satisfy the subsystem, if
there are less than 15 SCSI-devices connected. In the case of more than 15
devices, the dynamical mapping goes active. If the get_scsi[][] reports a
- device to be existant, but it has no ldn assigned, it gets a ldn out of 7
- to 14. The numbers are assigned in cyclic order. Therefore it takes 8
- dynamical reassignments on the SCSI-devices, until a certain device
+ device to be existent, but it has no ldn assigned, it gets an ldn out of 7
+ to 14. The numbers are assigned in cyclic order, therefore it takes 8
+ dynamical reassignments on the SCSI-devices until a certain device
loses its ldn again. This assures that dynamical remapping is avoided
during intense I/O between up to 15 SCSI-devices (means pun,lun
combinations). A further advantage of this method is that people who
@@ -551,7 +551,7 @@
than devices are available, they are assigned to non existing pun,lun
combinations to satisfy the adapter. With this, the dynamical mapping
was possible to implement. (For further info see the text in the
- source-code and in the description below. Read the description
+ source code and in the description below. Read the description
below BEFORE installing this driver on your system!)
2) Changed the name IBMMCA_DRIVER_VERSION to IBMMCA_SCSI_DRIVER_VERSION.
3) The LED-display shows on PS/2-95 no longer the ldn, but the SCSI-ID
@@ -762,9 +762,9 @@
- Michael Lang
Apr 23, 2000 (v3.2pre1)
- 1) During a very long time, I collected a huge amount of bugreports from
+ 1) During a very long time, I collected a huge amount of bug reports from
various people, trying really quite different things on their SCSI-
- PS/2s. Today, all these bugreports are taken into account and should be
+ PS/2s. Today, all these bug reports are taken into account and should be
mostly solved. The major topics were:
- Driver crashes during boottime by no obvious reason.
- Driver panics while the midlevel-SCSI-driver is trying to inquire
@@ -819,7 +819,7 @@
- Michael Lang
July 17, 2000 (v3.2pre8)
- A long period of collecting bugreports from all corners of the world
+ A long period of collecting bug reports from all corners of the world
now lead to the following corrections to the code:
1) SCSI-2 F/W support crashed with a COMMAND ERROR. The reason for this
was that it is possible to disable Fast-SCSI for the external bus.
@@ -873,7 +873,7 @@
July 26, 2000 (v3.2pre11)
1) I passed a horrible weekend getting mad with NMIs on kernel 2.2.14 and
a model 9595. Asking around in the community, nobody except of me has
- seen such errors. Weired, but I am trying to recompile everything on
+ seen such errors. Weird, but I am trying to recompile everything on
the model 9595. Maybe, as I use a specially modified gcc, that could
cause problems. But, it was not the reason. The true background was,
that the kernel was compiled for i386 and the 9595 has a 486DX-2.
@@ -886,7 +886,7 @@
alive rotator during boottime. This makes sense, when no monitor is
connected to the system. You can get rid of all display activity, if
you do not use any parameter or just ibmmcascsi=activity, for the
- harddrive activity LED, existant on all PS/2, except models 8595-XXX.
+ harddrive activity LED, existent on all PS/2, except models 8595-XXX.
If no monitor is available, please use ibmmcascsi=display, which works
fine together with the linuxinfo utility for the LED-panel.
- Michael Lang
@@ -1115,7 +1115,7 @@
If this really happens, do also send e-mail to the maintainer, as
forced detection should be never necessary. Forced detection is in
principal some flaw of the driver adapter detection and goes into
- bugreports.
+ bug reports.
Q: The driver screws up, if it starts to probe SCSI-devices, is there
some way out of it?
A: Yes, that was some recognition problem of the correct SCSI-adapter
@@ -1172,7 +1172,7 @@
recommended version is 3.2 or later. Here, the F/W support is in
a stable and reliable condition. Wide-addressing is in addition
supported.
- Q: I get a Ooops message and something like "killing interrupt".
+ Q: I get an Oops message and something like "killing interrupt".
A: The reason for this is that the IBM SCSI-subsystem only sends a
termination status back, if some error appeared. In former releases
of the driver, it was not checked, if the termination status block
@@ -1213,21 +1213,21 @@
problem. Not yet tried, but guessing that it could work. To get this,
set unchecked_isa_dma argument of ibmmca.h from 0 to 1.
- 5.3 Bugreports
+ 5.3 Bug reports
--------------
- If you really find bugs in the sourcecode or the driver will successfully
+ If you really find bugs in the source code or the driver will successfully
refuse to work on your machine, you should send a bug report to me. The
best for this is to follow the instructions on the WWW-page for this
driver. Fill out the bug-report form, placed on the WWW-page and ship it,
so the bugs can be taken into account with maximum efforts. But, please
do not send bug reports about this driver to Linus Torvalds or Leonard
- Zubkoff, as Linus is burried in E-Mail and Leonard is supervising all
+ Zubkoff, as Linus is buried in E-Mail and Leonard is supervising all
SCSI-drivers and won't have the time left to look inside every single
driver to fix a bug and especially DO NOT send modified code to Linus
Torvalds or Alan J. Cox which has not been checked here!!! They are both
- quite burried in E-mail (as me, sometimes, too) and one should first check
+ quite buried in E-mail (as me, sometimes, too) and one should first check
for problems on my local teststand. Recently, I got a lot of
- bugreports for errors in the ibmmca.c code, which I could not imagine, but
+ bug reports for errors in the ibmmca.c code, which I could not imagine, but
a look inside some Linux-distribution showed me quite often some modified
code, which did no longer work on most other machines than the one of the
modifier. Ok, so now that there is maintenance service available for this
@@ -1261,7 +1261,7 @@
some e-mail directly, but at least with the same information as required by
the formular.
- If you have extensive bugreports, including Ooops messages and
+ If you have extensive bug reports, including Oops messages and
screen-shots, please feel free to send it directly to the address
of the maintainer, too. The current address of the maintainer is:
@@ -1318,7 +1318,7 @@
detailed bug reports and ideas for this driver (and his
patience ;-)).
Alan J. Cox
- for his bugreports and his bold activities in cross-checking
+ for his bug reports and his bold activities in cross-checking
the driver-code with his teststand.
7.2 Sponsors & Supporters
diff --git a/Documentation/sharedsubtree.txt b/Documentation/sharedsubtree.txt
index ccf1cebe744..736540045dc 100644
--- a/Documentation/sharedsubtree.txt
+++ b/Documentation/sharedsubtree.txt
@@ -153,6 +153,7 @@ replicas continue to be exactly same.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+ #include <string.h>
#include <sys/mount.h>
#include <sys/fsuid.h>
diff --git a/Documentation/sound/alsa/soc/DAI.txt b/Documentation/sound/alsa/soc/DAI.txt
index 58cbfd01ea8..3feeb9ecdec 100644
--- a/Documentation/sound/alsa/soc/DAI.txt
+++ b/Documentation/sound/alsa/soc/DAI.txt
@@ -20,12 +20,12 @@ I2S
===
I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
-Rx lines are used for audio transmision, whilst the bit clock (BCLK) and
+Rx lines are used for audio transmission, whilst the bit clock (BCLK) and
left/right clock (LRC) synchronise the link. I2S is flexible in that either the
controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
usually varies depending on the sample rate and the master system clock
(SYSCLK). LRCLK is the same as the sample rate. A few devices support separate
-ADC and DAC LRCLK's, this allows for similtanious capture and playback at
+ADC and DAC LRCLK's, this allows for simultaneous capture and playback at
different sample rates.
I2S has several different operating modes:-
@@ -41,12 +41,12 @@ I2S has several different operating modes:-
PCM
===
-PCM is another 4 wire interface, very similar to I2S, that can support a more
+PCM is another 4 wire interface, very similar to I2S, which can support a more
flexible protocol. It has bit clock (BCLK) and sync (SYNC) lines that are used
to synchronise the link whilst the Tx and Rx lines are used to transmit and
receive the audio data. Bit clock usually varies depending on sample rate
whilst sync runs at the sample rate. PCM also supports Time Division
-Multiplexing (TDM) in that several devices can use the bus similtaniuosly (This
+Multiplexing (TDM) in that several devices can use the bus simultaneously (this
is sometimes referred to as network mode).
Common PCM operating modes:-
diff --git a/Documentation/sound/alsa/soc/clocking.txt b/Documentation/sound/alsa/soc/clocking.txt
index e93960d53a1..14930887c25 100644
--- a/Documentation/sound/alsa/soc/clocking.txt
+++ b/Documentation/sound/alsa/soc/clocking.txt
@@ -2,20 +2,20 @@ Audio Clocking
==============
This text describes the audio clocking terms in ASoC and digital audio in
-general. Note: Audio clocking can be complex !
+general. Note: Audio clocking can be complex!
Master Clock
------------
-Every audio subsystem is driven by a master clock (sometimes refered to as MCLK
+Every audio subsystem is driven by a master clock (sometimes referred to as MCLK
or SYSCLK). This audio master clock can be derived from a number of sources
(e.g. crystal, PLL, CPU clock) and is responsible for producing the correct
audio playback and capture sample rates.
-Some master clocks (e.g. PLL's and CPU based clocks) are configuarble in that
+Some master clocks (e.g. PLL's and CPU based clocks) are configurable in that
their speed can be altered by software (depending on the system use and to save
-power). Other master clocks are fixed at at set frequency (i.e. crystals).
+power). Other master clocks are fixed at a set frequency (i.e. crystals).
DAI Clocks
@@ -44,7 +44,7 @@ This relationship depends on the codec or SoC CPU in particular. In general
it's best to configure BCLK to the lowest possible speed (depending on your
rate, number of channels and wordsize) to save on power.
-It's also desireable to use the codec (if possible) to drive (or master) the
+It's also desirable to use the codec (if possible) to drive (or master) the
audio clocks as it's usually gives more accurate sample rates than the CPU.
diff --git a/Documentation/sound/alsa/soc/codec.txt b/Documentation/sound/alsa/soc/codec.txt
index 48983c75aad..1e766ad0ebd 100644
--- a/Documentation/sound/alsa/soc/codec.txt
+++ b/Documentation/sound/alsa/soc/codec.txt
@@ -19,7 +19,7 @@ Optionally, codec drivers can also provide:-
6) DAPM event handler.
7) DAC Digital mute control.
-It's probably best to use this guide in conjuction with the existing codec
+It's probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/
ASoC Codec driver breakdown
@@ -28,7 +28,7 @@ ASoC Codec driver breakdown
1 - Codec DAI and PCM configuration
-----------------------------------
Each codec driver must have a struct snd_soc_codec_dai to define it's DAI and
-PCM's capablities and operations. This struct is exported so that it can be
+PCM's capabilities and operations. This struct is exported so that it can be
registered with the core by your machine driver.
e.g.
@@ -67,7 +67,7 @@ EXPORT_SYMBOL_GPL(wm8731_dai);
2 - Codec control IO
--------------------
-The codec can ususally be controlled via an I2C or SPI style interface (AC97
+The codec can usually be controlled via an I2C or SPI style interface (AC97
combines control with data in the DAI). The codec drivers will have to provide
functions to read and write the codec registers along with supplying a register
cache:-
diff --git a/Documentation/sound/alsa/soc/dapm.txt b/Documentation/sound/alsa/soc/dapm.txt
index c11877f5b4a..ab0766fd786 100644
--- a/Documentation/sound/alsa/soc/dapm.txt
+++ b/Documentation/sound/alsa/soc/dapm.txt
@@ -11,7 +11,7 @@ other PM systems.
DAPM is also completely transparent to all user space applications as all power
switching is done within the ASoC core. No code changes or recompiling are
-required for user space applications. DAPM makes power switching descisions based
+required for user space applications. DAPM makes power switching decisions based
upon any audio stream (capture/playback) activity and audio mixer settings
within the device.
@@ -38,7 +38,7 @@ There are 4 power domains within DAPM
Enabled and disabled when stream playback/capture is started and
stopped respectively. e.g. aplay, arecord.
-All DAPM power switching descisons are made automatically by consulting an audio
+All DAPM power switching decisions are made automatically by consulting an audio
routing map of the whole machine. This map is specific to each machine and
consists of the interconnections between every audio component (including
internal codec components). All audio components that effect power are called
diff --git a/Documentation/sound/alsa/soc/overview.txt b/Documentation/sound/alsa/soc/overview.txt
index 753c5cc5984..c47ce953067 100644
--- a/Documentation/sound/alsa/soc/overview.txt
+++ b/Documentation/sound/alsa/soc/overview.txt
@@ -2,18 +2,19 @@ ALSA SoC Layer
==============
The overall project goal of the ALSA System on Chip (ASoC) layer is to provide
-better ALSA support for embedded system on chip procesors (e.g. pxa2xx, au1x00,
+better ALSA support for embedded system-on-chip processors (e.g. pxa2xx, au1x00,
iMX, etc) and portable audio codecs. Currently there is some support in the
kernel for SoC audio, however it has some limitations:-
* Currently, codec drivers are often tightly coupled to the underlying SoC
- cpu. This is not ideal and leads to code duplication i.e. Linux now has 4
+ CPU. This is not ideal and leads to code duplication i.e. Linux now has 4
different wm8731 drivers for 4 different SoC platforms.
- * There is no standard method to signal user initiated audio events.
- e.g. Headphone/Mic insertion, Headphone/Mic detection after an insertion
- event. These are quite common events on portable devices and ofter require
- machine specific code to re route audio, enable amps etc after such an event.
+ * There is no standard method to signal user initiated audio events (e.g.
+ Headphone/Mic insertion, Headphone/Mic detection after an insertion
+ event). These are quite common events on portable devices and often require
+ machine specific code to re-route audio, enable amps, etc., after such an
+ event.
* Current drivers tend to power up the entire codec when playing
(or recording) audio. This is fine for a PC, but tends to waste a lot of
@@ -44,7 +45,7 @@ features :-
signals the codec when to change power states.
* Machine specific controls: Allow machines to add controls to the sound card
- e.g. volume control for speaker amp.
+ (e.g. volume control for speaker amp).
To achieve all this, ASoC basically splits an embedded audio system into 3
components :-
@@ -57,7 +58,7 @@ components :-
interface drivers (e.g. I2S, AC97, PCM) for that platform.
* Machine driver: The machine driver handles any machine specific controls and
- audio events. i.e. turing on an amp at start of playback.
+ audio events (e.g. turning on an amp at start of playback).
Documentation
diff --git a/Documentation/sound/alsa/soc/platform.txt b/Documentation/sound/alsa/soc/platform.txt
index e95b16d5a53..d4678b4dc6c 100644
--- a/Documentation/sound/alsa/soc/platform.txt
+++ b/Documentation/sound/alsa/soc/platform.txt
@@ -20,7 +20,7 @@ struct snd_soc_ops {
int (*trigger)(struct snd_pcm_substream *, int);
};
-The platform driver exports it's DMA functionailty via struct snd_soc_platform:-
+The platform driver exports its DMA functionality via struct snd_soc_platform:-
struct snd_soc_platform {
char *name;
diff --git a/Documentation/sound/alsa/soc/pops_clicks.txt b/Documentation/sound/alsa/soc/pops_clicks.txt
index 2cf7ee5b3d7..3371bd9d7cf 100644
--- a/Documentation/sound/alsa/soc/pops_clicks.txt
+++ b/Documentation/sound/alsa/soc/pops_clicks.txt
@@ -2,7 +2,7 @@ Audio Pops and Clicks
=====================
Pops and clicks are unwanted audio artifacts caused by the powering up and down
-of components within the audio subsystem. This is noticable on PC's when an
+of components within the audio subsystem. This is noticeable on PCs when an
audio module is either loaded or unloaded (at module load time the sound card is
powered up and causes a popping noise on the speakers).
@@ -16,7 +16,7 @@ Minimising Playback Pops and Clicks
===================================
Playback pops in portable audio subsystems cannot be completely eliminated atm,
-however future audio codec hardware will have better pop and click supression.
+however future audio codec hardware will have better pop and click suppression.
Pops can be reduced within playback by powering the audio components in a
specific order. This order is different for startup and shutdown and follows
some basic rules:-
@@ -33,7 +33,7 @@ Minimising Capture Pops and Clicks
==================================
Capture artifacts are somewhat easier to get rid as we can delay activating the
-ADC until all the pops have occured. This follows similar power rules to
+ADC until all the pops have occurred. This follows similar power rules to
playback in that components are powered in a sequence depending upon stream
startup or shutdown.
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index 215e3b8e726..f3853cc37bd 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -1,4 +1,4 @@
-PXA2xx SPI on SSP driver HOWTO
+PXA2xx SPI on SSP driver HOWTO
===================================================
This a mini howto on the pxa2xx_spi driver. The driver turns a PXA2xx
synchronous serial port into a SPI master controller
diff --git a/Documentation/thinkpad-acpi.txt b/Documentation/thinkpad-acpi.txt
index 60953d6c919..ec499265dec 100644
--- a/Documentation/thinkpad-acpi.txt
+++ b/Documentation/thinkpad-acpi.txt
@@ -105,10 +105,15 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver
as a driver attribute (see below).
Sysfs driver attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/.
+for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and
+/sys/bus/platform/drivers/thinkpad_hwmon/
-Sysfs device attributes are on the driver's sysfs attribute space,
-for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/.
+Sysfs device attributes are on the thinkpad_acpi device sysfs attribute
+space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/.
+
+Sysfs device attributes for the sensors and fan are on the
+thinkpad_hwmon device's sysfs attribute space, but you should locate it
+looking for a hwmon device with the name attribute of "thinkpad".
Driver version
--------------
@@ -766,7 +771,7 @@ Temperature sensors
-------------------
procfs: /proc/acpi/ibm/thermal
-sysfs device attributes: (hwmon) temp*_input
+sysfs device attributes: (hwmon "thinkpad") temp*_input
Most ThinkPads include six or more separate temperature sensors but only
expose the CPU temperature through the standard ACPI methods. This
@@ -989,7 +994,9 @@ Fan control and monitoring: fan speed, fan enable/disable
---------------------------------------------------------
procfs: /proc/acpi/ibm/fan
-sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable
+sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1,
+ pwm1_enable
+sysfs hwmon driver attributes: fan_watchdog
NOTE NOTE NOTE: fan control operations are disabled by default for
safety reasons. To enable them, the module parameter "fan_control=1"
@@ -1028,7 +1035,7 @@ enable it if necessary to avoid overheating.
An enabled fan in level "auto" may stop spinning if the EC decides the
ThinkPad is cool enough and doesn't need the extra airflow. This is
-normal, and the EC will spin the fan up if the varios thermal readings
+normal, and the EC will spin the fan up if the various thermal readings
rise too much.
On the X40, this seems to depend on the CPU and HDD temperatures.
@@ -1131,7 +1138,7 @@ hwmon device attribute fan1_input:
which can take up to two minutes. May return rubbish on older
ThinkPads.
-driver attribute fan_watchdog:
+hwmon driver attribute fan_watchdog:
Fan safety watchdog timer interval, in seconds. Minimum is
1 second, maximum is 120 seconds. 0 disables the watchdog.
@@ -1196,7 +1203,7 @@ for example:
Enabling debugging output
-------------------------
-The module takes a debug paramater which can be used to selectively
+The module takes a debug parameter which can be used to selectively
enable various classes of debugging output, for example:
modprobe ibm_acpi debug=0xffff
@@ -1233,3 +1240,9 @@ Sysfs interface changelog:
layer, the radio switch generates input event EV_RADIO,
and the driver enables hot key handling by default in
the firmware.
+
+0x020000: ABI fix: added a separate hwmon platform device and
+ driver, which must be located by name (thinkpad)
+ and the hwmon class for libsensors4 (lm-sensors 3)
+ compatibility. Moved all hwmon attributes to this
+ new platform device.
diff --git a/Documentation/usb/usb-serial.txt b/Documentation/usb/usb-serial.txt
index 4e0b62b8566..8b077e43eee 100644
--- a/Documentation/usb/usb-serial.txt
+++ b/Documentation/usb/usb-serial.txt
@@ -338,7 +338,7 @@ MCT USB Single Port Serial Adapter U232
This driver is for the MCT USB-RS232 Converter (25 pin, Model No.
U232-P25) from Magic Control Technology Corp. (there is also a 9 pin
Model No. U232-P9). More information about this device can be found at
- the manufacture's web-site: http://www.mct.com.tw.
+ the manufacturer's web-site: http://www.mct.com.tw.
The driver is generally working, though it still needs some more testing.
It is derived from the Belkin USB Serial Adapter F5U103 driver and its
diff --git a/MAINTAINERS b/MAINTAINERS
index 2534dc4aa95..40245af2d0e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1963,11 +1963,6 @@ M: adaplas@gmail.com
L: linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
S: Maintained
-INTEL APIC/IOAPIC, LOWLEVEL X86 SMP SUPPORT
-P: Ingo Molnar
-M: mingo@redhat.com
-S: Maintained
-
INTEL I8XX RANDOM NUMBER GENERATOR SUPPORT
P: Jeff Garzik
M: jgarzik@pobox.com
@@ -2178,7 +2173,7 @@ S: Maintained
KCONFIG
P: Roman Zippel
M: zippel@linux-m68k.org
-L: kbuild-devel@lists.sourceforge.net
+L: linux-kbuild@vger.kernel.org
S: Maintained
KDUMP
@@ -2207,6 +2202,7 @@ KERNEL BUILD (kbuild: Makefile, scripts/Makefile.*)
P: Sam Ravnborg
M: sam@ravnborg.org
T: git kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
+L: linux-kbuild@vger.kernel.org
S: Maintained
KERNEL JANITORS
@@ -2342,6 +2338,8 @@ L: linuxppc-dev@ozlabs.org
S: Maintained
LINUX FOR POWERPC EMBEDDED PPC8XX
+P: Vitaly Bordug
+M: vitb@kernel.crashing.org
P: Marcelo Tosatti
M: marcelo@kvack.org
W: http://www.penguinppc.org/
@@ -4268,9 +4266,15 @@ M: jacmet@sunsite.dk
L: linux-serial@vger.kernel.org
S: Maintained
-X86 3-LEVEL PAGING (PAE) SUPPORT
+X86 ARCHITECTURE (32-BIT AND 64-BIT)
+P: Thomas Gleixner
+M: tglx@linutronix.de
P: Ingo Molnar
M: mingo@redhat.com
+P: H. Peter Anvin
+M: hpa@zytor.com
+L: linux-kernel@vger.kernel.org
+T: git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86.git
S: Maintained
YAM DRIVER FOR AX.25
diff --git a/Makefile b/Makefile
index 529b9048d97..264f37b8b26 100644
--- a/Makefile
+++ b/Makefile
@@ -774,6 +774,9 @@ vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o
ifdef CONFIG_HEADERS_CHECK
$(Q)$(MAKE) -f $(srctree)/Makefile headers_check
endif
+ifdef CONFIG_SAMPLES
+ $(Q)$(MAKE) $(build)=samples
+endif
$(call vmlinux-modpost)
$(call if_changed_rule,vmlinux__)
$(Q)rm -f .old_version
@@ -884,10 +887,7 @@ prepare2: prepare3 outputmakefile
prepare1: prepare2 include/linux/version.h include/linux/utsrelease.h \
include/asm include/config/auto.conf
-ifneq ($(KBUILD_MODULES),)
- $(Q)mkdir -p $(MODVERDIR)
- $(Q)rm -f $(MODVERDIR)/*
-endif
+ $(cmd_crmodverdir)
archprepare: prepare1 scripts_basic
@@ -903,14 +903,24 @@ prepare: prepare0
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
-# FIXME: The asm symlink changes when $(ARCH) changes. That's
-# hard to detect, but I suppose "make mrproper" is a good idea
-# before switching between archs anyway.
-
-include/asm:
- @echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'
- $(Q)if [ ! -d include ]; then mkdir -p include; fi;
- @ln -fsn asm-$(SRCARCH) $@
+# The asm symlink changes when $(ARCH) changes.
+# Detect this and ask user to run make mrproper
+
+include/asm: FORCE
+ $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \
+ if [ -L include/asm ]; then \
+ if [ "$$asmlink" != "$(SRCARCH)" ]; then \
+ echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \
+ echo " set ARCH or save .config and run 'make mrproper' to fix it"; \
+ exit 1; \
+ fi; \
+ else \
+ echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \
+ if [ ! -d include ]; then \
+ mkdir -p include; \
+ fi; \
+ ln -fsn asm-$(SRCARCH) $@; \
+ fi
# Generate some files
# ---------------------------------------------------------------------------
@@ -1020,19 +1030,12 @@ _modinst_:
fi
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
-# If System.map exists, run depmod. This deliberately does not have a
-# dependency on System.map since that would run the dependency tree on
-# vmlinux. This depmod is only for convenience to give the initial
+# This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write. However the
# boot script depmod is the master version.
-ifeq "$(strip $(INSTALL_MOD_PATH))" ""
-depmod_opts :=
-else
-depmod_opts := -b $(INSTALL_MOD_PATH) -r
-endif
PHONY += _modinst_post
_modinst_post: _modinst_
- if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+ $(call cmd,depmod)
else # CONFIG_MODULES
@@ -1220,8 +1223,7 @@ else # KBUILD_EXTMOD
KBUILD_MODULES := 1
PHONY += crmodverdir
crmodverdir:
- $(Q)mkdir -p $(MODVERDIR)
- $(Q)rm -f $(MODVERDIR)/*
+ $(cmd_crmodverdir)
PHONY += $(objtree)/Module.symvers
$(objtree)/Module.symvers:
@@ -1249,15 +1251,6 @@ _emodinst_:
$(Q)mkdir -p $(MODLIB)/$(install-dir)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
-# Run depmod only is we have System.map and depmod is executable
-quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
- cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
- $(DEPMOD) -ae -F System.map \
- $(if $(strip $(INSTALL_MOD_PATH)), \
- -b $(INSTALL_MOD_PATH) -r) \
- $(KERNELRELEASE); \
- fi
-
PHONY += _emodinst_post
_emodinst_post: _emodinst_
$(call cmd,depmod)
@@ -1341,7 +1334,7 @@ define find-sources
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
-name $1 -print; \
find $(__srctree) $(RCS_FIND_IGNORE) \
- \( -name include -o -name arch \) -prune -o \
+ \( -name include -o -name arch -o -name '.tmp_*' \) -prune -o \
-name $1 -print; \
)
endef
@@ -1490,9 +1483,11 @@ endif
# Modules
/ %/: prepare scripts FORCE
+ $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir)
%.ko: prepare scripts FORCE
+ $(cmd_crmodverdir)
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
@@ -1506,6 +1501,20 @@ quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN $(wildcard $(rm-dirs)))
quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN $(wildcard $(rm-files)))
cmd_rmfiles = rm -f $(rm-files)
+# Run depmod only is we have System.map and depmod is executable
+# and we build for the host arch
+quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
+ cmd_depmod = \
+ if [ -r System.map -a -x $(DEPMOD) ]; then \
+ $(DEPMOD) -ae -F System.map \
+ $(if $(strip $(INSTALL_MOD_PATH)), -b $(INSTALL_MOD_PATH) -r) \
+ $(KERNELRELEASE); \
+ fi
+
+# Create temporary dir for module support files
+# clean it up only when building all modules
+cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \
+ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*)
a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \
$(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 2a85dc33907..4c002ba37e5 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -654,7 +654,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/alpha/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/alpha/Kconfig.debug"
diff --git a/arch/alpha/kernel/err_marvel.c b/arch/alpha/kernel/err_marvel.c
index f2956ac8dcc..497877bf201 100644
--- a/arch/alpha/kernel/err_marvel.c
+++ b/arch/alpha/kernel/err_marvel.c
@@ -1082,7 +1082,7 @@ marvel_machine_check(u64 vector, u64 la_ptr)
}
/*
- * A system event or error has occured, handle it here.
+ * A system event or error has occurred, handle it here.
*
* Any errors in the logout frame have already been cleared by the
* PALcode, so just parse it.
diff --git a/arch/alpha/kernel/err_titan.c b/arch/alpha/kernel/err_titan.c
index 543d96d7fa2..6f3867877d9 100644
--- a/arch/alpha/kernel/err_titan.c
+++ b/arch/alpha/kernel/err_titan.c
@@ -591,7 +591,7 @@ privateer_process_680_frame(struct el_common *mchk_header, int print)
(struct el_PRIVATEER_envdata_mcheck *)
((unsigned long)mchk_header + mchk_header->sys_offset);
- /* TODO - catagorize errors, for now, no error */
+ /* TODO - categorize errors, for now, no error */
if (!print)
return status;
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ce857158c1e..6413c5f2322 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -715,7 +715,7 @@ osf_setsysinfo(unsigned long op, void __user *buffer, unsigned long nbytes,
/*
* Alpha Architecture Handbook 4.7.7.3:
* To be fully IEEE compiant, we must track the current IEEE
- * exception state in software, because spurrious bits can be
+ * exception state in software, because spurious bits can be
* set in the trap shadow of a software-complete insn.
*/
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index e1c470752eb..ee07dceae1d 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -465,7 +465,7 @@ EXPORT_SYMBOL(pci_free_consistent);
Write dma_length of each leader with the combined lengths of
the mergable followers. */
-#define SG_ENT_VIRT_ADDRESS(SG) (page_address((SG)->page) + (SG)->offset)
+#define SG_ENT_VIRT_ADDRESS(SG) (sg_virt((SG)))
#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
static void
diff --git a/arch/alpha/kernel/semaphore.c b/arch/alpha/kernel/semaphore.c
index 8c8aaa205ea..8d2982aa1b8 100644
--- a/arch/alpha/kernel/semaphore.c
+++ b/arch/alpha/kernel/semaphore.c
@@ -69,7 +69,7 @@ __down_failed(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down failed(%p)\n",
- tsk->comm, tsk->pid, sem);
+ tsk->comm, task_pid_nr(tsk), sem);
#endif
tsk->state = TASK_UNINTERRUPTIBLE;
@@ -98,7 +98,7 @@ __down_failed(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down acquired(%p)\n",
- tsk->comm, tsk->pid, sem);
+ tsk->comm, task_pid_nr(tsk), sem);
#endif
}
@@ -111,7 +111,7 @@ __down_failed_interruptible(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down failed(%p)\n",
- tsk->comm, tsk->pid, sem);
+ tsk->comm, task_pid_nr(tsk), sem);
#endif
tsk->state = TASK_INTERRUPTIBLE;
@@ -139,7 +139,7 @@ __down_failed_interruptible(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down %s(%p)\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
(ret < 0 ? "interrupted" : "acquired"), sem);
#endif
return ret;
@@ -168,7 +168,7 @@ down(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down(%p) <count=%d> from %p\n",
- current->comm, current->pid, sem,
+ current->comm, task_pid_nr(current), sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
__down(sem);
@@ -182,7 +182,7 @@ down_interruptible(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down(%p) <count=%d> from %p\n",
- current->comm, current->pid, sem,
+ current->comm, task_pid_nr(current), sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
return __down_interruptible(sem);
@@ -201,7 +201,7 @@ down_trylock(struct semaphore *sem)
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): down_trylock %s from %p\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
ret ? "failed" : "acquired",
__builtin_return_address(0));
#endif
@@ -217,7 +217,7 @@ up(struct semaphore *sem)
#endif
#ifdef CONFIG_DEBUG_SEMAPHORE
printk("%s(%d): up(%p) <count=%d> from %p\n",
- current->comm, current->pid, sem,
+ current->comm, task_pid_nr(current), sem,
atomic_read(&sem->count), __builtin_return_address(0));
#endif
__up(sem);
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index ad176441be5..f4ab233201b 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -439,7 +439,6 @@ setup_smp(void)
((char *)cpubase + i*hwrpb->processor_size);
if ((cpu->flags & 0x1cc) == 0x1cc) {
smp_num_probed++;
- /* Assume here that "whami" == index */
cpu_set(i, cpu_present_map);
cpu->pal_revision = boot_cpu_palrev;
}
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 49bedfbbd31..d187d01d2a1 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -138,7 +138,7 @@ alcor_init_irq(void)
for (i = 16; i < 48; ++i) {
/* On Alcor, at least, lines 20..30 are not connected
- and can generate spurrious interrupts if we turn them
+ and can generate spurious interrupts if we turn them
on while IRQ probing. */
if (i >= 16+20 && i <= 16+30)
continue;
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index 14b5a753aba..ee7b9009ebb 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -78,7 +78,7 @@ alphabook1_init_arch(void)
* example, sound boards seem to like using IRQ 9.
*
* This is NOT how we should do it. PIRQ0-X should have
- * their own IRQ's, the way intel uses the IO-APIC irq's.
+ * their own IRQs, the way intel uses the IO-APIC IRQs.
*/
static void __init
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index ec0f05e0d8f..2dc7f9fed21 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -182,7 +182,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
#ifdef CONFIG_SMP
printk("CPU %d ", hard_smp_processor_id());
#endif
- printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
+ printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
dik_show_regs(regs, r9_15);
add_taint(TAINT_DIE);
dik_show_trace((unsigned long *)(regs+1));
@@ -646,7 +646,7 @@ got_exception:
lock_kernel();
printk("%s(%d): unhandled unaligned exception\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n",
pc, una_reg(26), regs->ps);
@@ -786,7 +786,7 @@ do_entUnaUser(void __user * va, unsigned long opcode,
}
if (++cnt < 5) {
printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
regs->pc - 4, va, opcode, reg);
}
last_time = jiffies;
diff --git a/arch/alpha/lib/checksum.c b/arch/alpha/lib/checksum.c
index 8698e0746f9..199f6efa83f 100644
--- a/arch/alpha/lib/checksum.c
+++ b/arch/alpha/lib/checksum.c
@@ -5,7 +5,7 @@
* in an architecture-specific manner due to speed..
* Comments in other versions indicate that the algorithms are from RFC1071
*
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
* Rick Gorton <rick.gorton@alpha-processor.com>
*/
diff --git a/arch/alpha/lib/csum_partial_copy.c b/arch/alpha/lib/csum_partial_copy.c
index 4ca75c74ce9..40736da9bea 100644
--- a/arch/alpha/lib/csum_partial_copy.c
+++ b/arch/alpha/lib/csum_partial_copy.c
@@ -2,7 +2,7 @@
* csum_partial_copy - do IP checksumming and copy
*
* (C) Copyright 1996 Linus Torvalds
- * accellerated versions (and 21264 assembly versions ) contributed by
+ * accelerated versions (and 21264 assembly versions ) contributed by
* Rick Gorton <rick.gorton@alpha-processor.com>
*
* Don't look at this too closely - you'll go mad. The things
diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c
index 7ad84ea0acf..32afaa3fa68 100644
--- a/arch/alpha/lib/fls.c
+++ b/arch/alpha/lib/fls.c
@@ -3,7 +3,7 @@
*/
#include <linux/module.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
/* This is fls(x)-1, except zero is held to zero. This allows most
efficent input into extbl, plus it allows easy handling of fls(0)=0. */
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index 25154df3055..4829f96585b 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -188,13 +188,13 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
/* We ran out of memory, or some other thing happened to us that
made us unable to handle the page fault gracefully. */
out_of_memory:
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
}
printk(KERN_ALERT "VM: killing process %s(%d)\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
if (!user_mode(regs))
goto no_context;
do_group_exit(SIGKILL);
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 5e6da47779a..40c15e7301d 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -235,7 +235,7 @@ callback_init(void * kernel_end)
unsigned long pfn = crb->map[i].pa >> PAGE_SHIFT;
crb->map[i].va = vaddr;
for (j = 0; j < crb->map[i].count; ++j) {
- /* Newer console's (especially on larger
+ /* Newer consoles (especially on larger
systems) may require more pages of
PTEs. Grab additional pages as needed. */
if (pmd != pmd_offset(pgd, vaddr)) {
diff --git a/arch/alpha/oprofile/Kconfig b/arch/alpha/oprofile/Kconfig
deleted file mode 100644
index 5ade19801b9..00000000000
--- a/arch/alpha/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/alpha/oprofile/op_impl.h b/arch/alpha/oprofile/op_impl.h
index 6b97893c1a8..b2b87ae9a35 100644
--- a/arch/alpha/oprofile/op_impl.h
+++ b/arch/alpha/oprofile/op_impl.h
@@ -38,7 +38,7 @@ struct op_register_config {
unsigned long need_reset;
};
-/* Per-architecture configury and hooks. */
+/* Per-architecture configuration and hooks. */
struct op_axp_model {
void (*reg_setup) (struct op_register_config *,
struct op_counter_config *,
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a0c88d0039..a0cdaafa115 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -851,7 +851,7 @@ config KEXEC
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
- but it is indepedent of the system firmware. And like a reboot
+ but it is independent of the system firmware. And like a reboot
you can start any kernel with it, not just Linux.
It is an ongoing process to be certain the hardware in a machine
@@ -1068,7 +1068,7 @@ endmenu
source "fs/Kconfig"
-source "arch/arm/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/arm/Kconfig.debug"
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 44ab0dad403..9d371e47655 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -442,7 +442,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(dir == DMA_NONE);
for (i = 0; i < nents; i++, sg++) {
- struct page *page = sg->page;
+ struct page *page = sg_page(sg);
unsigned int offset = sg->offset;
unsigned int length = sg->length;
void *ptr = page_address(page) + offset;
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 93b7f8e22dc..4f1a03124a7 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -265,7 +265,7 @@ void __show_regs(struct pt_regs *regs)
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
+ printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
__show_regs(regs);
__backtrace();
}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 5feee722ea9..4b05dc5c102 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -382,16 +382,16 @@ static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
- "0x%08lx (0x%04x)\n", task->comm, task->pid,
- addr, old_insn.thumb);
+ "0x%08lx (0x%04x)\n", task->comm,
+ task_pid_nr(task), addr, old_insn.thumb);
} else {
ret = swap_insn(task, addr & ~3, &old_insn.arm,
&bp->insn.arm, 4);
if (ret != 4 || old_insn.arm != BREAKINST_ARM)
printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
- "0x%08lx (0x%08x)\n", task->comm, task->pid,
- addr, old_insn.arm);
+ "0x%08lx (0x%08x)\n", task->comm,
+ task_pid_nr(task), addr, old_insn.arm);
}
}
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 8ad47619c07..4764bd9ccee 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -223,7 +223,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
- tsk->comm, tsk->pid, thread + 1);
+ tsk->comm, task_pid_nr(tsk), thread + 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
@@ -337,7 +337,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",
- current->comm, current->pid, pc);
+ current->comm, task_pid_nr(current), pc);
dump_instr(regs);
}
#endif
@@ -388,7 +388,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_SYSCALL) {
printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n",
- current->pid, current->comm, n);
+ task_pid_nr(current), current->comm, n);
dump_instr(regs);
}
#endif
@@ -565,7 +565,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
*/
if (user_debug & UDBG_SYSCALL) {
printk("[%d] %s: arm syscall %d\n",
- current->pid, current->comm, no);
+ task_pid_nr(current), current->comm, no);
dump_instr(regs);
if (user_mode(regs)) {
__show_regs(regs);
@@ -642,7 +642,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_BADABORT) {
printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
- current->pid, current->comm, code, instr);
+ task_pid_nr(current), current->comm, code, instr);
dump_instr(regs);
show_pte(current->mm, addr);
}
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index ba4a1bb3ee4..aa2d365c93f 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -439,7 +439,7 @@ void __init at91_gpio_irq_setup(void)
for (i = 0; i < 32; i++, pin++) {
/*
* Can use the "simple" and not "edge" handler since it's
- * shorter, and the AIC handles interupts sanely.
+ * shorter, and the AIC handles interrupts sanely.
*/
set_irq_chip(pin, &gpio_irqchip);
set_irq_handler(pin, handle_simple_irq);
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 0733078940f..1da9d59a034 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2004 Nokia Corporation
* Written by Tony Lindgren <tony@atomide.com>
- * Major cleanups by Juha Yrjl <juha.yrjola@nokia.com>
+ * Major cleanups by Juha Yrjölä <juha.yrjola@nokia.com>
*
* Completely re-written to support various OMAP chips with bank specific
* interrupt handlers.
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 62e801ef9ad..8d322c20cca 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -5,7 +5,7 @@
*
* Copyright (C) 2005 Nokia Corporation
* Author: Paul Mundt <paul.mundt@nokia.com>
- * Juha Yrjl <juha.yrjola@nokia.com>
+ * Juha Yrjölä <juha.yrjola@nokia.com>
* OMAP Dual-mode timer framework support by Timo Teras
*
* Some parts based off of TI's 24xx code:
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index cab9d6265e9..2bfaa610202 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -238,7 +238,7 @@ int __init s3c2410_baseclk_add(void)
}
/* We must be careful disabling the clocks we are not intending to
- * be using at boot time, as subsytems such as the LCD which do
+ * be using at boot time, as subsystems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 8543dd6df39..45899360189 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -689,7 +689,7 @@ int __init s3c2412_baseclk_add(void)
}
/* We must be careful disabling the clocks we are not intending to
- * be using at boot time, as subsytems such as the LCD which do
+ * be using at boot time, as subsystems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 58402948c47..b42f956738d 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -1005,7 +1005,7 @@ void __init s3c2443_init_clocks(int xtal)
}
/* We must be careful disabling the clocks we are not intending to
- * be using at boot time, as subsytems such as the LCD which do
+ * be using at boot time, as subsystems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 074b7cb0774..e162cca5917 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -757,7 +757,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (ai_usermode & 1)
printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx "
"Address=0x%08lx FSR 0x%03x\n", current->comm,
- current->pid, instrptr,
+ task_pid_nr(current), instrptr,
thumb_mode(regs) ? 4 : 8,
thumb_mode(regs) ? tinstr : instr,
addr, fsr);
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 59ed1d05b71..a8a7dab757e 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -197,7 +197,7 @@ survive:
return fault;
out_of_memory:
- if (!is_init(tsk))
+ if (!is_global_init(tsk))
goto out;
/*
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h
index 0090b19bbe6..786e4c96156 100644
--- a/arch/arm/nwfpe/fpopcode.h
+++ b/arch/arm/nwfpe/fpopcode.h
@@ -78,11 +78,11 @@ TABLE 1
+-------------------------+---+---+---------+---------+
| Precision | u | v | FPSR.EP | length |
+-------------------------+---+---+---------+---------+
-| Single | 0 0 | x | 1 words |
-| Double | 1 1 | x | 2 words |
-| Extended | 1 1 | x | 3 words |
-| Packed decimal | 1 1 | 0 | 3 words |
-| Expanded packed decimal | 1 1 | 1 | 4 words |
+| Single | 0 | 0 | x | 1 words |
+| Double | 1 | 1 | x | 2 words |
+| Extended | 1 | 1 | x | 3 words |
+| Packed decimal | 1 | 1 | 0 | 3 words |
+| Expanded packed decimal | 1 | 1 | 1 | 4 words |
+-------------------------+---+---+---------+---------+
Note: x = don't care
*/
@@ -92,10 +92,10 @@ TABLE 2
+---+---+---------------------------------+
| w | x | Number of registers to transfer |
+---+---+---------------------------------+
-| 0 1 | 1 |
-| 1 0 | 2 |
-| 1 1 | 3 |
-| 0 0 | 4 |
+| 0 | 1 | 1 |
+| 1 | 0 | 2 |
+| 1 | 1 | 3 |
+| 0 | 0 | 4 |
+---+---+---------------------------------+
*/
@@ -156,10 +156,10 @@ TABLE 5
+-------------------------+---+---+
| Rounding Precision | e | f |
+-------------------------+---+---+
-| IEEE Single precision | 0 0 |
-| IEEE Double precision | 0 1 |
-| IEEE Extended precision | 1 0 |
-| undefined (trap) | 1 1 |
+| IEEE Single precision | 0 | 0 |
+| IEEE Double precision | 0 | 1 |
+| IEEE Extended precision | 1 | 0 |
+| undefined (trap) | 1 | 1 |
+-------------------------+---+---+
*/
@@ -168,10 +168,10 @@ TABLE 5
+---------------------------------+---+---+
| Rounding Mode | g | h |
+---------------------------------+---+---+
-| Round to nearest (default) | 0 0 |
-| Round toward plus infinity | 0 1 |
-| Round toward negative infinity | 1 0 |
-| Round toward zero | 1 1 |
+| Round to nearest (default) | 0 | 0 |
+| Round toward plus infinity | 0 | 1 |
+| Round toward negative infinity | 1 | 0 |
+| Round toward zero | 1 | 1 |
+---------------------------------+---+---+
*/
diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig
deleted file mode 100644
index afd93ad02fe..00000000000
--- a/arch/arm/oprofile/Kconfig
+++ /dev/null
@@ -1,42 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-if OPROFILE
-
-config OPROFILE_ARMV6
- bool
- depends on CPU_V6 && !SMP
- default y
- select OPROFILE_ARM11_CORE
-
-config OPROFILE_MPCORE
- bool
- depends on CPU_V6 && SMP
- default y
- select OPROFILE_ARM11_CORE
-
-config OPROFILE_ARM11_CORE
- bool
-
-endif
-
-endmenu
-
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 05a38498cbe..dcbba07cf98 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -2,7 +2,7 @@
* linux/arch/arm/plat-omap/dma.c
*
* Copyright (C) 2003 Nokia Corporation
- * Author: Juha Yrjl <juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
* DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
* Graphics DMA and LCD DMA graphics tranformations
* by Imre Deak <imre.deak@nokia.com>
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 337455dfe64..6097753394a 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -4,7 +4,7 @@
* Support functions for OMAP GPIO
*
* Copyright (C) 2003-2005 Nokia Corporation
- * Written by Juha Yrjl <juha.yrjola@nokia.com>
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index d12346aaa88..bbecbd8469b 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -189,7 +189,7 @@ config CMDLINE
endmenu
-menu "Power managment options"
+menu "Power management options"
menu "CPU Frequency scaling"
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 9a73ce7eb50..8a7caf8e7b4 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -89,7 +89,7 @@ void _exception(long signr, struct pt_regs *regs, int code,
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_init(current)) {
+ if (is_global_init(current)) {
__sighandler_t handler;
spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index 11472f8701b..6560cb18b4e 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -160,7 +160,7 @@ bad_area:
if (exception_trace && printk_ratelimit())
printk("%s%s[%d]: segfault at %08lx pc %08lx "
"sp %08lx ecr %lu\n",
- is_init(tsk) ? KERN_EMERG : KERN_INFO,
+ is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
tsk->comm, tsk->pid, address, regs->pc,
regs->sp, ecr);
_exception(SIGSEGV, regs, code, address);
@@ -209,7 +209,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
@@ -231,7 +231,7 @@ do_sigbus:
if (exception_trace)
printk("%s%s[%d]: bus error at %08lx pc %08lx "
"sp %08lx ecr %lu\n",
- is_init(tsk) ? KERN_EMERG : KERN_INFO,
+ is_global_init(tsk) ? KERN_EMERG : KERN_INFO,
tsk->comm, tsk->pid, address, regs->pc,
regs->sp, ecr);
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index aa9db307331..7888551ed93 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -71,7 +71,7 @@ config GENERIC_CALIBRATE_DELAY
config IRQCHIP_DEMUX_GPIO
bool
- depends on (BF53x || BF561 || BF54x)
+ depends on (BF52x || BF53x || BF561 || BF54x)
default y
source "init/Kconfig"
@@ -85,6 +85,21 @@ choice
prompt "CPU"
default BF533
+config BF522
+ bool "BF522"
+ help
+ BF522 Processor Support.
+
+config BF525
+ bool "BF525"
+ help
+ BF525 Processor Support.
+
+config BF527
+ bool "BF527"
+ help
+ BF527 Processor Support.
+
config BF531
bool "BF531"
help
@@ -144,13 +159,18 @@ endchoice
choice
prompt "Silicon Rev"
+ default BF_REV_0_1 if BF527
default BF_REV_0_2 if BF537
default BF_REV_0_3 if BF533
default BF_REV_0_0 if BF549
config BF_REV_0_0
bool "0.0"
- depends on (BF549)
+ depends on (BF549 || BF527)
+
+config BF_REV_0_1
+ bool "0.2"
+ depends on (BF549 || BF527)
config BF_REV_0_2
bool "0.2"
@@ -176,6 +196,11 @@ config BF_REV_NONE
endchoice
+config BF52x
+ bool
+ depends on (BF522 || BF525 || BF527)
+ default y
+
config BF53x
bool
depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
@@ -204,6 +229,12 @@ choice
configuration to ensure that all the other settings are
correct.
+config BFIN527_EZKIT
+ bool "BF527-EZKIT"
+ depends on (BF522 || BF525 || BF527)
+ help
+ BF533-EZKIT-LITE board Support.
+
config BFIN533_EZKIT
bool "BF533-EZKIT"
depends on (BF533 || BF532 || BF531)
@@ -299,11 +330,17 @@ config MEM_MT48LC8M32B2B5_7
depends on (BFIN561_BLUETECHNIX_CM)
default y
+config MEM_MT48LC32M16A2TG_75
+ bool
+ depends on (BFIN527_EZKIT)
+ default y
+
config BFIN_SHARED_FLASH_ENET
bool
depends on (BFIN533_STAMP)
default y
+source "arch/blackfin/mach-bf527/Kconfig"
source "arch/blackfin/mach-bf533/Kconfig"
source "arch/blackfin/mach-bf561/Kconfig"
source "arch/blackfin/mach-bf537/Kconfig"
@@ -329,7 +366,7 @@ config CLKIN_HZ
int "Crystal Frequency in Hz"
default "11059200" if BFIN533_STAMP
default "27000000" if BFIN533_EZKIT
- default "25000000" if BFIN537_STAMP
+ default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT)
default "30000000" if BFIN561_EZKIT
default "24576000" if PNAV10
help
@@ -362,7 +399,7 @@ config VCO_MULT
range 1 64
default "22" if BFIN533_EZKIT
default "45" if BFIN533_STAMP
- default "20" if BFIN537_STAMP
+ default "20" if (BFIN537_STAMP || BFIN527_EZKIT)
default "22" if BFIN533_BLUETECHNIX_CM
default "20" if BFIN537_BLUETECHNIX_CM
default "20" if BFIN561_BLUETECHNIX_CM
@@ -398,7 +435,7 @@ config SCLK_DIV
range 1 15
default 5 if BFIN533_EZKIT
default 5 if BFIN533_STAMP
- default 4 if BFIN537_STAMP
+ default 4 if (BFIN537_STAMP || BFIN527_EZKIT)
default 5 if BFIN533_BLUETECHNIX_CM
default 4 if BFIN537_BLUETECHNIX_CM
default 4 if BFIN561_BLUETECHNIX_CM
@@ -450,6 +487,7 @@ comment "Memory Setup"
config MEM_SIZE
int "SDRAM Memory Size in MBytes"
default 32 if BFIN533_EZKIT
+ default 64 if BFIN527_EZKIT
default 64 if BFIN537_STAMP
default 64 if BFIN561_EZKIT
default 128 if BFIN533_STAMP
@@ -459,6 +497,7 @@ config MEM_ADD_WIDTH
int "SDRAM Memory Address Width"
default 9 if BFIN533_EZKIT
default 9 if BFIN561_EZKIT
+ default 10 if BFIN527_EZKIT
default 10 if BFIN537_STAMP
default 11 if BFIN533_STAMP
default 10 if PNAV10
@@ -613,85 +652,86 @@ config I_ENTRY_L1
bool "Locate interrupt entry code in L1 Memory"
default y
help
- If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked
- into L1 instruction memory.(less latency)
+ If enabled, interrupt entry code (STORE/RESTORE CONTEXT) is linked
+ into L1 instruction memory. (less latency)
config EXCPT_IRQ_SYSC_L1
- bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory"
+ bool "Locate entire ASM lowlevel exception / interrupt - Syscall and CPLB handler code in L1 Memory"
default y
help
- If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked
- into L1 instruction memory.(less latency)
+ If enabled, the entire ASM lowlevel exception and interrupt entry code
+ (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.
+ (less latency)
config DO_IRQ_L1
bool "Locate frequently called do_irq dispatcher function in L1 Memory"
default y
help
- If enabled frequently called do_irq dispatcher function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the frequently called do_irq dispatcher function is linked
+ into L1 instruction memory. (less latency)
config CORE_TIMER_IRQ_L1
bool "Locate frequently called timer_interrupt() function in L1 Memory"
default y
help
- If enabled frequently called timer_interrupt() function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the frequently called timer_interrupt() function is linked
+ into L1 instruction memory. (less latency)
config IDLE_L1
bool "Locate frequently idle function in L1 Memory"
default y
help
- If enabled frequently called idle function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the frequently called idle function is linked
+ into L1 instruction memory. (less latency)
config SCHEDULE_L1
bool "Locate kernel schedule function in L1 Memory"
default y
help
- If enabled frequently called kernel schedule is linked
- into L1 instruction memory.(less latency)
+ If enabled, the frequently called kernel schedule is linked
+ into L1 instruction memory. (less latency)
config ARITHMETIC_OPS_L1
bool "Locate kernel owned arithmetic functions in L1 Memory"
default y
help
- If enabled arithmetic functions are linked
- into L1 instruction memory.(less latency)
+ If enabled, arithmetic functions are linked
+ into L1 instruction memory. (less latency)
config ACCESS_OK_L1
bool "Locate access_ok function in L1 Memory"
default y
help
- If enabled access_ok function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the access_ok function is linked
+ into L1 instruction memory. (less latency)
config MEMSET_L1
bool "Locate memset function in L1 Memory"
default y
help
- If enabled memset function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the memset function is linked
+ into L1 instruction memory. (less latency)
config MEMCPY_L1
bool "Locate memcpy function in L1 Memory"
default y
help
- If enabled memcpy function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the memcpy function is linked
+ into L1 instruction memory. (less latency)
config SYS_BFIN_SPINLOCK_L1
bool "Locate sys_bfin_spinlock function in L1 Memory"
default y
help
- If enabled sys_bfin_spinlock function is linked
- into L1 instruction memory.(less latency)
+ If enabled, sys_bfin_spinlock function is linked
+ into L1 instruction memory. (less latency)
config IP_CHECKSUM_L1
bool "Locate IP Checksum function in L1 Memory"
default n
help
- If enabled IP Checksum function is linked
- into L1 instruction memory.(less latency)
+ If enabled, the IP Checksum function is linked
+ into L1 instruction memory. (less latency)
config CACHELINE_ALIGNED_L1
bool "Locate cacheline_aligned data to L1 Data Memory"
@@ -699,24 +739,24 @@ config CACHELINE_ALIGNED_L1
default n if BF54x
depends on !BF531
help
- If enabled cacheline_anligned data is linked
- into L1 data memory.(less latency)
+ If enabled, cacheline_anligned data is linked
+ into L1 data memory. (less latency)
config SYSCALL_TAB_L1
bool "Locate Syscall Table L1 Data Memory"
default n
depends on !BF531
help
- If enabled the Syscall LUT is linked
- into L1 data memory.(less latency)
+ If enabled, the Syscall LUT is linked
+ into L1 data memory. (less latency)
config CPLB_SWITCH_TAB_L1
bool "Locate CPLB Switch Tables L1 Data Memory"
default n
depends on !BF531
help
- If enabled the CPLB Switch Tables are linked
- into L1 data memory.(less latency)
+ If enabled, the CPLB Switch Tables are linked
+ into L1 data memory. (less latency)
endmenu
@@ -748,9 +788,19 @@ config LARGE_ALLOCS
a lot of RAM, and you need to able to allocate very large
contiguous chunks. If unsure, say N.
+config BFIN_GPTIMERS
+ tristate "Enable Blackfin General Purpose Timers API"
+ default n
+ help
+ Enable support for the General Purpose Timers API. If you
+ are unsure, say N.
+
+ To compile this driver as a module, choose M here: the module
+ will be called gptimers.ko.
+
config BFIN_DMA_5XX
bool "Enable DMA Support"
- depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
+ depends on (BF52x || BF53x || BF561 || BF54x)
default y
help
DMA driver for BF5xx.
@@ -1012,7 +1062,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/blackfin/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
menu "Kernel hacking"
@@ -1029,13 +1079,13 @@ config DEBUG_HWERR
from.
config DEBUG_ICACHE_CHECK
- bool "Check Instruction cache coherancy"
+ bool "Check Instruction cache coherency"
depends on DEBUG_KERNEL
depends on DEBUG_HWERR
help
- Say Y here if you are getting wierd unexplained errors. This will
- ensure that icache is what SDRAM says it should be, by doing a
- byte wise comparision between SDRAM and instruction cache. This
+ Say Y here if you are getting weird unexplained errors. This will
+ ensure that icache is what SDRAM says it should be by doing a
+ byte wise comparison between SDRAM and instruction cache. This
also relocates the irq_panic() function to L1 memory, (which is
un-cached).
diff --git a/arch/blackfin/Makefile b/arch/blackfin/Makefile
index 368933760d2..f7cac7c51e7 100644
--- a/arch/blackfin/Makefile
+++ b/arch/blackfin/Makefile
@@ -12,12 +12,17 @@ LDFLAGS_vmlinux := -X
OBJCOPYFLAGS := -O binary -R .note -R .comment -S
GZFLAGS := -9
+KBUILD_CFLAGS += $(call cc-option,-mno-fdpic)
+KBUILD_AFLAGS += $(call cc-option,-mno-fdpic)
CFLAGS_MODULE += -mlong-calls
KALLSYMS += --symbol-prefix=_
KBUILD_DEFCONFIG := BF537-STAMP_defconfig
# setup the machine name and the machine dependent settings
+machine-$(CONFIG_BF522) := bf527
+machine-$(CONFIG_BF525) := bf527
+machine-$(CONFIG_BF527) := bf527
machine-$(CONFIG_BF531) := bf533
machine-$(CONFIG_BF532) := bf533
machine-$(CONFIG_BF533) := bf533
@@ -32,6 +37,9 @@ machine-$(CONFIG_BF561) := bf561
MACHINE := $(machine-y)
export MACHINE
+cpu-$(CONFIG_BF522) := bf522
+cpu-$(CONFIG_BF525) := bf525
+cpu-$(CONFIG_BF527) := bf527
cpu-$(CONFIG_BF531) := bf531
cpu-$(CONFIG_BF532) := bf532
cpu-$(CONFIG_BF533) := bf533
@@ -97,12 +105,23 @@ archclean:
$(Q)$(MAKE) $(clean)=$(boot)
-all: vmImage
boot := arch/$(ARCH)/boot
BOOT_TARGETS = vmImage
-.PHONY: $(BOOT_TARGETS)
+PHONY += $(BOOT_TARGETS) install
+KBUILD_IMAGE := $(boot)/vmImage
+
+all: vmImage
+
$(BOOT_TARGETS): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+install:
+ $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
+
define archhelp
echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
+ echo ' install - Install kernel using'
+ echo ' (your) ~/bin/$(CROSS_COMPILE)installkernel or'
+ echo ' (distribution) PATH: $(CROSS_COMPILE)installkernel or'
+ echo ' install to $$(INSTALL_PATH)'
endef
diff --git a/arch/blackfin/boot/Makefile b/arch/blackfin/boot/Makefile
index 8cd33560e81..522f3c12406 100644
--- a/arch/blackfin/boot/Makefile
+++ b/arch/blackfin/boot/Makefile
@@ -26,3 +26,6 @@ $(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
$(obj)/vmImage: $(obj)/vmlinux.gz
$(call if_changed,uimage)
@echo 'Kernel: $@ is ready'
+
+install:
+ sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
diff --git a/arch/blackfin/boot/install.sh b/arch/blackfin/boot/install.sh
new file mode 100644
index 00000000000..9560a6b2910
--- /dev/null
+++ b/arch/blackfin/boot/install.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# arch/blackfin/boot/install.sh
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License. See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1995 by Linus Torvalds
+#
+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin
+# Adapted from code in arch/i386/boot/install.sh by Mike Frysinger
+#
+# "make install" script for Blackfin architecture
+#
+# Arguments:
+# $1 - kernel version
+# $2 - kernel image file
+# $3 - kernel map file
+# $4 - default install path (blank if root directory)
+#
+
+verify () {
+ if [ ! -f "$1" ]; then
+ echo "" 1>&2
+ echo " *** Missing file: $1" 1>&2
+ echo ' *** You need to run "make" before "make install".' 1>&2
+ echo "" 1>&2
+ exit 1
+ fi
+}
+
+# Make sure the files actually exist
+verify "$2"
+verify "$3"
+
+# User may have a custom install script
+
+if [ -x ~/bin/${CROSS_COMPILE}installkernel ]; then exec ~/bin/${CROSS_COMPILE}installkernel "$@"; fi
+if which ${CROSS_COMPILE}installkernel >/dev/null 2>&1; then
+ exec ${CROSS_COMPILE}installkernel "$@"
+fi
+
+# Default install - same as make zlilo
+
+back_it_up() {
+ local file=$1
+ [ -f ${file} ] || return 0
+ local stamp=$(stat -c %Y ${file} 2>/dev/null)
+ mv ${file} ${file}.${stamp:-old}
+}
+
+back_it_up $4/uImage
+back_it_up $4/System.map
+
+cat $2 > $4/uImage
+cp $3 $4/System.map
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
new file mode 100644
index 00000000000..df974e785ee
--- /dev/null
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -0,0 +1,1241 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.22.9
+#
+# CONFIG_MMU is not set
+# CONFIG_FPU is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_BLACKFIN=y
+CONFIG_ZONE_DMA=y
+CONFIG_BFIN=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+# CONFIG_GENERIC_TIME is not set
+CONFIG_GENERIC_GPIO=y
+CONFIG_FORCE_MAX_ZONEORDER=14
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_IRQCHIP_DEMUX_GPIO=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_BIG_ORDER_ALLOC_NOFAIL_MAGIC=3
+# CONFIG_NP2 is not set
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_TINY_SHMEM=y
+CONFIG_BASE_SMALL=0
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+
+#
+# Blackfin Processor Options
+#
+
+#
+# Processor and Board Settings
+#
+# CONFIG_BF522 is not set
+# CONFIG_BF525 is not set
+CONFIG_BF527=y
+# CONFIG_BF531 is not set
+# CONFIG_BF532 is not set
+# CONFIG_BF533 is not set
+# CONFIG_BF534 is not set
+# CONFIG_BF536 is not set
+# CONFIG_BF537 is not set
+# CONFIG_BF542 is not set
+# CONFIG_BF544 is not set
+# CONFIG_BF548 is not set
+# CONFIG_BF549 is not set
+# CONFIG_BF561 is not set
+CONFIG_BF_REV_0_0=y
+# CONFIG_BF_REV_0_1 is not set
+# CONFIG_BF_REV_0_2 is not set
+# CONFIG_BF_REV_0_3 is not set
+# CONFIG_BF_REV_0_4 is not set
+# CONFIG_BF_REV_0_5 is not set
+# CONFIG_BF_REV_ANY is not set
+# CONFIG_BF_REV_NONE is not set
+CONFIG_BF52x=y
+CONFIG_BFIN_SINGLE_CORE=y
+CONFIG_BFIN527_EZKIT=y
+# CONFIG_BFIN533_EZKIT is not set
+# CONFIG_BFIN533_STAMP is not set
+# CONFIG_BFIN537_STAMP is not set
+# CONFIG_BFIN533_BLUETECHNIX_CM is not set
+# CONFIG_BFIN537_BLUETECHNIX_CM is not set
+# CONFIG_BFIN548_EZKIT is not set
+# CONFIG_BFIN561_BLUETECHNIX_CM is not set
+# CONFIG_BFIN561_EZKIT is not set
+# CONFIG_BFIN561_TEPLA is not set
+# CONFIG_PNAV10 is not set
+# CONFIG_GENERIC_BOARD is not set
+CONFIG_MEM_MT48LC32M16A2TG_75=y
+
+#
+# BF527 Specific Configuration
+#
+
+#
+# Alternative Multiplexing Scheme
+#
+# CONFIG_BF527_SPORT0_PORTF is not set
+CONFIG_BF527_SPORT0_PORTG=y
+CONFIG_BF527_SPORT0_TSCLK_PG10=y
+# CONFIG_BF527_SPORT0_TSCLK_PG14 is not set
+# CONFIG_BF527_UART1_PORTF is not set
+CONFIG_BF527_UART1_PORTG=y
+# CONFIG_BF527_NAND_D_PORTF is not set
+CONFIG_BF527_NAND_D_PORTH=y
+
+#
+# Interrupt Priority Assignment
+#
+
+#
+# Priority
+#
+CONFIG_IRQ_PLL_WAKEUP=7
+CONFIG_IRQ_DMA0_ERROR=7
+CONFIG_IRQ_DMAR0_BLK=7
+CONFIG_IRQ_DMAR1_BLK=7
+CONFIG_IRQ_DMAR0_OVR=7
+CONFIG_IRQ_DMAR1_OVR=7
+CONFIG_IRQ_PPI_ERROR=7
+CONFIG_IRQ_MAC_ERROR=7
+CONFIG_IRQ_SPORT0_ERROR=7
+CONFIG_IRQ_SPORT1_ERROR=7
+CONFIG_IRQ_UART0_ERROR=7
+CONFIG_IRQ_UART1_ERROR=7
+CONFIG_IRQ_RTC=8
+CONFIG_IRQ_PPI=8
+CONFIG_IRQ_SPORT0_RX=9
+CONFIG_IRQ_SPORT0_TX=9
+CONFIG_IRQ_SPORT1_RX=9
+CONFIG_IRQ_SPORT1_TX=9
+CONFIG_IRQ_TWI=10
+CONFIG_IRQ_SPI=10
+CONFIG_IRQ_UART0_RX=10
+CONFIG_IRQ_UART0_TX=10
+CONFIG_IRQ_UART1_RX=10
+CONFIG_IRQ_UART1_TX=10
+CONFIG_IRQ_OPTSEC=11
+CONFIG_IRQ_CNT=11
+CONFIG_IRQ_MAC_RX=11
+CONFIG_IRQ_PORTH_INTA=11
+CONFIG_IRQ_MAC_TX=11
+CONFIG_IRQ_PORTH_INTB=11
+CONFIG_IRQ_TMR0=12
+CONFIG_IRQ_TMR1=12
+CONFIG_IRQ_TMR2=12
+CONFIG_IRQ_TMR3=12
+CONFIG_IRQ_TMR4=12
+CONFIG_IRQ_TMR5=12
+CONFIG_IRQ_TMR6=12
+CONFIG_IRQ_TMR7=12
+CONFIG_IRQ_PORTG_INTA=12
+CONFIG_IRQ_PORTG_INTB=12
+CONFIG_IRQ_MEM_DMA0=13
+CONFIG_IRQ_MEM_DMA1=13
+CONFIG_IRQ_WATCH=13
+CONFIG_IRQ_PORTF_INTA=13
+CONFIG_IRQ_PORTF_INTB=13
+CONFIG_IRQ_SPI_ERROR=7
+CONFIG_IRQ_NFC_ERROR=7
+CONFIG_IRQ_HDMA_ERROR=7
+CONFIG_IRQ_HDMA=7
+CONFIG_IRQ_USB_EINT=10
+CONFIG_IRQ_USB_INT0=11
+CONFIG_IRQ_USB_INT1=11
+CONFIG_IRQ_USB_INT2=11
+CONFIG_IRQ_USB_DMA=11
+
+#
+# Board customizations
+#
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Clock/PLL Setup
+#
+CONFIG_CLKIN_HZ=25000000
+# CONFIG_BFIN_KERNEL_CLOCK is not set
+CONFIG_MAX_VCO_HZ=600000000
+CONFIG_MIN_VCO_HZ=50000000
+CONFIG_MAX_SCLK_HZ=133000000
+CONFIG_MIN_SCLK_HZ=27000000
+
+#
+# Kernel Timer/Scheduler
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+
+#
+# Memory Setup
+#
+CONFIG_MEM_SIZE=64
+CONFIG_MEM_ADD_WIDTH=10
+CONFIG_BOOT_LOAD=0x1000
+CONFIG_BFIN_SCRATCH_REG_RETN=y
+# CONFIG_BFIN_SCRATCH_REG_RETE is not set
+# CONFIG_BFIN_SCRATCH_REG_CYCLES is not set
+
+#
+# Blackfin Kernel Optimizations
+#
+
+#
+# Memory Optimizations
+#
+CONFIG_I_ENTRY_L1=y
+CONFIG_EXCPT_IRQ_SYSC_L1=y
+CONFIG_DO_IRQ_L1=y
+CONFIG_CORE_TIMER_IRQ_L1=y
+CONFIG_IDLE_L1=y
+# CONFIG_SCHEDULE_L1 is not set
+CONFIG_ARITHMETIC_OPS_L1=y
+CONFIG_ACCESS_OK_L1=y
+# CONFIG_MEMSET_L1 is not set
+# CONFIG_MEMCPY_L1 is not set
+# CONFIG_SYS_BFIN_SPINLOCK_L1 is not set
+# CONFIG_IP_CHECKSUM_L1 is not set
+CONFIG_CACHELINE_ALIGNED_L1=y
+# CONFIG_SYSCALL_TAB_L1 is not set
+# CONFIG_CPLB_SWITCH_TAB_L1 is not set
+CONFIG_RAMKERNEL=y
+# CONFIG_ROMKERNEL is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_LARGE_ALLOCS=y
+CONFIG_BFIN_DMA_5XX=y
+# CONFIG_DMA_UNCACHED_2M is not set
+CONFIG_DMA_UNCACHED_1M=y
+# CONFIG_DMA_UNCACHED_NONE is not set
+
+#
+# Cache Support
+#
+CONFIG_BFIN_ICACHE=y
+CONFIG_BFIN_DCACHE=y
+# CONFIG_BFIN_DCACHE_BANKA is not set
+# CONFIG_BFIN_ICACHE_LOCK is not set
+# CONFIG_BFIN_WB is not set
+CONFIG_BFIN_WT=y
+CONFIG_L1_MAX_PIECE=16
+
+#
+# Asynchonous Memory Configuration
+#
+
+#
+# EBIU_AMBCTL Global Control
+#
+CONFIG_C_AMCKEN=y
+CONFIG_C_CDPRIO=y
+# CONFIG_C_AMBEN is not set
+# CONFIG_C_AMBEN_B0 is not set
+# CONFIG_C_AMBEN_B0_B1 is not set
+# CONFIG_C_AMBEN_B0_B1_B2 is not set
+CONFIG_C_AMBEN_ALL=y
+
+#
+# EBIU_AMBCTL Control
+#
+CONFIG_BANK_0=0x7BB0
+CONFIG_BANK_1=0x5554
+CONFIG_BANK_2=0x7BB0
+CONFIG_BANK_3=0xFFC0
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF_FDPIC=y
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_ZFLAT=y
+# CONFIG_BINFMT_SHARED_FLAT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_MW320D=m
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=m
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_BF5xx=m
+CONFIG_BFIN_FLASH_SIZE=0x400000
+CONFIG_EBIU_FLASH_BASE=0x20000000
+# CONFIG_MTD_UCLINUX is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=m
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_BFIN=m
+CONFIG_BFIN_NAND_BASE=0x20212000
+CONFIG_BFIN_NAND_CLE=2
+CONFIG_BFIN_NAND_ALE=1
+CONFIG_BFIN_NAND_READY=3
+CONFIG_MTD_NAND_IDS=m
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_FIXED_PHY is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_SMC91X is not set
+CONFIG_BFIN_MAC=y
+CONFIG_BFIN_MAC_USE_L1=y
+CONFIG_BFIN_TX_DESC_NUM=10
+CONFIG_BFIN_RX_DESC_NUM=20
+CONFIG_BFIN_MAC_RMII=y
+# CONFIG_SMSC911X is not set
+# CONFIG_DM9000 is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_BF53X_PFBUTTONS is not set
+# CONFIG_TWI_KEYPAD is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_AD9960 is not set
+# CONFIG_SPI_ADC_BF533 is not set
+# CONFIG_BF5xx_PFLAGS is not set
+# CONFIG_BF5xx_PPIFCD is not set
+# CONFIG_BF5xx_TIMERS is not set
+# CONFIG_BF5xx_PPI is not set
+# CONFIG_BFIN_SPORT is not set
+# CONFIG_BFIN_TIMER_LATENCY is not set
+# CONFIG_TWI_LCD is not set
+# CONFIG_AD5304 is not set
+# CONFIG_BF5xx_TEA5764 is not set
+# CONFIG_BF5xx_FBDMA is not set
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_BFIN=y
+CONFIG_SERIAL_BFIN_CONSOLE=y
+# CONFIG_SERIAL_BFIN_DMA is not set
+CONFIG_SERIAL_BFIN_PIO=y
+# CONFIG_SERIAL_BFIN_UART0 is not set
+CONFIG_SERIAL_BFIN_UART1=y
+# CONFIG_BFIN_UART1_CTSRTS is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_BFIN_SPORT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# CAN, the car bus and industrial fieldbus
+#
+# CONFIG_CAN4LINUX is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
+CONFIG_HW_RANDOM=y
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_BLACKFIN_GPIO is not set
+CONFIG_I2C_BLACKFIN_TWI=m
+CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=50
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+# CONFIG_SENSORS_AD5252 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_SENSORS_PCF8575 is not set
+# CONFIG_SENSORS_PCA9543 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BFIN=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_ABITUGURU is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# HID Devices
+#
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+
+#
+# USB support
+#
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_DRV_BFIN=y
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# PBX support
+#
+# CONFIG_PBX is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_YAFFS_FS=m
+CONFIG_YAFFS_YAFFS1=y
+# CONFIG_YAFFS_DOES_ECC is not set
+CONFIG_YAFFS_YAFFS2=y
+CONFIG_YAFFS_AUTO_YAFFS2=y
+# CONFIG_YAFFS_DISABLE_LAZY_LOAD is not set
+CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS=10
+# CONFIG_YAFFS_DISABLE_WIDE_TNODES is not set
+# CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED is not set
+CONFIG_YAFFS_SHORT_NAMES_IN_RAM=y
+CONFIG_JFFS2_FS=m
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_MMRS=y
+CONFIG_DEBUG_HUNT_FOR_ZERO=y
+CONFIG_DEBUG_BFIN_HWTRACE_ON=y
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_OFF=y
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_ONE is not set
+# CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION_TWO is not set
+CONFIG_DEBUG_BFIN_HWTRACE_COMPRESSION=0
+# CONFIG_DEBUG_BFIN_HWTRACE_EXPAND is not set
+# CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_CPLB_INFO=y
+CONFIG_ACCESS_CHECK=y
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITY_NETWORK is not set
+CONFIG_SECURITY_CAPABILITIES=y
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index e80f3d59c28..d8569888a1c 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -809,7 +809,14 @@ CONFIG_UNIX98_PTYS=y
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_BFIN_WDT=y
CONFIG_HW_RANDOM=y
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 8aeb6066b19..8a4cfb293b2 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -9,6 +9,7 @@ obj-y := \
sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
+obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index e19164fb4cd..503eef4c7fe 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -420,6 +420,32 @@ unsigned short get_dma_curr_ycount(unsigned int channel)
}
EXPORT_SYMBOL(get_dma_curr_ycount);
+unsigned long get_dma_next_desc_ptr(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->next_desc_ptr;
+}
+EXPORT_SYMBOL(get_dma_next_desc_ptr);
+
+unsigned long get_dma_curr_desc_ptr(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_desc_ptr;
+}
+
+unsigned long get_dma_curr_addr(unsigned int channel)
+{
+ BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
+ && channel < MAX_BLACKFIN_DMA_CHANNEL));
+
+ return dma_ch[channel].regs->curr_addr_ptr;
+}
+EXPORT_SYMBOL(get_dma_curr_addr);
+
static void *__dma_memcpy(void *dest, const void *src, size_t size)
{
int direction; /* 1 - address decrease, 0 - address increase */
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 3fe0cd49e8d..ce85d4bf34c 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -124,7 +124,7 @@ static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
};
#endif
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
(struct gpio_port_t *) PORTFIO,
(struct gpio_port_t *) PORTGIO,
@@ -139,6 +139,21 @@ static unsigned short *port_fer[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
#endif
+#ifdef BF527_FAMILY
+static unsigned short *port_mux[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
+ (unsigned short *) PORTF_MUX,
+ (unsigned short *) PORTG_MUX,
+ (unsigned short *) PORTH_MUX,
+};
+
+static const
+u8 pmux_offset[][16] =
+ {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
+ { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
+ { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
+ };
+#endif
+
#ifdef BF561_FAMILY
static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
(struct gpio_port_t *) FIO0_FLAG_D,
@@ -186,6 +201,10 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB
static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX};
#endif
+#ifdef BF527_FAMILY
+static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB};
+#endif
+
#ifdef BF561_FAMILY
static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB};
#endif
@@ -238,7 +257,7 @@ static int cmp_label(unsigned short ident, const char *label)
return -EINVAL;
}
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
static void port_setup(unsigned short gpio, unsigned short usage)
{
if (!check_gpio(gpio)) {
@@ -354,6 +373,18 @@ inline u16 get_portmux(unsigned short portno)
return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
}
+#elif defined(BF527_FAMILY)
+inline void portmux_setup(unsigned short portno, unsigned short function)
+{
+ u16 pmux, ident = P_IDENT(portno);
+ u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
+
+ pmux = *port_mux[gpio_bank(ident)];
+ pmux &= ~(3 << offset);
+ pmux |= (function & 3) << offset;
+ *port_mux[gpio_bank(ident)] = pmux;
+ SSYNC();
+}
#else
# define portmux_setup(...) do { } while (0)
#endif
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index 94d7b119b71..a16cb03c529 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -160,8 +160,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(direction == DMA_NONE);
for (i = 0; i < nents; i++, sg++) {
- sg->dma_address = (dma_addr_t)(page_address(sg->page) +
- sg->offset);
+ sg->dma_address = (dma_addr_t) sg_virt(sg);
invalidate_dcache_range(sg_dma_address(sg),
sg_dma_address(sg) +
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
new file mode 100644
index 00000000000..cb7ba9bfc79
--- /dev/null
+++ b/arch/blackfin/kernel/gptimers.c
@@ -0,0 +1,250 @@
+/*
+ * bfin_gptimers.c - derived from bf53x_timers.c
+ * Driver for General Purpose Timer functions on the Blackfin processor
+ *
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ * Licensed under the GPLv2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/io.h>
+#include <asm/blackfin.h>
+#include <asm/gptimers.h>
+
+#ifdef DEBUG
+# define tassert(expr)
+#else
+# define tassert(expr) \
+ if (!(expr)) \
+ printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", \
+ __FILE__, __func__, __LINE__);
+#endif
+
+#define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1)
+
+typedef struct {
+ uint16_t config;
+ uint16_t __pad;
+ uint32_t counter;
+ uint32_t period;
+ uint32_t width;
+} GPTIMER_timer_regs;
+
+typedef struct {
+ uint16_t enable;
+ uint16_t __pad0;
+ uint16_t disable;
+ uint16_t __pad1;
+ uint32_t status;
+} GPTIMER_group_regs;
+
+static volatile GPTIMER_timer_regs *const timer_regs[MAX_BLACKFIN_GPTIMERS] =
+{
+ (GPTIMER_timer_regs *)TIMER0_CONFIG,
+ (GPTIMER_timer_regs *)TIMER1_CONFIG,
+ (GPTIMER_timer_regs *)TIMER2_CONFIG,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+ (GPTIMER_timer_regs *)TIMER3_CONFIG,
+ (GPTIMER_timer_regs *)TIMER4_CONFIG,
+ (GPTIMER_timer_regs *)TIMER5_CONFIG,
+ (GPTIMER_timer_regs *)TIMER6_CONFIG,
+ (GPTIMER_timer_regs *)TIMER7_CONFIG,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+ (GPTIMER_timer_regs *)TIMER8_CONFIG,
+ (GPTIMER_timer_regs *)TIMER9_CONFIG,
+ (GPTIMER_timer_regs *)TIMER10_CONFIG,
+ (GPTIMER_timer_regs *)TIMER11_CONFIG,
+#endif
+};
+
+static volatile GPTIMER_group_regs *const group_regs[BFIN_TIMER_NUM_GROUP] =
+{
+ (GPTIMER_group_regs *)TIMER0_GROUP_REG,
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+ (GPTIMER_group_regs *)TIMER8_GROUP_REG,
+#endif
+};
+
+static uint32_t const dis_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+ TIMER_STATUS_TRUN0,
+ TIMER_STATUS_TRUN1,
+ TIMER_STATUS_TRUN2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+ TIMER_STATUS_TRUN3,
+ TIMER_STATUS_TRUN4,
+ TIMER_STATUS_TRUN5,
+ TIMER_STATUS_TRUN6,
+ TIMER_STATUS_TRUN7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+ TIMER_STATUS_TRUN8,
+ TIMER_STATUS_TRUN9,
+ TIMER_STATUS_TRUN10,
+ TIMER_STATUS_TRUN11,
+#endif
+};
+
+static uint32_t const irq_mask[MAX_BLACKFIN_GPTIMERS] =
+{
+ TIMER_STATUS_TIMIL0,
+ TIMER_STATUS_TIMIL1,
+ TIMER_STATUS_TIMIL2,
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+ TIMER_STATUS_TIMIL3,
+ TIMER_STATUS_TIMIL4,
+ TIMER_STATUS_TIMIL5,
+ TIMER_STATUS_TIMIL6,
+ TIMER_STATUS_TIMIL7,
+#endif
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+ TIMER_STATUS_TIMIL8,
+ TIMER_STATUS_TIMIL9,
+ TIMER_STATUS_TIMIL10,
+ TIMER_STATUS_TIMIL11,
+#endif
+};
+
+void set_gptimer_pwidth(int timer_id, uint32_t value)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ timer_regs[timer_id]->width = value;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pwidth);
+
+uint32_t get_gptimer_pwidth(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return timer_regs[timer_id]->width;
+}
+EXPORT_SYMBOL(get_gptimer_pwidth);
+
+void set_gptimer_period(int timer_id, uint32_t period)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ timer_regs[timer_id]->period = period;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_period);
+
+uint32_t get_gptimer_period(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return timer_regs[timer_id]->period;
+}
+EXPORT_SYMBOL(get_gptimer_period);
+
+uint32_t get_gptimer_count(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return timer_regs[timer_id]->counter;
+}
+EXPORT_SYMBOL(get_gptimer_count);
+
+uint32_t get_gptimer_status(int group)
+{
+ tassert(group < BFIN_TIMER_NUM_GROUP);
+ return group_regs[group]->status;
+}
+EXPORT_SYMBOL(get_gptimer_status);
+
+void set_gptimer_status(int group, uint32_t value)
+{
+ tassert(group < BFIN_TIMER_NUM_GROUP);
+ group_regs[group]->status = value;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_status);
+
+uint16_t get_gptimer_intr(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & irq_mask[timer_id]) ? 1 : 0;
+}
+EXPORT_SYMBOL(get_gptimer_intr);
+
+void clear_gptimer_intr(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ group_regs[BFIN_TIMER_OCTET(timer_id)]->status = irq_mask[timer_id];
+}
+EXPORT_SYMBOL(clear_gptimer_intr);
+
+void set_gptimer_config(int timer_id, uint16_t config)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ timer_regs[timer_id]->config = config;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_config);
+
+uint16_t get_gptimer_config(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return timer_regs[timer_id]->config;
+}
+EXPORT_SYMBOL(get_gptimer_config);
+
+void enable_gptimers(uint16_t mask)
+{
+ int i;
+ tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+ for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+ group_regs[i]->enable = mask & 0xFF;
+ mask >>= 8;
+ }
+ SSYNC();
+}
+EXPORT_SYMBOL(enable_gptimers);
+
+void disable_gptimers(uint16_t mask)
+{
+ int i;
+ uint16_t m = mask;
+ tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
+ for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
+ group_regs[i]->disable = m & 0xFF;
+ m >>= 8;
+ }
+ for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
+ if (mask & (1 << i))
+ group_regs[BFIN_TIMER_OCTET(i)]->status |= dis_mask[i];
+ SSYNC();
+}
+EXPORT_SYMBOL(disable_gptimers);
+
+void set_gptimer_pulse_hi(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ timer_regs[timer_id]->config |= TIMER_PULSE_HI;
+ SSYNC();
+}
+EXPORT_SYMBOL(set_gptimer_pulse_hi);
+
+void clear_gptimer_pulse_hi(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ timer_regs[timer_id]->config &= ~TIMER_PULSE_HI;
+ SSYNC();
+}
+EXPORT_SYMBOL(clear_gptimer_pulse_hi);
+
+uint16_t get_enabled_gptimers(void)
+{
+ int i;
+ uint16_t result = 0;
+ for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i)
+ result |= (group_regs[i]->enable << (i << 3));
+ return result;
+}
+EXPORT_SYMBOL(get_enabled_gptimers);
+
+MODULE_AUTHOR("Axel Weiss (awe@aglaia-gmbh.de)");
+MODULE_DESCRIPTION("Blackfin General Purpose Timers API");
+MODULE_LICENSE("GPL");
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index 356078ec462..ae28aac6fec 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -11,7 +11,7 @@
#include <asm/reboot.h>
#include <asm/system.h>
-#if defined(BF537_FAMILY) || defined(BF533_FAMILY)
+#if defined(BF537_FAMILY) || defined(BF533_FAMILY) || defined(BF527_FAMILY)
#define SYSCR_VAL 0x0
#elif defined(BF561_FAMILY)
#define SYSCR_VAL 0x20
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 8dcd76e87ed..f1b059e5a06 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -459,7 +459,7 @@ static u_long get_vco(void)
return vco;
}
-/*Get the Core clock*/
+/* Get the Core clock */
u_long get_cclk(void)
{
u_long csel, ssel;
@@ -493,12 +493,24 @@ u_long get_sclk(void)
}
EXPORT_SYMBOL(get_sclk);
+unsigned long sclk_to_usecs(unsigned long sclk)
+{
+ return (USEC_PER_SEC * (u64)sclk) / get_sclk();
+}
+EXPORT_SYMBOL(sclk_to_usecs);
+
+unsigned long usecs_to_sclk(unsigned long usecs)
+{
+ return (get_sclk() * (u64)usecs) / USEC_PER_SEC;
+}
+EXPORT_SYMBOL(usecs_to_sclk);
+
/*
* Get CPU information for use by the procfs.
*/
static int show_cpuinfo(struct seq_file *m, void *v)
{
- char *cpu, *mmu, *fpu, *name;
+ char *cpu, *mmu, *fpu, *vendor, *cache;
uint32_t revid;
u_long cclk = 0, sclk = 0;
@@ -508,70 +520,83 @@ static int show_cpuinfo(struct seq_file *m, void *v)
mmu = "none";
fpu = "none";
revid = bfin_revid();
- name = bfin_board_name;
cclk = get_cclk();
sclk = get_sclk();
- seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n"
- "MMU:\t\t%s\n"
- "FPU:\t\t%s\n"
- "Core Clock:\t%9lu Hz\n"
- "System Clock:\t%9lu Hz\n"
- "BogoMips:\t%lu.%02lu\n"
- "Calibration:\t%lu loops\n",
- cpu, revid, mmu, fpu,
- cclk,
- sclk,
- (loops_per_jiffy * HZ) / 500000,
- ((loops_per_jiffy * HZ) / 5000) % 100,
- (loops_per_jiffy * HZ));
- seq_printf(m, "Board Name:\t%s\n", name);
- seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20);
- seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20);
- if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC))
- seq_printf(m, "I-CACHE:\tON\n");
- else
- seq_printf(m, "I-CACHE:\tOFF\n");
- if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
- seq_printf(m, "D-CACHE:\tON"
-#if defined CONFIG_BFIN_WB
- " (write-back)"
-#elif defined CONFIG_BFIN_WT
- " (write-through)"
-#endif
- "\n");
- else
- seq_printf(m, "D-CACHE:\tOFF\n");
-
+ switch (bfin_read_CHIPID() & CHIPID_MANUFACTURE) {
+ case 0xca:
+ vendor = "Analog Devices";
+ break;
+ default:
+ vendor = "unknown";
+ break;
+ }
+ seq_printf(m, "processor\t: %d\n"
+ "vendor_id\t: %s\n"
+ "cpu family\t: 0x%x\n"
+ "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK)\n"
+ "stepping\t: %d\n",
+ 0,
+ vendor,
+ (bfin_read_CHIPID() & CHIPID_FAMILY),
+ cpu, cclk/1000000, sclk/1000000,
+ revid);
+
+ seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
+ cclk/1000000, cclk%1000000,
+ sclk/1000000, sclk%1000000);
+ seq_printf(m, "bogomips\t: %lu.%02lu\n"
+ "Calibration\t: %lu loops\n",
+ (loops_per_jiffy * HZ) / 500000,
+ ((loops_per_jiffy * HZ) / 5000) % 100,
+ (loops_per_jiffy * HZ));
+
+ /* Check Cache configutation */
switch (bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) {
case ACACHE_BSRAM:
- seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n");
+ cache = "dbank-A/B\t: cache/sram";
dcache_size = 16;
dsup_banks = 1;
break;
case ACACHE_BCACHE:
- seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n");
+ cache = "dbank-A/B\t: cache/cache";
dcache_size = 32;
dsup_banks = 2;
break;
case ASRAM_BSRAM:
- seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n");
+ cache = "dbank-A/B\t: sram/sram";
dcache_size = 0;
dsup_banks = 0;
break;
default:
+ cache = "unknown";
+ dcache_size = 0;
+ dsup_banks = 0;
break;
}
+ /* Is it turned on? */
+ if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)))
+ dcache_size = 0;
- seq_printf(m, "I-CACHE Size:\t%dKB\n", BFIN_ICACHESIZE / 1024);
- seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
- seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
+ seq_printf(m, "cache size\t: %d KB(L1 icache) "
+ "%d KB(L1 dcache-%s) %d KB(L2 cache)\n",
+ BFIN_ICACHESIZE / 1024, dcache_size,
+#if defined CONFIG_BFIN_WB
+ "wb"
+#elif defined CONFIG_BFIN_WT
+ "wt"
+#endif
+ "", 0);
+
+ seq_printf(m, "%s\n", cache);
+
+ seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n",
BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES);
seq_printf(m,
- "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
+ "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
BFIN_DLINES);
#ifdef CONFIG_BFIN_ICACHE_LOCK
@@ -625,6 +650,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "No Ways are locked\n");
}
#endif
+
+ seq_printf(m, "board name\t: %s\n", bfin_board_name);
+ seq_printf(m, "board memory\t: %ld kB (0x%p -> 0x%p)\n",
+ physical_mem_end >> 10, (void *)0, (void *)physical_mem_end);
+ seq_printf(m, "kernel memory\t: %d kB (0x%p -> 0x%p)\n",
+ ((int)memory_end - (int)_stext) >> 10,
+ _stext,
+ (void *)memory_end);
+
return 0;
}
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 8823e9ade58..afd044e78af 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -118,12 +118,14 @@ static int printk_address(unsigned long address)
offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
write_unlock_irq(&tasklist_lock);
+ mmput(mm);
return printk("<0x%p> [ %s + 0x%lx ]",
(void *)address, name, offset);
}
vml = vml->next;
}
+ mmput(mm);
}
write_unlock_irq(&tasklist_lock);
diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile
index 635288fc5f5..bfdad52c570 100644
--- a/arch/blackfin/lib/Makefile
+++ b/arch/blackfin/lib/Makefile
@@ -4,7 +4,7 @@
lib-y := \
ashldi3.o ashrdi3.o lshrdi3.o \
- muldi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
+ muldi3.o divsi3.o udivsi3.o udivdi3.o modsi3.o umodsi3.o \
checksum.o memcpy.o memset.o memcmp.o memchr.o memmove.o \
strcmp.o strcpy.o strncmp.o strncpy.o \
umulsi3_highpart.o smulsi3_highpart.o \
diff --git a/arch/blackfin/lib/udivdi3.S b/arch/blackfin/lib/udivdi3.S
new file mode 100644
index 00000000000..ad1ebee675e
--- /dev/null
+++ b/arch/blackfin/lib/udivdi3.S
@@ -0,0 +1,375 @@
+/*
+ * udivdi3.S - unsigned long long division
+ *
+ * Copyright 2003-2007 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPLv2 or later.
+ */
+
+#include <linux/linkage.h>
+
+#define CARRY AC0
+
+#ifdef CONFIG_ARITHMETIC_OPS_L1
+.section .l1.text
+#else
+.text
+#endif
+
+
+ENTRY(___udivdi3)
+ R3 = [SP + 12];
+ [--SP] = (R7:4, P5:3);
+
+ /* Attempt to use divide primitive first; these will handle
+ ** most cases, and they're quick - avoids stalls incurred by
+ ** testing for identities.
+ */
+
+ R4 = R2 | R3;
+ CC = R4 == 0;
+ IF CC JUMP .LDIV_BY_ZERO;
+
+ R4.H = 0x8000;
+ R4 >>>= 16; // R4 now 0xFFFF8000
+ R5 = R0 | R2; // If either dividend or
+ R4 = R5 & R4; // divisor have bits in
+ CC = R4; // top half or low half's sign
+ IF CC JUMP .LIDENTS; // bit, skip builtins.
+ R4 = R1 | R3; // Also check top halves
+ CC = R4;
+ IF CC JUMP .LIDENTS;
+
+ /* Can use the builtins. */
+
+ AQ = CC; // Clear AQ (CC==0)
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ DIVQ(R0, R2);
+ R0 = R0.L (Z);
+ R1 = 0;
+ (R7:4, P5:3) = [SP++];
+ RTS;
+
+.LIDENTS:
+ /* Test for common identities. Value to be returned is
+ ** placed in R6,R7.
+ */
+ // Check for 0/y, return 0
+ R4 = R0 | R1;
+ CC = R4 == 0;
+ IF CC JUMP .LRETURN_R0;
+
+ // Check for x/x, return 1
+ R6 = R0 - R2; // If x == y, then both R6 and R7 will be zero
+ R7 = R1 - R3;
+ R4 = R6 | R7; // making R4 zero.
+ R6 += 1; // which would now make R6:R7==1.
+ CC = R4 == 0;
+ IF CC JUMP .LRETURN_IDENT;
+
+ // Check for x/1, return x
+ R6 = R0;
+ R7 = R1;
+ CC = R3 == 0;
+ IF !CC JUMP .Lnexttest;
+ CC = R2 == 1;
+ IF CC JUMP .LRETURN_IDENT;
+
+.Lnexttest:
+ R4.L = ONES R2; // check for div by power of two which
+ R5.L = ONES R3; // can be done using a shift
+ R6 = PACK (R5.L, R4.L);
+ CC = R6 == 1;
+ IF CC JUMP .Lpower_of_two_upper_zero;
+ R6 = PACK (R4.L, R5.L);
+ CC = R6 == 1;
+ IF CC JUMP .Lpower_of_two_lower_zero;
+
+ // Check for x < y, return 0
+ R6 = 0;
+ R7 = R6;
+ CC = R1 < R3 (IU);
+ IF CC JUMP .LRETURN_IDENT;
+ CC = R1 == R3;
+ IF !CC JUMP .Lno_idents;
+ CC = R0 < R2 (IU);
+ IF CC JUMP .LRETURN_IDENT;
+
+.Lno_idents: // Idents don't match. Go for the full operation
+
+
+ // If X, or X and Y have high bit set, it'll affect the
+ // results, so shift right one to stop this. Note: we've already
+ // checked that X >= Y, so Y's msb won't be set unless X's
+ // is.
+
+ R4 = 0;
+ CC = R1 < 0;
+ IF !CC JUMP .Lx_msb_clear;
+ CC = !CC; // 1 -> 0;
+ R1 = ROT R1 BY -1; // Shift X >> 1
+ R0 = ROT R0 BY -1; // lsb -> CC
+ BITSET(R4,31); // to record only x msb was set
+ CC = R3 < 0;
+ IF !CC JUMP .Ly_msb_clear;
+ CC = !CC;
+ R3 = ROT R3 BY -1; // Shift Y >> 1
+ R2 = ROT R2 BY -1;
+ BITCLR(R4,31); // clear bit to record only x msb was set
+
+.Ly_msb_clear:
+.Lx_msb_clear:
+ // Bit 31 in R4 indicates X msb set, but Y msb wasn't, and no bits
+ // were lost, so we should shift result left by one.
+
+ [--SP] = R4; // save for later
+
+ // In the loop that follows, each iteration we add
+ // either Y' or -Y' to the Remainder. We compute the
+ // negated Y', and store, for convenience. Y' goes
+ // into P0:P1, while -Y' goes into P2:P3.
+
+ P0 = R2;
+ P1 = R3;
+ R2 = -R2;
+ CC = CARRY;
+ CC = !CC;
+ R4 = CC;
+ R3 = -R3;
+ R3 = R3 - R4;
+
+ R6 = 0; // remainder = 0
+ R7 = R6;
+
+ [--SP] = R2; P2 = SP;
+ [--SP] = R3; P3 = SP;
+ [--SP] = R6; P5 = SP; // AQ = 0
+ [--SP] = P1;
+
+ /* In the loop that follows, we use the following
+ ** register assignments:
+ ** R0,R1 X, workspace
+ ** R2,R3 Y, workspace
+ ** R4,R5 partial Div
+ ** R6,R7 partial remainder
+ ** P5 AQ
+ ** The remainder and div form a 128-bit number, with
+ ** the remainder in the high 64-bits.
+ */
+ R4 = R0; // Div = X'
+ R5 = R1;
+ R3 = 0;
+
+ P4 = 64; // Iterate once per bit
+ LSETUP(.LULST,.LULEND) LC0 = P4;
+.LULST:
+ /* Shift Div and remainder up by one. The bit shifted
+ ** out of the top of the quotient is shifted into the bottom
+ ** of the remainder.
+ */
+ CC = R3;
+ R4 = ROT R4 BY 1;
+ R5 = ROT R5 BY 1 || // low q to high q
+ R2 = [P5]; // load saved AQ
+ R6 = ROT R6 BY 1 || // high q to low r
+ R0 = [P2]; // load -Y'
+ R7 = ROT R7 BY 1 || // low r to high r
+ R1 = [P3];
+
+ // Assume add -Y'
+ CC = R2 < 0; // But if AQ is set...
+ IF CC R0 = P0; // then add Y' instead
+ IF CC R1 = P1;
+
+ R6 = R6 + R0; // Rem += (Y' or -Y')
+ CC = CARRY;
+ R0 = CC;
+ R7 = R7 + R1;
+ R7 = R7 + R0 (NS) ||
+ R1 = [SP];
+ // Set the next AQ bit
+ R1 = R7 ^ R1; // from Remainder and Y'
+ R1 = R1 >> 31 || // Negate AQ's value, and
+ [P5] = R1; // save next AQ
+ BITTGL(R1, 0); // add neg AQ to the Div
+.LULEND: R4 = R4 + R1;
+
+ R6 = [SP + 16];
+
+ R0 = R4;
+ R1 = R5;
+ CC = BITTST(R6,30); // Just set CC=0
+ R4 = ROT R0 BY 1; // but if we had to shift X,
+ R5 = ROT R1 BY 1; // and didn't shift any bits out,
+ CC = BITTST(R6,31); // then the result will be half as
+ IF CC R0 = R4; // much as required, so shift left
+ IF CC R1 = R5; // one space.
+
+ SP += 20;
+ (R7:4, P5:3) = [SP++];
+ RTS;
+
+.Lpower_of_two:
+ /* Y has a single bit set, which means it's a power of two.
+ ** That means we can perform the division just by shifting
+ ** X to the right the appropriate number of bits
+ */
+
+ /* signbits returns the number of sign bits, minus one.
+ ** 1=>30, 2=>29, ..., 0x40000000=>0. Which means we need
+ ** to shift right n-signbits spaces. It also means 0x80000000
+ ** is a special case, because that *also* gives a signbits of 0
+ */
+.Lpower_of_two_lower_zero:
+ R7 = 0;
+ R6 = R1 >> 31;
+ CC = R3 < 0;
+ IF CC JUMP .LRETURN_IDENT;
+
+ R2.L = SIGNBITS R3;
+ R2 = R2.L (Z);
+ R2 += -62;
+ (R7:4, P5:3) = [SP++];
+ JUMP ___lshftli;
+
+.Lpower_of_two_upper_zero:
+ CC = R2 < 0;
+ IF CC JUMP .Lmaxint_shift;
+
+ R2.L = SIGNBITS R2;
+ R2 = R2.L (Z);
+ R2 += -30;
+ (R7:4, P5:3) = [SP++];
+ JUMP ___lshftli;
+
+.Lmaxint_shift:
+ R2 = -31;
+ (R7:4, P5:3) = [SP++];
+ JUMP ___lshftli;
+
+.LRETURN_IDENT:
+ R0 = R6;
+ R1 = R7;
+.LRETURN_R0:
+ (R7:4, P5:3) = [SP++];
+ RTS;
+.LDIV_BY_ZERO:
+ R0 = ~R2;
+ R1 = R0;
+ (R7:4, P5:3) = [SP++];
+ RTS;
+
+ENDPROC(___udivdi3)
+
+
+ENTRY(___lshftli)
+ CC = R2 == 0;
+ IF CC JUMP .Lfinished; // nothing to do
+ CC = R2 < 0;
+ IF CC JUMP .Lrshift;
+ R3 = 64;
+ CC = R2 < R3;
+ IF !CC JUMP .Lretzero;
+
+ // We're shifting left, and it's less than 64 bits, so
+ // a valid result will be returned.
+
+ R3 >>= 1; // R3 now 32
+ CC = R2 < R3;
+
+ IF !CC JUMP .Lzerohalf;
+
+ // We're shifting left, between 1 and 31 bits, which means
+ // some of the low half will be shifted into the high half.
+ // Work out how much.
+
+ R3 = R3 - R2;
+
+ // Save that much data from the bottom half.
+
+ P1 = R7;
+ R7 = R0;
+ R7 >>= R3;
+
+ // Adjust both parts of the parameter.
+
+ R0 <<= R2;
+ R1 <<= R2;
+
+ // And include the bits moved across.
+
+ R1 = R1 | R7;
+ R7 = P1;
+ RTS;
+
+.Lzerohalf:
+ // We're shifting left, between 32 and 63 bits, so the
+ // bottom half will become zero, and the top half will
+ // lose some bits. How many?
+
+ R2 = R2 - R3; // N - 32
+ R1 = LSHIFT R0 BY R2.L;
+ R0 = R0 - R0;
+ RTS;
+
+.Lretzero:
+ R0 = R0 - R0;
+ R1 = R0;
+.Lfinished:
+ RTS;
+
+.Lrshift:
+ // We're shifting right, but by how much?
+ R2 = -R2;
+ R3 = 64;
+ CC = R2 < R3;
+ IF !CC JUMP .Lretzero;
+
+ // Shifting right less than 64 bits, so some result bits will
+ // be retained.
+
+ R3 >>= 1; // R3 now 32
+ CC = R2 < R3;
+ IF !CC JUMP .Lsignhalf;
+
+ // Shifting right between 1 and 31 bits, so need to copy
+ // data across words.
+
+ P1 = R7;
+ R3 = R3 - R2;
+ R7 = R1;
+ R7 <<= R3;
+ R1 >>= R2;
+ R0 >>= R2;
+ R0 = R7 | R0;
+ R7 = P1;
+ RTS;
+
+.Lsignhalf:
+ // Shifting right between 32 and 63 bits, so the top half
+ // will become all zero-bits, and the bottom half is some
+ // of the top half. But how much?
+
+ R2 = R2 - R3;
+ R0 = R1;
+ R0 >>= R2;
+ R1 = 0;
+ RTS;
+
+ENDPROC(___lshftli)
diff --git a/arch/blackfin/mach-bf527/Kconfig b/arch/blackfin/mach-bf527/Kconfig
new file mode 100644
index 00000000000..50321f723de
--- /dev/null
+++ b/arch/blackfin/mach-bf527/Kconfig
@@ -0,0 +1,251 @@
+if (BF52x)
+
+menu "BF527 Specific Configuration"
+
+comment "Alternative Multiplexing Scheme"
+
+choice
+ prompt "SPORT0"
+ default BF527_SPORT0_PORTG
+ help
+ Select PORT used for SPORT0. See Hardware Reference Manual
+
+config BF527_SPORT0_PORTF
+ bool "PORT F"
+ help
+ PORT F
+
+config BF527_SPORT0_PORTG
+ bool "PORT G"
+ help
+ PORT G
+endchoice
+
+choice
+ prompt "SPORT0 TSCLK Location"
+ depends on BF527_SPORT0_PORTG
+ default BF527_SPORT0_TSCLK_PG10
+ help
+ Select PIN used for SPORT0_TSCLK. See Hardware Reference Manual
+
+config BF527_SPORT0_TSCLK_PG10
+ bool "PORT PG10"
+ help
+ PORT PG10
+
+config BF527_SPORT0_TSCLK_PG14
+ bool "PORT PG14"
+ help
+ PORT PG14
+endchoice
+
+choice
+ prompt "UART1"
+ default BF527_UART1_PORTG
+ help
+ Select PORT used for UART1. See Hardware Reference Manual
+
+config BF527_UART1_PORTF
+ bool "PORT F"
+ help
+ PORT F
+
+config BF527_UART1_PORTG
+ bool "PORT G"
+ help
+ PORT G
+endchoice
+
+choice
+ prompt "NAND (NFC) Data"
+ default BF527_NAND_D_PORTH
+ help
+ Select PORT used for NAND Data Bus. See Hardware Reference Manual
+
+config BF527_NAND_D_PORTF
+ bool "PORT F"
+ help
+ PORT F
+
+config BF527_NAND_D_PORTH
+ bool "PORT H"
+ help
+ PORT H
+endchoice
+
+comment "Interrupt Priority Assignment"
+menu "Priority"
+
+config IRQ_PLL_WAKEUP
+ int "IRQ_PLL_WAKEUP"
+ default 7
+config IRQ_DMA0_ERROR
+ int "IRQ_DMA0_ERROR"
+ default 7
+config IRQ_DMAR0_BLK
+ int "IRQ_DMAR0_BLK"
+ default 7
+config IRQ_DMAR1_BLK
+ int "IRQ_DMAR1_BLK"
+ default 7
+config IRQ_DMAR0_OVR
+ int "IRQ_DMAR0_OVR"
+ default 7
+config IRQ_DMAR1_OVR
+ int "IRQ_DMAR1_OVR"
+ default 7
+config IRQ_PPI_ERROR
+ int "IRQ_PPI_ERROR"
+ default 7
+config IRQ_MAC_ERROR
+ int "IRQ_MAC_ERROR"
+ default 7
+config IRQ_SPORT0_ERROR
+ int "IRQ_SPORT0_ERROR"
+ default 7
+config IRQ_SPORT1_ERROR
+ int "IRQ_SPORT1_ERROR"
+ default 7
+config IRQ_UART0_ERROR
+ int "IRQ_UART0_ERROR"
+ default 7
+config IRQ_UART1_ERROR
+ int "IRQ_UART1_ERROR"
+ default 7
+config IRQ_RTC
+ int "IRQ_RTC"
+ default 8
+config IRQ_PPI
+ int "IRQ_PPI"
+ default 8
+config IRQ_SPORT0_RX
+ int "IRQ_SPORT0_RX"
+ default 9
+config IRQ_SPORT0_TX
+ int "IRQ_SPORT0_TX"
+ default 9
+config IRQ_SPORT1_RX
+ int "IRQ_SPORT1_RX"
+ default 9
+config IRQ_SPORT1_TX
+ int "IRQ_SPORT1_TX"
+ default 9
+config IRQ_TWI
+ int "IRQ_TWI"
+ default 10
+config IRQ_SPI
+ int "IRQ_SPI"
+ default 10
+config IRQ_UART0_RX
+ int "IRQ_UART0_RX"
+ default 10
+config IRQ_UART0_TX
+ int "IRQ_UART0_TX"
+ default 10
+config IRQ_UART1_RX
+ int "IRQ_UART1_RX"
+ default 10
+config IRQ_UART1_TX
+ int "IRQ_UART1_TX"
+ default 10
+config IRQ_OPTSEC
+ int "IRQ_OPTSEC"
+ default 11
+config IRQ_CNT
+ int "IRQ_CNT"
+ default 11
+config IRQ_MAC_RX
+ int "IRQ_MAC_RX"
+ default 11
+config IRQ_PORTH_INTA
+ int "IRQ_PORTH_INTA"
+ default 11
+config IRQ_MAC_TX
+ int "IRQ_MAC_TX/NFC"
+ default 11
+config IRQ_PORTH_INTB
+ int "IRQ_PORTH_INTB"
+ default 11
+config IRQ_TMR0
+ int "IRQ_TMR0"
+ default 12
+config IRQ_TMR1
+ int "IRQ_TMR1"
+ default 12
+config IRQ_TMR2
+ int "IRQ_TMR2"
+ default 12
+config IRQ_TMR3
+ int "IRQ_TMR3"
+ default 12
+config IRQ_TMR4
+ int "IRQ_TMR4"
+ default 12
+config IRQ_TMR5
+ int "IRQ_TMR5"
+ default 12
+config IRQ_TMR6
+ int "IRQ_TMR6"
+ default 12
+config IRQ_TMR7
+ int "IRQ_TMR7"
+ default 12
+config IRQ_PORTG_INTA
+ int "IRQ_PORTG_INTA"
+ default 12
+config IRQ_PORTG_INTB
+ int "IRQ_PORTG_INTB"
+ default 12
+config IRQ_MEM_DMA0
+ int "IRQ_MEM_DMA0"
+ default 13
+config IRQ_MEM_DMA1
+ int "IRQ_MEM_DMA1"
+ default 13
+config IRQ_WATCH
+ int "IRQ_WATCH"
+ default 13
+config IRQ_PORTF_INTA
+ int "IRQ_PORTF_INTA"
+ default 13
+config IRQ_PORTF_INTB
+ int "IRQ_PORTF_INTB"
+ default 13
+config IRQ_SPI_ERROR
+ int "IRQ_SPI_ERROR"
+ default 7
+config IRQ_NFC_ERROR
+ int "IRQ_NFC_ERROR"
+ default 7
+config IRQ_HDMA_ERROR
+ int "IRQ_HDMA_ERROR"
+ default 7
+config IRQ_HDMA
+ int "IRQ_HDMA"
+ default 7
+config IRQ_USB_EINT
+ int "IRQ_USB_EINT"
+ default 10
+config IRQ_USB_INT0
+ int "IRQ_USB_INT0"
+ default 10
+config IRQ_USB_INT1
+ int "IRQ_USB_INT1"
+ default 10
+config IRQ_USB_INT2
+ int "IRQ_USB_INT2"
+ default 10
+config IRQ_USB_DMA
+ int "IRQ_USB_DMA"
+ default 10
+
+ help
+ Enter the priority numbers between 7-13 ONLY. Others are Reserved.
+ This applies to all the above. It is not recommended to assign the
+ highest priority number 7 to UART or any other device.
+
+endmenu
+
+endmenu
+
+endif
diff --git a/arch/blackfin/mach-bf527/Makefile b/arch/blackfin/mach-bf527/Makefile
new file mode 100644
index 00000000000..9f99f5d0bcd
--- /dev/null
+++ b/arch/blackfin/mach-bf527/Makefile
@@ -0,0 +1,9 @@
+#
+# arch/blackfin/mach-bf527/Makefile
+#
+
+extra-y := head.o
+
+obj-y := ints-priority.o dma.o
+
+obj-$(CONFIG_CPU_FREQ) += cpu.o
diff --git a/arch/blackfin/mach-bf527/boards/Makefile b/arch/blackfin/mach-bf527/boards/Makefile
new file mode 100644
index 00000000000..912ac8ebc88
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/Makefile
@@ -0,0 +1,7 @@
+#
+# arch/blackfin/mach-bf532/boards/Makefile
+#
+
+obj-y += eth_mac.o
+obj-$(CONFIG_BFIN527_EZKIT) += ezkit.o
+
diff --git a/arch/blackfin/mach-bf527/boards/eth_mac.c b/arch/blackfin/mach-bf527/boards/eth_mac.c
new file mode 100644
index 00000000000..a725cc8a929
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/eth_mac.c
@@ -0,0 +1,50 @@
+/*
+ * arch/blackfin/mach-bf537/board/eth_mac.c
+ *
+ * Copyright (C) 2007 Analog Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/module.h>
+#include <asm/blackfin.h>
+
+#if defined(CONFIG_GENERIC_BOARD) || defined(CONFIG_BFIN537_STAMP)
+
+/*
+ * Currently the MAC address is saved in Flash by U-Boot
+ */
+#define FLASH_MAC 0x203f0000
+
+void get_bf537_ether_addr(char *addr)
+{
+ unsigned int flash_mac = (unsigned int) FLASH_MAC;
+ *(u32 *)(&(addr[0])) = bfin_read32(flash_mac);
+ flash_mac += 4;
+ *(u16 *)(&(addr[4])) = bfin_read16(flash_mac);
+}
+
+#else
+
+/*
+ * Provide MAC address function for other specific board setting
+ */
+void get_bf537_ether_addr(char *addr)
+{
+ printk(KERN_WARNING "%s: No valid Ethernet MAC address found\n", __FILE__);
+}
+
+#endif
+
+EXPORT_SYMBOL(get_bf537_ether_addr);
diff --git a/arch/blackfin/mach-bf527/boards/ezkit.c b/arch/blackfin/mach-bf527/boards/ezkit.c
new file mode 100644
index 00000000000..3e884f3a818
--- /dev/null
+++ b/arch/blackfin/mach-bf527/boards/ezkit.c
@@ -0,0 +1,737 @@
+/*
+ * File: arch/blackfin/mach-bf527/boards/ezkit.c
+ * Based on: arch/blackfin/mach-bf537/boards/stamp.c
+ * Author: Aidan Williams <aidan@nicta.com.au>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ * Copyright 2005 National ICT Australia (NICTA)
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+#include <linux/usb_isp1362.h>
+#endif
+#include <linux/pata_platform.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/usb_sl811.h>
+#include <asm/dma.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/reboot.h>
+#include <linux/spi/ad7877.h>
+
+/*
+ * Name the Board for the /proc/cpuinfo
+ */
+const char bfin_board_name[] = "ADDS-BF527-EZKIT";
+
+/*
+ * Driver needs to know address, irq and flag pin.
+ */
+
+#define ISP1761_BASE 0x203C0000
+#define ISP1761_IRQ IRQ_PF7
+
+#if defined(CONFIG_USB_ISP1760_HCD) || defined(CONFIG_USB_ISP1760_HCD_MODULE)
+static struct resource bfin_isp1761_resources[] = {
+ [0] = {
+ .name = "isp1761-regs",
+ .start = ISP1761_BASE + 0x00000000,
+ .end = ISP1761_BASE + 0x000fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ISP1761_IRQ,
+ .end = ISP1761_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_isp1761_device = {
+ .name = "isp1761",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_isp1761_resources),
+ .resource = bfin_isp1761_resources,
+};
+
+static struct platform_device *bfin_isp1761_devices[] = {
+ &bfin_isp1761_device,
+};
+
+int __init bfin_isp1761_init(void)
+{
+ unsigned int num_devices = ARRAY_SIZE(bfin_isp1761_devices);
+
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ set_irq_type(ISP1761_IRQ, IRQF_TRIGGER_FALLING);
+
+ return platform_add_devices(bfin_isp1761_devices, num_devices);
+}
+
+void __exit bfin_isp1761_exit(void)
+{
+ platform_device_unregister(&bfin_isp1761_device);
+}
+
+arch_initcall(bfin_isp1761_init);
+#endif
+
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+static struct resource bfin_pcmcia_cf_resources[] = {
+ {
+ .start = 0x20310000, /* IO PORT */
+ .end = 0x20312000,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0x20311000, /* Attribute Memory */
+ .end = 0x20311FFF,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PF4,
+ .end = IRQ_PF4,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+ }, {
+ .start = 6, /* Card Detect PF6 */
+ .end = 6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pcmcia_cf_device = {
+ .name = "bfin_cf_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pcmcia_cf_resources),
+ .resource = bfin_pcmcia_cf_resources,
+};
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+static struct platform_device rtc_device = {
+ .name = "rtc-bfin",
+ .id = -1,
+};
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+static struct resource smc91x_resources[] = {
+ {
+ .name = "smc91x-regs",
+ .start = 0x20300300,
+ .end = 0x20300300 + 16,
+ .flags = IORESOURCE_MEM,
+ }, {
+
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+static struct platform_device smc91x_device = {
+ .name = "smc91x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smc91x_resources),
+ .resource = smc91x_resources,
+};
+#endif
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+static struct resource dm9000_resources[] = {
+ [0] = {
+ .start = 0x203FB800,
+ .end = 0x203FB800 + 8,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_PF9,
+ .end = IRQ_PF9,
+ .flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
+ },
+};
+
+static struct platform_device dm9000_device = {
+ .name = "dm9000",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(dm9000_resources),
+ .resource = dm9000_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+static struct resource sl811_hcd_resources[] = {
+ {
+ .start = 0x20340000,
+ .end = 0x20340000,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0x20340004,
+ .end = 0x20340004,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = CONFIG_USB_SL811_BFIN_IRQ,
+ .end = CONFIG_USB_SL811_BFIN_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+void sl811_port_power(struct device *dev, int is_on)
+{
+ gpio_request(CONFIG_USB_SL811_BFIN_GPIO_VBUS, "usb:SL811_VBUS");
+ gpio_direction_output(CONFIG_USB_SL811_BFIN_GPIO_VBUS);
+
+ if (is_on)
+ gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 1);
+ else
+ gpio_set_value(CONFIG_USB_SL811_BFIN_GPIO_VBUS, 0);
+}
+#endif
+
+static struct sl811_platform_data sl811_priv = {
+ .potpg = 10,
+ .power = 250, /* == 500mA */
+#if defined(CONFIG_USB_SL811_BFIN_USE_VBUS)
+ .port_power = &sl811_port_power,
+#endif
+};
+
+static struct platform_device sl811_hcd_device = {
+ .name = "sl811-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &sl811_priv,
+ },
+ .num_resources = ARRAY_SIZE(sl811_hcd_resources),
+ .resource = sl811_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+static struct resource isp1362_hcd_resources[] = {
+ {
+ .start = 0x20360000,
+ .end = 0x20360000,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 0x20360004,
+ .end = 0x20360004,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .end = CONFIG_USB_ISP1362_BFIN_GPIO_IRQ,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct isp1362_platform_data isp1362_priv = {
+ .sel15Kres = 1,
+ .clknotstop = 0,
+ .oc_enable = 0,
+ .int_act_high = 0,
+ .int_edge_triggered = 0,
+ .remote_wakeup_connected = 0,
+ .no_power_switching = 1,
+ .power_switching_mode = 0,
+};
+
+static struct platform_device isp1362_hcd_device = {
+ .name = "isp1362-hcd",
+ .id = 0,
+ .dev = {
+ .platform_data = &isp1362_priv,
+ },
+ .num_resources = ARRAY_SIZE(isp1362_hcd_resources),
+ .resource = isp1362_hcd_resources,
+};
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static struct platform_device bfin_mac_device = {
+ .name = "bfin_mac",
+};
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+static struct resource net2272_bfin_resources[] = {
+ {
+ .start = 0x20300000,
+ .end = 0x20300000 + 0x100,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PF7,
+ .end = IRQ_PF7,
+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
+ },
+};
+
+static struct platform_device net2272_bfin_device = {
+ .name = "net2272",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(net2272_bfin_resources),
+ .resource = net2272_bfin_resources,
+};
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+/* all SPI peripherals info goes here */
+
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition bfin_spi_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_CAP_ROM
+ }, {
+ .name = "kernel",
+ .size = 0xe0000,
+ .offset = 0x20000
+ }, {
+ .name = "file system",
+ .size = 0x700000,
+ .offset = 0x00100000,
+ }
+};
+
+static struct flash_platform_data bfin_spi_flash_data = {
+ .name = "m25p80",
+ .parts = bfin_spi_flash_partitions,
+ .nr_parts = ARRAY_SIZE(bfin_spi_flash_partitions),
+ .type = "m25p64",
+};
+
+/* SPI flash chip (m25p64) */
+static struct bfin5xx_spi_chip spi_flash_chip_info = {
+ .enable_dma = 0, /* use dma transfer with this chip*/
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+/* SPI ADC chip */
+static struct bfin5xx_spi_chip spi_adc_chip_info = {
+ .enable_dma = 1, /* use dma transfer with this chip*/
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+static struct bfin5xx_spi_chip ad1836_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+static struct bfin5xx_spi_chip ad9960_spi_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+static struct bfin5xx_spi_chip spi_mmc_chip_info = {
+ .enable_dma = 1,
+ .bits_per_word = 8,
+};
+#endif
+
+#if defined(CONFIG_PBX)
+static struct bfin5xx_spi_chip spi_si3xxx_chip_info = {
+ .ctl_reg = 0x4, /* send zero */
+ .enable_dma = 0,
+ .bits_per_word = 8,
+ .cs_change_per_word = 1,
+};
+#endif
+
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+static struct bfin5xx_spi_chip ad5304_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+static struct bfin5xx_spi_chip spi_ad7877_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+
+static const struct ad7877_platform_data bfin_ad7877_ts_info = {
+ .model = 7877,
+ .vref_delay_usecs = 50, /* internal, no capacitor */
+ .x_plate_ohms = 419,
+ .y_plate_ohms = 486,
+ .pressure_max = 1000,
+ .pressure_min = 0,
+ .stopacq_polarity = 1,
+ .first_conversion_delay = 3,
+ .acquisition_time = 1,
+ .averaging = 1,
+ .pen_down_acc_interval = 1,
+};
+#endif
+
+static struct spi_board_info bfin_spi_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80) \
+ || defined(CONFIG_MTD_M25P80_MODULE)
+ {
+ /* the modalias must be the same as spi device driver name */
+ .modalias = "m25p80", /* Name of spi_driver for this device */
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
+ .platform_data = &bfin_spi_flash_data,
+ .controller_data = &spi_flash_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+
+#if defined(CONFIG_SPI_ADC_BF533) \
+ || defined(CONFIG_SPI_ADC_BF533_MODULE)
+ {
+ .modalias = "bfin_spi_adc", /* Name of spi_driver for this device */
+ .max_speed_hz = 6250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0, /* Framework bus number */
+ .chip_select = 1, /* Framework chip select. */
+ .platform_data = NULL, /* No spi_driver specific config */
+ .controller_data = &spi_adc_chip_info,
+ },
+#endif
+
+#if defined(CONFIG_SND_BLACKFIN_AD1836) \
+ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE)
+ {
+ .modalias = "ad1836-spi",
+ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = CONFIG_SND_BLACKFIN_SPI_PFBIT,
+ .controller_data = &ad1836_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_AD9960) || defined(CONFIG_AD9960_MODULE)
+ {
+ .modalias = "ad9960-spi",
+ .max_speed_hz = 10000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 1,
+ .controller_data = &ad9960_spi_chip_info,
+ },
+#endif
+#if defined(CONFIG_SPI_MMC) || defined(CONFIG_SPI_MMC_MODULE)
+ {
+ .modalias = "spi_mmc_dummy",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 0,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "spi_mmc",
+ .max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = CONFIG_SPI_MMC_CS_CHAN,
+ .platform_data = NULL,
+ .controller_data = &spi_mmc_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_PBX)
+ {
+ .modalias = "fxs-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 8 - CONFIG_J11_JUMPER,
+ .controller_data = &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+ {
+ .modalias = "fxo-spi",
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 8 - CONFIG_J19_JUMPER,
+ .controller_data = &spi_si3xxx_chip_info,
+ .mode = SPI_MODE_3,
+ },
+#endif
+#if defined(CONFIG_AD5304) || defined(CONFIG_AD5304_MODULE)
+ {
+ .modalias = "ad5304_spi",
+ .max_speed_hz = 1250000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 0,
+ .chip_select = 2,
+ .platform_data = NULL,
+ .controller_data = &ad5304_chip_info,
+ .mode = SPI_MODE_2,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7877) || defined(CONFIG_TOUCHSCREEN_AD7877_MODULE)
+ {
+ .modalias = "ad7877",
+ .platform_data = &bfin_ad7877_ts_info,
+ .irq = IRQ_PF6,
+ .max_speed_hz = 12500000, /* max spi clock (SCK) speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ .controller_data = &spi_ad7877_chip_info,
+ },
+#endif
+};
+
+/* SPI controller data */
+static struct bfin5xx_spi_master bfin_spi0_info = {
+ .num_chipselect = 8,
+ .enable_dma = 1, /* master has the ability to do dma transfer */
+};
+
+/* SPI (0) */
+static struct resource bfin_spi0_resource[] = {
+ [0] = {
+ .start = SPI0_REGBASE,
+ .end = SPI0_REGBASE + 0xFF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CH_SPI,
+ .end = CH_SPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_spi0_device = {
+ .name = "bfin-spi",
+ .id = 0, /* Bus number */
+ .num_resources = ARRAY_SIZE(bfin_spi0_resource),
+ .resource = bfin_spi0_resource,
+ .dev = {
+ .platform_data = &bfin_spi0_info, /* Passed to driver */
+ },
+};
+#endif /* spi master and devices */
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+static struct platform_device bfin_fb_device = {
+ .name = "bf537-lq035",
+};
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+static struct platform_device bfin_fb_adv7393_device = {
+ .name = "bfin-adv7393",
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+static struct resource bfin_uart_resources[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ {
+ .start = 0xFFC00400,
+ .end = 0xFFC004FF,
+ .flags = IORESOURCE_MEM,
+ },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ {
+ .start = 0xFFC02000,
+ .end = 0xFFC020FF,
+ .flags = IORESOURCE_MEM,
+ },
+#endif
+};
+
+static struct platform_device bfin_uart_device = {
+ .name = "bfin-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(bfin_uart_resources),
+ .resource = bfin_uart_resources,
+};
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+static struct resource bfin_twi0_resource[] = {
+ [0] = {
+ .start = TWI0_REGBASE,
+ .end = TWI0_REGBASE,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TWI,
+ .end = IRQ_TWI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device i2c_bfin_twi_device = {
+ .name = "i2c-bfin-twi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(bfin_twi0_resource),
+ .resource = bfin_twi0_resource,
+};
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+static struct platform_device bfin_sport0_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 0,
+};
+
+static struct platform_device bfin_sport1_uart_device = {
+ .name = "bfin-sport-uart",
+ .id = 1,
+};
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+#define PATA_INT 55
+
+static struct pata_platform_info bfin_pata_platform_data = {
+ .ioport_shift = 1,
+ .irq_type = IRQF_TRIGGER_HIGH | IRQF_DISABLED,
+};
+
+static struct resource bfin_pata_resources[] = {
+ {
+ .start = 0x20314020,
+ .end = 0x2031403F,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x2031401C,
+ .end = 0x2031401F,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = PATA_INT,
+ .end = PATA_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device bfin_pata_device = {
+ .name = "pata_platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(bfin_pata_resources),
+ .resource = bfin_pata_resources,
+ .dev = {
+ .platform_data = &bfin_pata_platform_data,
+ }
+};
+#endif
+
+static struct platform_device *stamp_devices[] __initdata = {
+#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE)
+ &bfin_pcmcia_cf_device,
+#endif
+
+#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
+ &rtc_device,
+#endif
+
+#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE)
+ &sl811_hcd_device,
+#endif
+
+#if defined(CONFIG_USB_ISP1362_HCD) || defined(CONFIG_USB_ISP1362_HCD_MODULE)
+ &isp1362_hcd_device,
+#endif
+
+#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
+ &smc91x_device,
+#endif
+
+#if defined(CONFIG_DM9000) || defined(CONFIG_DM9000_MODULE)
+ &dm9000_device,
+#endif
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+ &bfin_mac_device,
+#endif
+
+#if defined(CONFIG_USB_NET2272) || defined(CONFIG_USB_NET2272_MODULE)
+ &net2272_bfin_device,
+#endif
+
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ &bfin_spi0_device,
+#endif
+
+#if defined(CONFIG_FB_BF537_LQ035) || defined(CONFIG_FB_BF537_LQ035_MODULE)
+ &bfin_fb_device,
+#endif
+
+#if defined(CONFIG_FB_BFIN_7393) || defined(CONFIG_FB_BFIN_7393_MODULE)
+ &bfin_fb_adv7393_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE)
+ &bfin_uart_device,
+#endif
+
+#if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE)
+ &i2c_bfin_twi_device,
+#endif
+
+#if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE)
+ &bfin_sport0_uart_device,
+ &bfin_sport1_uart_device,
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ &bfin_pata_device,
+#endif
+};
+
+static int __init stamp_init(void)
+{
+ printk(KERN_INFO "%s(): registering device resources\n", __FUNCTION__);
+ platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices));
+#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
+ spi_register_board_info(bfin_spi_board_info,
+ ARRAY_SIZE(bfin_spi_board_info));
+#endif
+
+#if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE)
+ irq_desc[PATA_INT].status |= IRQ_NOAUTOEN;
+#endif
+ return 0;
+}
+
+arch_initcall(stamp_init);
+
+void native_machine_restart(char *cmd)
+{
+ /* workaround reboot hang when booting from SPI */
+ if ((bfin_read_SYSCR() & 0x7) == 0x3)
+ bfin_gpio_reset_spi0_ssel1();
+}
diff --git a/arch/blackfin/mach-bf527/cpu.c b/arch/blackfin/mach-bf527/cpu.c
new file mode 100644
index 00000000000..1975402b1db
--- /dev/null
+++ b/arch/blackfin/mach-bf527/cpu.c
@@ -0,0 +1,161 @@
+/*
+ * File: arch/blackfin/mach-bf527/cpu.c
+ * Based on: arch/blackfin/mach-bf537/cpu.c
+ * Author: michael.kang@analog.com
+ *
+ * Created:
+ * Description: clock scaling for the bf527
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/dpmc.h>
+#include <linux/fs.h>
+#include <asm/bfin-global.h>
+
+/* CONFIG_CLKIN_HZ=11059200 */
+#define VCO5 (CONFIG_CLKIN_HZ*45) /*497664000 */
+#define VCO4 (CONFIG_CLKIN_HZ*36) /*398131200 */
+#define VCO3 (CONFIG_CLKIN_HZ*27) /*298598400 */
+#define VCO2 (CONFIG_CLKIN_HZ*18) /*199065600 */
+#define VCO1 (CONFIG_CLKIN_HZ*9) /*99532800 */
+#define VCO(x) VCO##x
+
+#define MFREQ(x) {VCO(x), VCO(x)/4}, {VCO(x), VCO(x)/2}, {VCO(x), VCO(x)}
+/* frequency */
+static struct cpufreq_frequency_table bf527_freq_table[] = {
+ MFREQ(1),
+ MFREQ(3),
+ {VCO4, VCO4 / 2}, {VCO4, VCO4},
+ MFREQ(5),
+ {0, CPUFREQ_TABLE_END},
+};
+
+/*
+ * dpmc_fops->ioctl()
+ * static int dpmc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+ */
+static int bf527_getfreq(unsigned int cpu)
+{
+ unsigned long cclk_mhz;
+
+ /* The driver only support single cpu */
+ if (cpu == 0)
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_GET_CORECLOCK, &cclk_mhz);
+ else
+ cclk_mhz = -1;
+
+ return cclk_mhz;
+}
+
+static int bf527_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ unsigned long cclk_mhz;
+ unsigned long vco_mhz;
+ unsigned long flags;
+ unsigned int index;
+ struct cpufreq_freqs freqs;
+
+ if (cpufreq_frequency_table_target
+ (policy, bf527_freq_table, target_freq, relation, &index))
+ return -EINVAL;
+
+ cclk_mhz = bf527_freq_table[index].frequency;
+ vco_mhz = bf527_freq_table[index].index;
+
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_CHANGE_FREQUENCY, &vco_mhz);
+ freqs.old = bf527_getfreq(0);
+ freqs.new = cclk_mhz;
+ freqs.cpu = 0;
+
+ pr_debug
+ ("cclk begin change to cclk %d,vco=%d,index=%d,target=%d,oldfreq=%d\n",
+ cclk_mhz, vco_mhz, index, target_freq, freqs.old);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ local_irq_save(flags);
+ dpmc_fops.ioctl(NULL, NULL, IOCTL_SET_CCLK, &cclk_mhz);
+ local_irq_restore(flags);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ vco_mhz = get_vco();
+ cclk_mhz = get_cclk();
+ return 0;
+}
+
+/* make sure that only the "userspace" governor is run -- anything else wouldn't make sense on
+ * this platform, anyway.
+ */
+static int bf527_verify_speed(struct cpufreq_policy *policy)
+{
+ return cpufreq_frequency_table_verify(policy, &bf527_freq_table);
+}
+
+static int __init __bf527_cpu_init(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ /*Now ,only support one cpu */
+ policy->cur = bf527_getfreq(0);
+ cpufreq_frequency_table_get_attr(bf527_freq_table, policy->cpu);
+ return cpufreq_frequency_table_cpuinfo(policy, bf527_freq_table);
+}
+
+static struct freq_attr *bf527_freq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver bf527_driver = {
+ .verify = bf527_verify_speed,
+ .target = bf527_target,
+ .get = bf527_getfreq,
+ .init = __bf527_cpu_init,
+ .name = "bf527",
+ .owner = THIS_MODULE,
+ .attr = bf527_freq_attr,
+};
+
+static int __init bf527_cpu_init(void)
+{
+ return cpufreq_register_driver(&bf527_driver);
+}
+
+static void __exit bf527_cpu_exit(void)
+{
+ cpufreq_unregister_driver(&bf527_driver);
+}
+
+MODULE_AUTHOR("Mickael Kang");
+MODULE_DESCRIPTION("cpufreq driver for bf527 CPU");
+MODULE_LICENSE("GPL");
+
+module_init(bf527_cpu_init);
+module_exit(bf527_cpu_exit);
diff --git a/arch/blackfin/mach-bf527/dma.c b/arch/blackfin/mach-bf527/dma.c
new file mode 100644
index 00000000000..522de24cc39
--- /dev/null
+++ b/arch/blackfin/mach-bf527/dma.c
@@ -0,0 +1,115 @@
+/*
+ * File: arch/blackfin/mach-bf527/dma.c
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description: This file contains the simple DMA Implementation for Blackfin
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <asm/blackfin.h>
+#include <asm/dma.h>
+
+struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
+ (struct dma_register *) DMA0_NEXT_DESC_PTR,
+ (struct dma_register *) DMA1_NEXT_DESC_PTR,
+ (struct dma_register *) DMA2_NEXT_DESC_PTR,
+ (struct dma_register *) DMA3_NEXT_DESC_PTR,
+ (struct dma_register *) DMA4_NEXT_DESC_PTR,
+ (struct dma_register *) DMA5_NEXT_DESC_PTR,
+ (struct dma_register *) DMA6_NEXT_DESC_PTR,
+ (struct dma_register *) DMA7_NEXT_DESC_PTR,
+ (struct dma_register *) DMA8_NEXT_DESC_PTR,
+ (struct dma_register *) DMA9_NEXT_DESC_PTR,
+ (struct dma_register *) DMA10_NEXT_DESC_PTR,
+ (struct dma_register *) DMA11_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
+ (struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
+};
+
+int channel2irq(unsigned int channel)
+{
+ int ret_irq = -1;
+
+ switch (channel) {
+ case CH_PPI:
+ ret_irq = IRQ_PPI;
+ break;
+
+ case CH_EMAC_RX:
+ ret_irq = IRQ_MAC_RX;
+ break;
+
+ case CH_EMAC_TX:
+ ret_irq = IRQ_MAC_TX;
+ break;
+
+ case CH_UART1_RX:
+ ret_irq = IRQ_UART1_RX;
+ break;
+
+ case CH_UART1_TX:
+ ret_irq = IRQ_UART1_TX;
+ break;
+
+ case CH_SPORT0_RX:
+ ret_irq = IRQ_SPORT0_RX;
+ break;
+
+ case CH_SPORT0_TX:
+ ret_irq = IRQ_SPORT0_TX;
+ break;
+
+ case CH_SPORT1_RX:
+ ret_irq = IRQ_SPORT1_RX;
+ break;
+
+ case CH_SPORT1_TX:
+ ret_irq = IRQ_SPORT1_TX;
+ break;
+
+ case CH_SPI:
+ ret_irq = IRQ_SPI;
+ break;
+
+ case CH_UART0_RX:
+ ret_irq = IRQ_UART0_RX;
+ break;
+
+ case CH_UART0_TX:
+ ret_irq = IRQ_UART0_TX;
+ break;
+
+ case CH_MEM_STREAM0_SRC:
+ case CH_MEM_STREAM0_DEST:
+ ret_irq = IRQ_MEM_DMA0;
+ break;
+
+ case CH_MEM_STREAM1_SRC:
+ case CH_MEM_STREAM1_DEST:
+ ret_irq = IRQ_MEM_DMA1;
+ break;
+ }
+ return ret_irq;
+}
diff --git a/arch/blackfin/mach-bf527/head.S b/arch/blackfin/mach-bf527/head.S
new file mode 100644
index 00000000000..cdb00a08496
--- /dev/null
+++ b/arch/blackfin/mach-bf527/head.S
@@ -0,0 +1,456 @@
+/*
+ * File: arch/blackfin/mach-bf527/head.S
+ * Based on: arch/blackfin/mach-bf533/head.S
+ * Author: Jeff Dionne <jeff@uclinux.org> COPYRIGHT 1998 D. Jeff Dionne
+ *
+ * Created: 1998
+ * Description: Startup code for Blackfin BF537
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/blackfin.h>
+#include <asm/trace.h>
+
+#if CONFIG_BFIN_KERNEL_CLOCK
+#include <asm/mach-common/clocks.h>
+#include <asm/mach/mem_init.h>
+#endif
+
+.global __rambase
+.global __ramstart
+.global __ramend
+.extern ___bss_stop
+.extern ___bss_start
+.extern _bf53x_relocate_l1_mem
+
+#define INITIAL_STACK 0xFFB01000
+
+__INIT
+
+ENTRY(__start)
+ /* R0: argument of command line string, passed from uboot, save it */
+ R7 = R0;
+ /* Enable Cycle Counter and Nesting Of Interrupts */
+#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES
+ R0 = SYSCFG_SNEN;
+#else
+ R0 = SYSCFG_SNEN | SYSCFG_CCEN;
+#endif
+ SYSCFG = R0;
+ R0 = 0;
+
+ /* Clear Out All the data and pointer Registers */
+ R1 = R0;
+ R2 = R0;
+ R3 = R0;
+ R4 = R0;
+ R5 = R0;
+ R6 = R0;
+
+ P0 = R0;
+ P1 = R0;
+ P2 = R0;
+ P3 = R0;
+ P4 = R0;
+ P5 = R0;
+
+ LC0 = r0;
+ LC1 = r0;
+ L0 = r0;
+ L1 = r0;
+ L2 = r0;
+ L3 = r0;
+
+ /* Clear Out All the DAG Registers */
+ B0 = r0;
+ B1 = r0;
+ B2 = r0;
+ B3 = r0;
+
+ I0 = r0;
+ I1 = r0;
+ I2 = r0;
+ I3 = r0;
+
+ M0 = r0;
+ M1 = r0;
+ M2 = r0;
+ M3 = r0;
+
+ trace_buffer_init(p0,r0);
+ P0 = R1;
+ R0 = R1;
+
+ /* Turn off the icache */
+ p0.l = LO(IMEM_CONTROL);
+ p0.h = HI(IMEM_CONTROL);
+ R1 = [p0];
+ R0 = ~ENICPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#if ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#if ANOMALY_05000125
+ STI R2;
+#endif
+
+ /* Turn off the dcache */
+ p0.l = LO(DMEM_CONTROL);
+ p0.h = HI(DMEM_CONTROL);
+ R1 = [p0];
+ R0 = ~ENDCPLB;
+ R0 = R0 & R1;
+
+ /* Anomaly 05000125 */
+#if ANOMALY_05000125
+ CLI R2;
+ SSYNC;
+#endif
+ [p0] = R0;
+ SSYNC;
+#if ANOMALY_05000125
+ STI R2;
+#endif
+
+
+#if defined(CONFIG_BF527)
+ p0.h = hi(EMAC_SYSTAT);
+ p0.l = lo(EMAC_SYSTAT);
+ R0.h = 0xFFFF; /* Clear EMAC Interrupt Status bits */
+ R0.l = 0xFFFF;
+ [P0] = R0;
+ SSYNC;
+#endif
+
+ /* Initialise UART - when booting from u-boot, the UART is not disabled
+ * so if we dont initalize here, our serial console gets hosed */
+ p0.h = hi(UART1_LCR);
+ p0.l = lo(UART1_LCR);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable DLL writes */
+ ssync;
+
+ p0.h = hi(UART1_DLL);
+ p0.l = lo(UART1_DLL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART1_DLH);
+ p0.l = lo(UART1_DLH);
+ r0 = 0x00(Z);
+ w[p0] = r0.L;
+ ssync;
+
+ p0.h = hi(UART1_GCTL);
+ p0.l = lo(UART1_GCTL);
+ r0 = 0x0(Z);
+ w[p0] = r0.L; /* To enable UART clock */
+ ssync;
+
+ /* Initialize stack pointer */
+ sp.l = lo(INITIAL_STACK);
+ sp.h = hi(INITIAL_STACK);
+ fp = sp;
+ usp = sp;
+
+#ifdef CONFIG_EARLY_PRINTK
+ SP += -12;
+ call _init_early_exception_vectors;
+ SP += 12;
+#endif
+
+ /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */
+ call _bf53x_relocate_l1_mem;
+#if CONFIG_BFIN_KERNEL_CLOCK
+ call _start_dma_code;
+#endif
+
+ /* Code for initializing Async memory banks */
+
+ p2.h = hi(EBIU_AMBCTL1);
+ p2.l = lo(EBIU_AMBCTL1);
+ r0.h = hi(AMBCTL1VAL);
+ r0.l = lo(AMBCTL1VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMBCTL0);
+ p2.l = lo(EBIU_AMBCTL0);
+ r0.h = hi(AMBCTL0VAL);
+ r0.l = lo(AMBCTL0VAL);
+ [p2] = r0;
+ ssync;
+
+ p2.h = hi(EBIU_AMGCTL);
+ p2.l = lo(EBIU_AMGCTL);
+ r0 = AMGCTLVAL;
+ w[p2] = r0;
+ ssync;
+
+ /* This section keeps the processor in supervisor mode
+ * during kernel boot. Switches to user mode at end of boot.
+ * See page 3-9 of Hardware Reference manual for documentation.
+ */
+
+ /* EVT15 = _real_start */
+
+ p0.l = lo(EVT15);
+ p0.h = hi(EVT15);
+ p1.l = _real_start;
+ p1.h = _real_start;
+ [p0] = p1;
+ csync;
+
+ p0.l = lo(IMASK);
+ p0.h = hi(IMASK);
+ p1.l = IMASK_IVG15;
+ p1.h = 0x0;
+ [p0] = p1;
+ csync;
+
+ raise 15;
+ p0.l = .LWAIT_HERE;
+ p0.h = .LWAIT_HERE;
+ reti = p0;
+#if ANOMALY_05000281
+ nop; nop; nop;
+#endif
+ rti;
+
+.LWAIT_HERE:
+ jump .LWAIT_HERE;
+ENDPROC(__start)
+
+ENTRY(_real_start)
+ [ -- sp ] = reti;
+ p0.l = lo(WDOG_CTL);
+ p0.h = hi(WDOG_CTL);
+ r0 = 0xAD6(z);
+ w[p0] = r0; /* watchdog off for now */
+ ssync;
+
+ /* Code update for BSS size == 0
+ * Zero out the bss region.
+ */
+
+ p1.l = ___bss_start;
+ p1.h = ___bss_start;
+ p2.l = ___bss_stop;
+ p2.h = ___bss_stop;
+ r0 = 0;
+ p2 -= p1;
+ lsetup (.L_clear_bss, .L_clear_bss) lc0 = p2;
+.L_clear_bss:
+ B[p1++] = r0;
+
+ /* In case there is a NULL pointer reference
+ * Zero out region before stext
+ */
+
+ p1.l = 0x0;
+ p1.h = 0x0;
+ r0.l = __stext;
+ r0.h = __stext;
+ r0 = r0 >> 1;
+ p2 = r0;
+ r0 = 0;
+ lsetup (.L_clear_zero, .L_clear_zero) lc0 = p2;
+.L_clear_zero:
+ W[p1++] = r0;
+
+ /* pass the uboot arguments to the global value command line */
+ R0 = R7;
+ call _cmdline_init;
+
+ p1.l = __rambase;
+ p1.h = __rambase;
+ r0.l = __sdata;
+ r0.h = __sdata;
+ [p1] = r0;
+
+ p1.l = __ramstart;
+ p1.h = __ramstart;
+ p3.l = ___bss_stop;
+ p3.h = ___bss_stop;
+
+ r1 = p3;
+ [p1] = r1;
+
+ /*
+ * load the current thread pointer and stack
+ */
+ r1.l = _init_thread_union;
+ r1.h = _init_thread_union;
+
+ r2.l = 0x2000;
+ r2.h = 0x0000;
+ r1 = r1 + r2;
+ sp = r1;
+ usp = sp;
+ fp = sp;
+ jump.l _start_kernel;
+ENDPROC(_real_start)
+
+__FINIT
+
+.section .l1.text
+#if CONFIG_BFIN_KERNEL_CLOCK
+ENTRY(_start_dma_code)
+
+ /* Enable PHY CLK buffer output */
+ p0.h = hi(VR_CTL);
+ p0.l = lo(VR_CTL);
+ r0.l = w[p0];
+ bitset(r0, 14);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.h = hi(SIC_IWR0);
+ p0.l = lo(SIC_IWR0);
+ r0.l = 0x1;
+ r0.h = 0x0;
+ [p0] = r0;
+ SSYNC;
+
+ /*
+ * Set PLL_CTL
+ * - [14:09] = MSEL[5:0] : CLKIN / VCO multiplication factors
+ * - [8] = BYPASS : BYPASS the PLL, run CLKIN into CCLK/SCLK
+ * - [7] = output delay (add 200ps of delay to mem signals)
+ * - [6] = input delay (add 200ps of input delay to mem signals)
+ * - [5] = PDWN : 1=All Clocks off
+ * - [3] = STOPCK : 1=Core Clock off
+ * - [1] = PLL_OFF : 1=Disable Power to PLL
+ * - [0] = DF : 1=Pass CLKIN/2 to PLL / 0=Pass CLKIN to PLL
+ * all other bits set to zero
+ */
+
+ p0.h = hi(PLL_LOCKCNT);
+ p0.l = lo(PLL_LOCKCNT);
+ r0 = 0x300(Z);
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITSET (R0, 24);
+ [P2] = R0;
+ SSYNC;
+
+ r0 = CONFIG_VCO_MULT & 63; /* Load the VCO multiplier */
+ r0 = r0 << 9; /* Shift it over, */
+ r1 = CLKIN_HALF; /* Do we need to divide CLKIN by 2?*/
+ r0 = r1 | r0;
+ r1 = PLL_BYPASS; /* Bypass the PLL? */
+ r1 = r1 << 8; /* Shift it over */
+ r0 = r1 | r0; /* add them all together */
+
+ p0.h = hi(PLL_CTL);
+ p0.l = lo(PLL_CTL); /* Load the address */
+ cli r2; /* Disable interrupts */
+ ssync;
+ w[p0] = r0.l; /* Set the value */
+ idle; /* Wait for the PLL to stablize */
+ sti r2; /* Enable interrupts */
+
+.Lcheck_again:
+ p0.h = hi(PLL_STAT);
+ p0.l = lo(PLL_STAT);
+ R0 = W[P0](Z);
+ CC = BITTST(R0,5);
+ if ! CC jump .Lcheck_again;
+
+ /* Configure SCLK & CCLK Dividers */
+ r0 = (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV);
+ p0.h = hi(PLL_DIV);
+ p0.l = lo(PLL_DIV);
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = lo(EBIU_SDRRC);
+ p0.h = hi(EBIU_SDRRC);
+ r0 = mem_SDRRC;
+ w[p0] = r0.l;
+ ssync;
+
+ p0.l = LO(EBIU_SDBCTL);
+ p0.h = HI(EBIU_SDBCTL); /* SDRAM Memory Bank Control Register */
+ r0 = mem_SDBCTL;
+ w[p0] = r0.l;
+ ssync;
+
+ P2.H = hi(EBIU_SDGCTL);
+ P2.L = lo(EBIU_SDGCTL);
+ R0 = [P2];
+ BITCLR (R0, 24);
+ p0.h = hi(EBIU_SDSTAT);
+ p0.l = lo(EBIU_SDSTAT);
+ r2.l = w[p0];
+ cc = bittst(r2,3);
+ if !cc jump .Lskip;
+ NOP;
+ BITSET (R0, 23);
+.Lskip:
+ [P2] = R0;
+ SSYNC;
+
+ R0.L = lo(mem_SDGCTL);
+ R0.H = hi(mem_SDGCTL);
+ R1 = [p2];
+ R1 = R1 | R0;
+ [P2] = R1;
+ SSYNC;
+
+ p0.h = hi(SIC_IWR0);
+ p0.l = lo(SIC_IWR0);
+ r0.l = lo(IWR_ENABLE_ALL);
+ r0.h = hi(IWR_ENABLE_ALL);
+ [p0] = r0;
+ SSYNC;
+
+ RTS;
+ENDPROC(_start_dma_code)
+#endif /* CONFIG_BFIN_KERNEL_CLOCK */
+
+.data
+
+/*
+ * Set up the usable of RAM stuff. Size of RAM is determined then
+ * an initial stack set up at the end.
+ */
+
+.align 4
+__rambase:
+.long 0
+__ramstart:
+.long 0
+__ramend:
+.long 0
diff --git a/arch/blackfin/mach-bf527/ints-priority.c b/arch/blackfin/mach-bf527/ints-priority.c
new file mode 100644
index 00000000000..1fa38979396
--- /dev/null
+++ b/arch/blackfin/mach-bf527/ints-priority.c
@@ -0,0 +1,100 @@
+/*
+ * File: arch/blackfin/mach-bf537/ints-priority.c
+ * Based on: arch/blackfin/mach-bf533/ints-priority.c
+ * Author: Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description: Set up the interrupt priorities
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <asm/blackfin.h>
+
+void program_IAR(void)
+{
+ /* Program the IAR0 Register with the configured priority */
+ bfin_write_SIC_IAR0(((CONFIG_IRQ_PLL_WAKEUP - 7) << IRQ_PLL_WAKEUP_POS) |
+ ((CONFIG_IRQ_DMA0_ERROR - 7) << IRQ_DMA0_ERROR_POS) |
+ ((CONFIG_IRQ_DMAR0_BLK - 7) << IRQ_DMAR0_BLK_POS) |
+ ((CONFIG_IRQ_DMAR1_BLK - 7) << IRQ_DMAR1_BLK_POS) |
+ ((CONFIG_IRQ_DMAR0_OVR - 7) << IRQ_DMAR0_OVR_POS) |
+ ((CONFIG_IRQ_DMAR1_OVR - 7) << IRQ_DMAR1_OVR_POS) |
+ ((CONFIG_IRQ_PPI_ERROR - 7) << IRQ_PPI_ERROR_POS) |
+ ((CONFIG_IRQ_MAC_ERROR - 7) << IRQ_MAC_ERROR_POS));
+
+
+ bfin_write_SIC_IAR1(((CONFIG_IRQ_SPORT0_ERROR - 7) << IRQ_SPORT0_ERROR_POS) |
+ ((CONFIG_IRQ_SPORT1_ERROR - 7) << IRQ_SPORT1_ERROR_POS) |
+ ((CONFIG_IRQ_UART0_ERROR - 7) << IRQ_UART0_ERROR_POS) |
+ ((CONFIG_IRQ_UART1_ERROR - 7) << IRQ_UART1_ERROR_POS) |
+ ((CONFIG_IRQ_RTC - 7) << IRQ_RTC_POS) |
+ ((CONFIG_IRQ_PPI - 7) << IRQ_PPI_POS));
+
+ bfin_write_SIC_IAR2(((CONFIG_IRQ_SPORT0_RX - 7) << IRQ_SPORT0_RX_POS) |
+ ((CONFIG_IRQ_SPORT0_TX - 7) << IRQ_SPORT0_TX_POS) |
+ ((CONFIG_IRQ_SPORT1_RX - 7) << IRQ_SPORT1_RX_POS) |
+ ((CONFIG_IRQ_SPORT1_TX - 7) << IRQ_SPORT1_TX_POS) |
+ ((CONFIG_IRQ_TWI - 7) << IRQ_TWI_POS) |
+ ((CONFIG_IRQ_SPI - 7) << IRQ_SPI_POS) |
+ ((CONFIG_IRQ_UART0_RX - 7) << IRQ_UART0_RX_POS) |
+ ((CONFIG_IRQ_UART0_TX - 7) << IRQ_UART0_TX_POS));
+
+ bfin_write_SIC_IAR3(((CONFIG_IRQ_UART1_RX - 7) << IRQ_UART1_RX_POS) |
+ ((CONFIG_IRQ_UART1_TX - 7) << IRQ_UART1_TX_POS) |
+ ((CONFIG_IRQ_OPTSEC - 7) << IRQ_OPTSEC_POS) |
+ ((CONFIG_IRQ_CNT - 7) << IRQ_CNT_POS) |
+ ((CONFIG_IRQ_MAC_RX - 7) << IRQ_MAC_RX_POS) |
+ ((CONFIG_IRQ_PORTH_INTA - 7) << IRQ_PORTH_INTA_POS) |
+ ((CONFIG_IRQ_MAC_TX - 7) << IRQ_MAC_TX_POS) |
+ ((CONFIG_IRQ_PORTH_INTB - 7) << IRQ_PORTH_INTB_POS));
+
+ bfin_write_SIC_IAR4(((CONFIG_IRQ_TMR0 - 7) << IRQ_TMR0_POS) |
+ ((CONFIG_IRQ_TMR1 - 7) << IRQ_TMR1_POS) |
+ ((CONFIG_IRQ_TMR2 - 7) << IRQ_TMR2_POS) |
+ ((CONFIG_IRQ_TMR3 - 7) << IRQ_TMR3_POS) |
+ ((CONFIG_IRQ_TMR4 - 7) << IRQ_TMR4_POS) |
+ ((CONFIG_IRQ_TMR5 - 7) << IRQ_TMR5_POS) |
+ ((CONFIG_IRQ_TMR6 - 7) << IRQ_TMR6_POS) |
+ ((CONFIG_IRQ_TMR7 - 7) << IRQ_TMR7_POS));
+
+ bfin_write_SIC_IAR5(((CONFIG_IRQ_PORTG_INTA - 7) << IRQ_PORTG_INTA_POS) |
+ ((CONFIG_IRQ_PORTG_INTB - 7) << IRQ_PORTG_INTB_POS) |
+ ((CONFIG_IRQ_MEM_DMA0 - 7) << IRQ_MEM_DMA0_POS) |
+ ((CONFIG_IRQ_MEM_DMA1 - 7) << IRQ_MEM_DMA1_POS) |
+ ((CONFIG_IRQ_WATCH - 7) << IRQ_WATCH_POS) |
+ ((CONFIG_IRQ_PORTF_INTA - 7) << IRQ_PORTF_INTA_POS) |
+ ((CONFIG_IRQ_PORTF_INTB - 7) << IRQ_PORTF_INTB_POS) |
+ ((CONFIG_IRQ_SPI_ERROR - 7) << IRQ_SPI_ERROR_POS));
+
+ bfin_write_SIC_IAR6(((CONFIG_IRQ_NFC_ERROR - 7) << IRQ_NFC_ERROR_POS) |
+ ((CONFIG_IRQ_HDMA_ERROR - 7) << IRQ_HDMA_ERROR_POS) |
+ ((CONFIG_IRQ_HDMA - 7) << IRQ_HDMA_POS) |
+ ((CONFIG_IRQ_USB_EINT - 7) << IRQ_USB_EINT_POS) |
+ ((CONFIG_IRQ_USB_INT0 - 7) << IRQ_USB_INT0_POS) |
+ ((CONFIG_IRQ_USB_INT1 - 7) << IRQ_USB_INT1_POS) |
+ ((CONFIG_IRQ_USB_INT2 - 7) << IRQ_USB_INT2_POS) |
+ ((CONFIG_IRQ_USB_DMA - 7) << IRQ_USB_DMA_POS));
+
+ SSYNC();
+}
diff --git a/arch/blackfin/mach-bf533/boards/cm_bf533.c b/arch/blackfin/mach-bf533/boards/cm_bf533.c
index a57b52d207c..1c5a86adfab 100644
--- a/arch/blackfin/mach-bf533/boards/cm_bf533.c
+++ b/arch/blackfin/mach-bf533/boards/cm_bf533.c
@@ -42,7 +42,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "Bluetechnix CM BF533";
+const char bfin_board_name[] = "Bluetechnix CM BF533";
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
/* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf533/boards/ezkit.c b/arch/blackfin/mach-bf533/boards/ezkit.c
index 5c1e35d3c01..34b63920e27 100644
--- a/arch/blackfin/mach-bf533/boards/ezkit.c
+++ b/arch/blackfin/mach-bf533/boards/ezkit.c
@@ -43,7 +43,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "ADDS-BF533-EZKIT";
+const char bfin_board_name[] = "ADDS-BF533-EZKIT";
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf533/boards/generic_board.c b/arch/blackfin/mach-bf533/boards/generic_board.c
index 9bc1f0d0ab5..310b7772c45 100644
--- a/arch/blackfin/mach-bf533/boards/generic_board.c
+++ b/arch/blackfin/mach-bf533/boards/generic_board.c
@@ -35,7 +35,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf533/boards/stamp.c b/arch/blackfin/mach-bf533/boards/stamp.c
index 8975e06ea15..f84be4eabfd 100644
--- a/arch/blackfin/mach-bf533/boards/stamp.c
+++ b/arch/blackfin/mach-bf533/boards/stamp.c
@@ -46,7 +46,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "ADDS-BF533-STAMP";
+const char bfin_board_name[] = "ADDS-BF533-STAMP";
#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE)
static struct platform_device rtc_device = {
diff --git a/arch/blackfin/mach-bf537/boards/cm_bf537.c b/arch/blackfin/mach-bf537/boards/cm_bf537.c
index 44dea05e1d0..52e2320307d 100644
--- a/arch/blackfin/mach-bf537/boards/cm_bf537.c
+++ b/arch/blackfin/mach-bf537/boards/cm_bf537.c
@@ -43,7 +43,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "Bluetechnix CM BF537";
+const char bfin_board_name[] = "Bluetechnix CM BF537";
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
/* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf537/boards/generic_board.c b/arch/blackfin/mach-bf537/boards/generic_board.c
index 6668c8e4a3f..255da7a9848 100644
--- a/arch/blackfin/mach-bf537/boards/generic_board.c
+++ b/arch/blackfin/mach-bf537/boards/generic_board.c
@@ -49,7 +49,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "GENERIC Board";
+const char bfin_board_name[] = "GENERIC Board";
/*
* Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf537/boards/pnav10.c b/arch/blackfin/mach-bf537/boards/pnav10.c
index f83a2544004..87b80892678 100644
--- a/arch/blackfin/mach-bf537/boards/pnav10.c
+++ b/arch/blackfin/mach-bf537/boards/pnav10.c
@@ -47,7 +47,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "PNAV-1.0";
+const char bfin_board_name[] = "PNAV-1.0";
/*
* Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index f42ba3aa86d..cc41f6c2ef4 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -49,7 +49,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "ADDS-BF537-STAMP";
+const char bfin_board_name[] = "ADDS-BF537-STAMP";
/*
* Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf548/boards/ezkit.c b/arch/blackfin/mach-bf548/boards/ezkit.c
index 046e6d84bbf..6b6490e66b3 100644
--- a/arch/blackfin/mach-bf548/boards/ezkit.c
+++ b/arch/blackfin/mach-bf548/boards/ezkit.c
@@ -49,7 +49,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "ADSP-BF548-EZKIT";
+const char bfin_board_name[] = "ADSP-BF548-EZKIT";
/*
* Driver needs to know address, irq and flag pin.
@@ -560,7 +560,7 @@ static struct platform_device *ezkit_devices[] __initdata = {
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
&bf54x_spi_master0,
-/* &bf54x_spi_master1,*/
+ &bf54x_spi_master1,
#endif
#if defined(CONFIG_KEYBOARD_BFIN) || defined(CONFIG_KEYBOARD_BFIN_MODULE)
diff --git a/arch/blackfin/mach-bf548/dma.c b/arch/blackfin/mach-bf548/dma.c
index a8184113be4..957bf1366ef 100644
--- a/arch/blackfin/mach-bf548/dma.c
+++ b/arch/blackfin/mach-bf548/dma.c
@@ -64,6 +64,7 @@
(struct dma_register *) MDMA_D3_NEXT_DESC_PTR,
(struct dma_register *) MDMA_S3_NEXT_DESC_PTR,
};
+EXPORT_SYMBOL(base_addr);
int channel2irq(unsigned int channel)
{
diff --git a/arch/blackfin/mach-bf561/boards/cm_bf561.c b/arch/blackfin/mach-bf561/boards/cm_bf561.c
index cd827a1b6ba..97aeb43fd8b 100644
--- a/arch/blackfin/mach-bf561/boards/cm_bf561.c
+++ b/arch/blackfin/mach-bf561/boards/cm_bf561.c
@@ -42,7 +42,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "Bluetechnix CM BF561";
+const char bfin_board_name[] = "Bluetechnix CM BF561";
#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE)
/* all SPI peripherals info goes here */
diff --git a/arch/blackfin/mach-bf561/boards/ezkit.c b/arch/blackfin/mach-bf561/boards/ezkit.c
index 57e14edca8b..059d516cec2 100644
--- a/arch/blackfin/mach-bf561/boards/ezkit.c
+++ b/arch/blackfin/mach-bf561/boards/ezkit.c
@@ -39,7 +39,7 @@
/*
* Name the Board for the /proc/cpuinfo
*/
-char *bfin_board_name = "ADDS-BF561-EZKIT";
+const char bfin_board_name[] = "ADDS-BF561-EZKIT";
#define ISP1761_BASE 0x2C0F0000
#define ISP1761_IRQ IRQ_PF10
diff --git a/arch/blackfin/mach-bf561/boards/generic_board.c b/arch/blackfin/mach-bf561/boards/generic_board.c
index 4dfea5da674..46816be4b2b 100644
--- a/arch/blackfin/mach-bf561/boards/generic_board.c
+++ b/arch/blackfin/mach-bf561/boards/generic_board.c
@@ -32,7 +32,7 @@
#include <linux/platform_device.h>
#include <linux/irq.h>
-char *bfin_board_name = "UNKNOWN BOARD";
+const char bfin_board_name[] = "UNKNOWN BOARD";
/*
* Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-bf561/boards/tepla.c b/arch/blackfin/mach-bf561/boards/tepla.c
index c442eb23db5..4a17c6da2a5 100644
--- a/arch/blackfin/mach-bf561/boards/tepla.c
+++ b/arch/blackfin/mach-bf561/boards/tepla.c
@@ -16,7 +16,7 @@
#include <linux/platform_device.h>
#include <linux/irq.h>
-char *bfin_board_name = "Tepla-BF561";
+const char bfin_board_name[] = "Tepla-BF561";
/*
* Driver needs to know address, irq and flag pin.
diff --git a/arch/blackfin/mach-common/ints-priority-dc.c b/arch/blackfin/mach-common/ints-priority-dc.c
index 2db3546fc87..c2f05fabedc 100644
--- a/arch/blackfin/mach-common/ints-priority-dc.c
+++ b/arch/blackfin/mach-common/ints-priority-dc.c
@@ -52,7 +52,13 @@
* -
*/
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise). The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
/* The number of spurious interrupts */
atomic_t num_spurious;
diff --git a/arch/blackfin/mach-common/ints-priority-sc.c b/arch/blackfin/mach-common/ints-priority-sc.c
index d3b7672b2b9..2d2b63567b3 100644
--- a/arch/blackfin/mach-common/ints-priority-sc.c
+++ b/arch/blackfin/mach-common/ints-priority-sc.c
@@ -58,7 +58,13 @@
* -
*/
-unsigned long irq_flags = 0;
+/* Initialize this to an actual value to force it into the .data
+ * section so that we know it is properly initialized at entry into
+ * the kernel but before bss is initialized to zero (which is where
+ * it would live otherwise). The 0x1f magic represents the IRQs we
+ * cannot actually mask out in hardware.
+ */
+unsigned long irq_flags = 0x1f;
/* The number of spurious interrupts */
atomic_t num_spurious;
@@ -92,10 +98,15 @@ static void __init search_IAR(void)
for (irqn = 0; irqn < NR_PERI_INTS; irqn++) {
int iar_shift = (irqn & 7) * 4;
- if (ivg ==
+ if (ivg ==
(0xf &
+#ifndef CONFIG_BF52x
bfin_read32((unsigned long *)SIC_IAR0 +
(irqn >> 3)) >> iar_shift)) {
+#else
+ bfin_read32((unsigned long *)SIC_IAR0 +
+ ((irqn%32) >> 3) + ((irqn / 32) * 16)) >> iar_shift)) {
+#endif
ivg_table[irq_pos].irqno = IVG7 + irqn;
ivg_table[irq_pos].isrflag = 1 << (irqn % 32);
ivg7_13[ivg].istop++;
@@ -140,7 +151,7 @@ static void bfin_core_unmask_irq(unsigned int irq)
static void bfin_internal_mask_irq(unsigned int irq)
{
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
~(1 << (irq - (IRQ_CORETMR + 1))));
#else
@@ -155,7 +166,7 @@ static void bfin_internal_mask_irq(unsigned int irq)
static void bfin_internal_unmask_irq(unsigned int irq)
{
-#ifndef CONFIG_BF54x
+#ifdef CONFIG_BF53x
bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
(1 << (irq - (IRQ_CORETMR + 1))));
#else
@@ -750,13 +761,15 @@ int __init init_arch_irq(void)
int irq;
unsigned long ilat = 0;
/* Disable all the peripheral intrs - page 4-29 HW Ref manual */
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
- bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
bfin_write_SIC_IWR0(IWR_ENABLE_ALL);
bfin_write_SIC_IWR1(IWR_ENABLE_ALL);
+#ifdef CONFIG_BF54x
+ bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
bfin_write_SIC_IWR2(IWR_ENABLE_ALL);
+#endif
#else
bfin_write_SIC_IMASK(SIC_UNMASK_ALL);
bfin_write_SIC_IWR(IWR_ENABLE_ALL);
@@ -787,7 +800,7 @@ int __init init_arch_irq(void)
switch (irq) {
#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
-#ifndef CONFIG_BF54x
+#if defined(CONFIG_BF53x)
case IRQ_PROG_INTA:
set_irq_chained_handler(irq,
bfin_demux_gpio_irq);
@@ -798,7 +811,7 @@ int __init init_arch_irq(void)
bfin_demux_gpio_irq);
break;
#endif
-#else
+#elif defined(CONFIG_BF54x)
case IRQ_PINT0:
set_irq_chained_handler(irq,
bfin_demux_gpio_irq);
@@ -815,7 +828,20 @@ int __init init_arch_irq(void)
set_irq_chained_handler(irq,
bfin_demux_gpio_irq);
break;
-#endif /*CONFIG_BF54x */
+#elif defined(CONFIG_BF52x)
+ case IRQ_PORTF_INTA:
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
+ case IRQ_PORTG_INTA:
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
+ case IRQ_PORTH_INTA:
+ set_irq_chained_handler(irq,
+ bfin_demux_gpio_irq);
+ break;
+#endif
#endif
default:
set_irq_handler(irq, handle_simple_irq);
@@ -880,14 +906,15 @@ void do_irq(int vec, struct pt_regs *fp)
} else {
struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)
unsigned long sic_status[3];
SSYNC();
- sic_status[0] = bfin_read_SIC_ISR(0) & bfin_read_SIC_IMASK(0);
- sic_status[1] = bfin_read_SIC_ISR(1) & bfin_read_SIC_IMASK(1);
- sic_status[2] = bfin_read_SIC_ISR(2) & bfin_read_SIC_IMASK(2);
-
+ sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+ sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+#ifdef CONFIG_BF54x
+ sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
for (;; ivg++) {
if (ivg >= ivg_stop) {
atomic_inc(&num_spurious);
diff --git a/arch/blackfin/oprofile/Kconfig b/arch/blackfin/oprofile/Kconfig
deleted file mode 100644
index 0a2fd999c94..00000000000
--- a/arch/blackfin/oprofile/Kconfig
+++ /dev/null
@@ -1,29 +0,0 @@
-menu "Profiling support"
-depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-config HARDWARE_PM
- tristate "Hardware Performance Monitor Profiling"
- depends on PROFILING
- help
- take use of hardware performance monitor to profiling the kernel
- and application.
-
- If unsure, say N.
-
-endmenu
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 6b4d026a00a..21900a9378b 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -196,6 +196,8 @@ source "sound/Kconfig"
source "drivers/usb/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/cris/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/cris/arch-v10/Kconfig b/arch/cris/arch-v10/Kconfig
index c7ea9efd010..f1ce6f64401 100644
--- a/arch/cris/arch-v10/Kconfig
+++ b/arch/cris/arch-v10/Kconfig
@@ -182,7 +182,7 @@ config ETRAX_LED7G
set this to same as CONFIG_ETRAX_LED1G (normally 2).
config ETRAX_LED8Y
- int "Eigth yellow LED bit"
+ int "Eighth yellow LED bit"
depends on ETRAX_CSP0_LEDS
default "2"
help
diff --git a/arch/cris/arch-v10/boot/compressed/misc.c b/arch/cris/arch-v10/boot/compressed/misc.c
index ffb8d21b2f8..e205d2e7e08 100644
--- a/arch/cris/arch-v10/boot/compressed/misc.c
+++ b/arch/cris/arch-v10/boot/compressed/misc.c
@@ -8,7 +8,7 @@
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
* puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
*
*/
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 1de0026bb94..c263b8232db 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -4,7 +4,7 @@
* From Phillips' datasheet:
*
* The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
* low detector are also provided. All address and data are transferred
* serially via two-line bidirectional I2C-bus. Maximum bus speed is
* 400 kbits/s. The built-in word address register is incremented
diff --git a/arch/cris/arch-v10/kernel/debugport.c b/arch/cris/arch-v10/kernel/debugport.c
index 2b536ca6f44..93679a48c79 100644
--- a/arch/cris/arch-v10/kernel/debugport.c
+++ b/arch/cris/arch-v10/kernel/debugport.c
@@ -83,7 +83,7 @@
*
* Revision 1.4 2002/11/19 14:35:24 starvik
* Changes from linux 2.4
- * Changed struct initializer syntax to the currently prefered notation
+ * Changed struct initializer syntax to the currently preferred notation
*
* Revision 1.3 2002/11/06 09:47:03 starvik
* Modified for new interrupt macros
diff --git a/arch/cris/arch-v10/kernel/entry.S b/arch/cris/arch-v10/kernel/entry.S
index ae45d4522e6..c5844cb70f0 100644
--- a/arch/cris/arch-v10/kernel/entry.S
+++ b/arch/cris/arch-v10/kernel/entry.S
@@ -97,7 +97,7 @@
*
* Revision 1.36 2001/11/22 13:36:36 bjornw
* * In ret_from_intr, check regs->dccr for usermode reentrance instead of
- * DCCR explicitely (because the latter might not reflect current reality)
+ * DCCR explicitly (because the latter might not reflect current reality)
* * In mmu_bus_fault, set $r9 _after_ calling the C-code instead of before
* since $r9 is call-clobbered and is potentially needed afterwards
*
diff --git a/arch/cris/arch-v10/kernel/fasttimer.c b/arch/cris/arch-v10/kernel/fasttimer.c
index 8cbdf594b36..d3ea052e5ee 100644
--- a/arch/cris/arch-v10/kernel/fasttimer.c
+++ b/arch/cris/arch-v10/kernel/fasttimer.c
@@ -84,7 +84,7 @@
* with time based on jiffies and *R_TIMER0_DATA, uses a table
* for fast conversion of timer value to microseconds.
* (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
* when we change the time.
* TODO: Add efficient support for continuous timers as well.
*
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index 96094cbf125..845c95f6e87 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -169,7 +169,7 @@ init_IRQ(void)
for (i = 0; i < 256; i++)
etrax_irv->v[i] = weird_irq;
- /* Initialize IRQ handler descriptiors. */
+ /* Initialize IRQ handler descriptors. */
for(i = 2; i < NR_IRQS; i++) {
irq_desc[i].chip = &crisv10_irq_type;
set_int_vector(i, interrupt[i]);
diff --git a/arch/cris/arch-v10/kernel/kgdb.c b/arch/cris/arch-v10/kernel/kgdb.c
index 07628a13c6c..77f4b142372 100644
--- a/arch/cris/arch-v10/kernel/kgdb.c
+++ b/arch/cris/arch-v10/kernel/kgdb.c
@@ -959,7 +959,7 @@ stub_is_stopped(int sigval)
/* Send register contents. We probably only need to send the
* PC, frame pointer and stack pointer here. Other registers will be
- * explicitely asked for. But for now, send all.
+ * explicitly asked for. But for now, send all.
*/
for (regno = R0; regno <= USP; regno++) {
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c
index b6831ceb6a6..1a3760c94f8 100644
--- a/arch/cris/arch-v10/kernel/process.c
+++ b/arch/cris/arch-v10/kernel/process.c
@@ -64,7 +64,7 @@ void hard_reset_now (void)
#if defined(CONFIG_ETRAX_WATCHDOG) && !defined(CONFIG_SVINTO_SIM)
cause_of_death = 0xbedead;
#else
- /* Since we dont plan to keep on reseting the watchdog,
+ /* Since we dont plan to keep on resetting the watchdog,
the key can be arbitrary hence three */
*R_WATCHDOG = IO_FIELD(R_WATCHDOG, key, 3) |
IO_STATE(R_WATCHDOG, enable, start);
diff --git a/arch/cris/arch-v10/kernel/shadows.c b/arch/cris/arch-v10/kernel/shadows.c
index 38fd44dfbc5..326178aef6e 100644
--- a/arch/cris/arch-v10/kernel/shadows.c
+++ b/arch/cris/arch-v10/kernel/shadows.c
@@ -20,7 +20,7 @@ unsigned long r_timer_ctrl_shadow;
* These are only usable if there actually IS a latch connected
* to the corresponding external chip-select pin.
*
- * A common usage is that CSP0 controls LED's and CSP4 video chips.
+ * A common usage is that CSP0 controls LEDs and CSP4 video chips.
*/
unsigned long port_cse1_shadow;
diff --git a/arch/cris/arch-v10/lib/dram_init.S b/arch/cris/arch-v10/lib/dram_init.S
index 9cf83932cd5..6a6bdfd6984 100644
--- a/arch/cris/arch-v10/lib/dram_init.S
+++ b/arch/cris/arch-v10/lib/dram_init.S
@@ -40,7 +40,7 @@
* Copy warning from head.S about r8 and r9
*
* Revision 1.7 2001/04/18 12:05:39 bjornw
- * Fixed comments, and explicitely include config.h to be sure its there
+ * Fixed comments, and explicitly include config.h to be sure its there
*
* Revision 1.6 2001/04/10 06:20:16 starvik
* Delay should be 200us, not 200ns
@@ -66,7 +66,7 @@
*/
/* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
* uses this code.
*/
diff --git a/arch/cris/arch-v10/lib/string.c b/arch/cris/arch-v10/lib/string.c
index 8ffde4901b5..15d6662b03b 100644
--- a/arch/cris/arch-v10/lib/string.c
+++ b/arch/cris/arch-v10/lib/string.c
@@ -41,7 +41,7 @@ void *memcpy(void *pdst,
Make sure the compiler is able to make something useful of this.
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
diff --git a/arch/cris/arch-v10/lib/usercopy.c b/arch/cris/arch-v10/lib/usercopy.c
index 43778d53c25..a12c708afc9 100644
--- a/arch/cris/arch-v10/lib/usercopy.c
+++ b/arch/cris/arch-v10/lib/usercopy.c
@@ -38,7 +38,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pdst;
@@ -200,7 +200,7 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pdst;
@@ -380,7 +380,7 @@ __do_clear_user (void __user *pto, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pto;
diff --git a/arch/cris/arch-v32/boot/compressed/misc.c b/arch/cris/arch-v32/boot/compressed/misc.c
index 11902697196..0169ba1ca9c 100644
--- a/arch/cris/arch-v32/boot/compressed/misc.c
+++ b/arch/cris/arch-v32/boot/compressed/misc.c
@@ -8,7 +8,7 @@
*
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
* puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adoptation for Linux/CRIS Axis Communications AB, 1999
+ * adaptation for Linux/CRIS Axis Communications AB, 1999
*
*/
@@ -151,7 +151,7 @@ serout(const char *s, reg_scope_instances regi_ser)
do {
rs = REG_RD(ser, regi_ser, rs_stat_din);
}
- while (!rs.tr_rdy);/* Wait for tranceiver. */
+ while (!rs.tr_rdy);/* Wait for transceiver. */
REG_WR(ser, regi_ser, rw_dout, dout);
}
@@ -264,7 +264,7 @@ serial_setup(reg_scope_instances regi_ser)
tr_ctrl.stop_bits = 1; /* 2 stop bits. */
/*
- * The baudrate setup is a bit fishy, but in the end the tranceiver is
+ * The baudrate setup is a bit fishy, but in the end the transceiver is
* set to 4800 and the receiver to 115200. The magic value is
* 29.493 MHz.
*/
diff --git a/arch/cris/arch-v32/drivers/axisflashmap.c b/arch/cris/arch-v32/drivers/axisflashmap.c
index 5180d45412f..3ec12ea44e8 100644
--- a/arch/cris/arch-v32/drivers/axisflashmap.c
+++ b/arch/cris/arch-v32/drivers/axisflashmap.c
@@ -205,7 +205,7 @@ static struct mtd_info *probe_cs(struct map_info *map_cs)
/*
* Probe each chip select individually for flash chips. If there are chips on
* both cse0 and cse1, the mtd_info structs will be concatenated to one struct
- * so that MTD partitions can cross chip boundries.
+ * so that MTD partitions can cross chip boundaries.
*
* The only known restriction to how you can mount your chips is that each
* chip select must hold similar flash chips. But you need external hardware
diff --git a/arch/cris/arch-v32/drivers/i2c.c b/arch/cris/arch-v32/drivers/i2c.c
index e12f6cc6f4a..f1edd2e359b 100644
--- a/arch/cris/arch-v32/drivers/i2c.c
+++ b/arch/cris/arch-v32/drivers/i2c.c
@@ -275,7 +275,7 @@ i2c_getack(void)
ack = 0;
i2c_delay(CLOCK_HIGH_TIME/2);
if(!ack){
- if(!i2c_getbit()) /* receiver pulld SDA low */
+ if(!i2c_getbit()) /* receiver pulled SDA low */
ack = 1;
i2c_delay(CLOCK_HIGH_TIME/2);
}
diff --git a/arch/cris/arch-v32/drivers/nandflash.c b/arch/cris/arch-v32/drivers/nandflash.c
index 93ddea4d956..5ce015c6bb0 100644
--- a/arch/cris/arch-v32/drivers/nandflash.c
+++ b/arch/cris/arch-v32/drivers/nandflash.c
@@ -138,7 +138,7 @@ struct mtd_info* __init crisv32_nand_flash_probe (void)
/* Enable the following for a flash based bad block table */
this->options = NAND_USE_FLASH_BBT;
- /* Scan to find existance of the device */
+ /* Scan to find existence of the device */
if (nand_scan (crisv32_mtd, 1)) {
err = -ENXIO;
goto out_ior;
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index da479a14f83..6dbd700d3d6 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -4,7 +4,7 @@
* From Phillips' datasheet:
*
* The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interupt output and voltage
+ * consumption. A programmable clock output, interrupt output and voltage
* low detector are also provided. All address and data are transferred
* serially via two-line bidirectional I2C-bus. Maximum bus speed is
* 400 kbits/s. The built-in word address register is incremented
diff --git a/arch/cris/arch-v32/kernel/fasttimer.c b/arch/cris/arch-v32/kernel/fasttimer.c
index 79e1e4c2ca1..b40551f9f40 100644
--- a/arch/cris/arch-v32/kernel/fasttimer.c
+++ b/arch/cris/arch-v32/kernel/fasttimer.c
@@ -97,7 +97,7 @@
* with time based on jiffies and *R_TIMER0_DATA, uses a table
* for fast conversion of timer value to microseconds.
* (Much faster the standard do_gettimeofday() and we don't really
- * wan't to use the true time - we wan't the "uptime" so timers don't screw up
+ * want to use the true time - we want the "uptime" so timers don't screw up
* when we change the time.
* TODO: Add efficient support for continuous timers as well.
*
diff --git a/arch/cris/arch-v32/kernel/irq.c b/arch/cris/arch-v32/kernel/irq.c
index cc361bf578a..a9acaa27024 100644
--- a/arch/cris/arch-v32/kernel/irq.c
+++ b/arch/cris/arch-v32/kernel/irq.c
@@ -140,7 +140,7 @@ block_irq(int irq, int cpu)
spin_lock_irqsave(&irq_lock, flags);
intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
- /* Remember; 1 let thru, 0 block. */
+ /* Remember; 1 let through, 0 block. */
intr_mask &= ~(1 << (irq - FIRST_IRQ));
REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -156,7 +156,7 @@ unblock_irq(int irq, int cpu)
spin_lock_irqsave(&irq_lock, flags);
intr_mask = REG_RD_INT(intr_vect, irq_regs[cpu], rw_mask);
- /* Remember; 1 let thru, 0 block. */
+ /* Remember; 1 let through, 0 block. */
intr_mask |= (1 << (irq - FIRST_IRQ));
REG_WR_INT(intr_vect, irq_regs[cpu], rw_mask, intr_mask);
@@ -308,7 +308,7 @@ crisv32_do_multiple(struct pt_regs* regs)
*/
irq_enter();
- /* Get which IRQs that happend. */
+ /* Get which IRQs that happened. */
masked = REG_RD_INT(intr_vect, irq_regs[cpu], r_masked_vect);
/* Calculate new IRQ mask with these IRQs disabled. */
@@ -366,7 +366,7 @@ init_IRQ(void)
for (i = 0; i < 256; i++)
etrax_irv->v[i] = weird_irq;
- /* Point all IRQ's to bad handlers. */
+ /* Point all IRQs to bad handlers. */
for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) {
irq_desc[j].chip = &crisv32_irq_type;
set_exception_vector(i, interrupt[j]);
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c
index 6326351af25..b72a15580dc 100644
--- a/arch/cris/arch-v32/kernel/process.c
+++ b/arch/cris/arch-v32/kernel/process.c
@@ -162,7 +162,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/* Put the switch stack right below the pt_regs. */
swstack = ((struct switch_stack *) childregs) - 1;
- /* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
+ /* Parameter to ret_from_sys_call. 0 is don't restart the syscall. */
swstack->r9 = 0;
/*
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c
index 7cd6ac80340..024cc690197 100644
--- a/arch/cris/arch-v32/kernel/signal.c
+++ b/arch/cris/arch-v32/kernel/signal.c
@@ -347,7 +347,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
/* Grab and setup a signal frame.
*
* Basically a lot of state-info is stacked, and arranged for the
- * user-mode program to return to the kernel using either a trampiline
+ * user-mode program to return to the kernel using either a trampoline
* which performs the syscall sigreturn(), or a provided user-mode
* trampoline.
*/
@@ -641,7 +641,7 @@ ugdb_trap_user(struct thread_info *ti, int sig)
user_regs(ti)->spc = 0;
}
/* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
- not withing any configured h/w breakpoint range). Synchronize with
+ not within any configured h/w breakpoint range). Synchronize with
what already exists for kernel debugging. */
if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
/* Break 8: subtract 2 from ERP unless in a delay slot. */
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 697494bc2de..171c96e0a5d 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -142,7 +142,7 @@ smp_boot_one_cpu(int cpuid)
return -1;
}
-/* Secondary CPUs starts uing C here. Here we need to setup CPU
+/* Secondary CPUs starts using C here. Here we need to setup CPU
* specific stuff such as the local timer and the MMU. */
void __init smp_callin(void)
{
diff --git a/arch/cris/arch-v32/kernel/time.c b/arch/cris/arch-v32/kernel/time.c
index be0a01657d4..2f7e8e200f2 100644
--- a/arch/cris/arch-v32/kernel/time.c
+++ b/arch/cris/arch-v32/kernel/time.c
@@ -99,7 +99,7 @@ unsigned long do_slow_gettimeoffset(void)
/* From timer MDS describing the hardware watchdog:
* 4.3.1 Watchdog Operation
* The watchdog timer is an 8-bit timer with a configurable start value.
- * Once started the whatchdog counts downwards with a frequency of 763 Hz
+ * Once started the watchdog counts downwards with a frequency of 763 Hz
* (100/131072 MHz). When the watchdog counts down to 1, it generates an
* NMI (Non Maskable Interrupt), and when it counts down to 0, it resets the
* chip.
diff --git a/arch/cris/arch-v32/kernel/traps.c b/arch/cris/arch-v32/kernel/traps.c
index 2462b1ef1fb..17fd3dbd1c8 100644
--- a/arch/cris/arch-v32/kernel/traps.c
+++ b/arch/cris/arch-v32/kernel/traps.c
@@ -105,7 +105,7 @@ bad_value:
/*
* This gets called from entry.S when the watchdog has bitten. Show something
- * similiar to an Oops dump, and if the kernel if configured to be a nice doggy;
+ * similar to an Oops dump, and if the kernel is configured to be a nice doggy;
* halt instead of reboot.
*/
void
diff --git a/arch/cris/arch-v32/lib/dram_init.S b/arch/cris/arch-v32/lib/dram_init.S
index 158b3dbb4d9..218fbe259ee 100644
--- a/arch/cris/arch-v32/lib/dram_init.S
+++ b/arch/cris/arch-v32/lib/dram_init.S
@@ -12,7 +12,7 @@
*/
/* Just to be certain the config file is included, we include it here
- * explicitely instead of depending on it being included in the file that
+ * explicitly instead of depending on it being included in the file that
* uses this code.
*/
diff --git a/arch/cris/arch-v32/lib/string.c b/arch/cris/arch-v32/lib/string.c
index 98e282ac824..6740b2cebae 100644
--- a/arch/cris/arch-v32/lib/string.c
+++ b/arch/cris/arch-v32/lib/string.c
@@ -41,7 +41,7 @@ void *memcpy(void *pdst,
Make sure the compiler is able to make something useful of this.
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register void *return_dst __asm__ ("r10") = pdst;
diff --git a/arch/cris/arch-v32/lib/usercopy.c b/arch/cris/arch-v32/lib/usercopy.c
index f0b08460c1b..04d0cf35a27 100644
--- a/arch/cris/arch-v32/lib/usercopy.c
+++ b/arch/cris/arch-v32/lib/usercopy.c
@@ -34,7 +34,7 @@ __copy_user (void __user *pdst, const void *psrc, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pdst;
@@ -168,7 +168,7 @@ __copy_user_zeroing (void __user *pdst, const void *psrc, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pdst;
@@ -332,7 +332,7 @@ __do_clear_user (void __user *pto, unsigned long pn)
As it is now: r10 -> r13; r11 -> r11 (nop); r12 -> r12 (nop).
FIXME: Comment for old gcc version. Check.
- If gcc was allright, it really would need no temporaries, and no
+ If gcc was alright, it really would need no temporaries, and no
stack space to save stuff on. */
register char *dst __asm__ ("r13") = pto;
diff --git a/arch/cris/arch-v32/mm/tlb.c b/arch/cris/arch-v32/mm/tlb.c
index c2d12e9c40d..a076ef6e938 100644
--- a/arch/cris/arch-v32/mm/tlb.c
+++ b/arch/cris/arch-v32/mm/tlb.c
@@ -30,8 +30,8 @@ do { \
* The TLB can host up to 256 different mm contexts at the same time. The running
* context is found in the PID register. Each TLB entry contains a page_id that
* has to match the PID register to give a hit. page_id_map keeps track of which
- * mm's is assigned to which page_id's, making sure it's known when to
- * invalidate TLB entries.
+ * mm is assigned to which page_id, making sure it's known when to invalidate TLB
+ * entries.
*
* The last page_id is never running, it is used as an invalid page_id so that
* it's possible to make TLB entries that will nerver match.
@@ -188,7 +188,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
spin_unlock(&mmu_context_lock);
/*
- * Remember the pgd for the fault handlers. Keep a seperate copy of it
+ * Remember the pgd for the fault handlers. Keep a separate copy of it
* because current and active_mm might be invalid at points where
* there's still a need to derefer the pgd.
*/
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
index 903ea62c6e2..5c27ff86121 100644
--- a/arch/cris/kernel/irq.c
+++ b/arch/cris/kernel/irq.c
@@ -7,7 +7,7 @@
* Authors: Bjorn Wesen (bjornw@axis.com)
*
* This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
+ * asking for different IRQs should be done through these routines
* instead of just grabbing them. Thus setups with different IRQ numbers
* shouldn't result in any weird surprises, and installing new handlers
* should be easier.
@@ -15,7 +15,7 @@
*/
/*
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * IRQs are in fact implemented a bit like signal handlers for the kernel.
* Naturally it's not a 1:1 relation, but there are similarities.
*/
@@ -83,9 +83,9 @@ skip:
/* called by the assembler IRQ entry functions defined in irq.h
- * to dispatch the interrupts to registred handlers
+ * to dispatch the interrupts to registered handlers
* interrupts are disabled upon entry - depending on if the
- * interrupt was registred with IRQF_DISABLED or not, interrupts
+ * interrupt was registered with IRQF_DISABLED or not, interrupts
* are re-enabled or not.
*/
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 8aab8143069..3034f3ff950 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -13,7 +13,7 @@
* Fixed warning.
*
* Revision 1.18 2005/01/12 08:10:14 starvik
- * Readded the change of frametype when handling kernel page fault fixup
+ * Re-added the change of frametype when handling kernel page fault fixup
* for v10. This is necessary to avoid that the CPU remakes the faulting
* access.
*
@@ -49,7 +49,7 @@
*
* Revision 1.8 2003/07/04 13:02:48 tobiasa
* Moved code snippet from arch/cris/mm/fault.c that searches for fixup code
- * to seperate function in arch-specific files.
+ * to separate function in arch-specific files.
*
* Revision 1.7 2003/01/22 06:48:38 starvik
* Fixed warnings issued by GCC 3.2.1
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c
index b7842ff213a..0c833d17622 100644
--- a/arch/cris/mm/init.c
+++ b/arch/cris/mm/init.c
@@ -8,7 +8,7 @@
*
* $Log: init.c,v $
* Revision 1.11 2004/05/28 09:28:56 starvik
- * Calculation of loops_per_usec moved because initalization order has changed
+ * Calculation of loops_per_usec moved because initialization order has changed
* in Linux 2.6.
*
* Revision 1.10 2004/05/14 07:58:05 starvik
diff --git a/arch/cris/mm/tlb.c b/arch/cris/mm/tlb.c
index c4a98e2e529..b7f8de57677 100644
--- a/arch/cris/mm/tlb.c
+++ b/arch/cris/mm/tlb.c
@@ -16,7 +16,7 @@
/* The TLB can host up to 64 different mm contexts at the same time.
* The running context is R_MMU_CONTEXT, and each TLB entry contains a
* page_id that has to match to give a hit. In page_id_map, we keep track
- * of which mm's we have assigned which page_id's, so that we know when
+ * of which mm we have assigned to which page_id, so that we know when
* to invalidate TLB entries.
*
* The last page_id is never running - it is used as an invalid page_id
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 74eef7111f2..43153e767bb 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -375,6 +375,8 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/frv/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index ad753c1e9b8..9e38f99bbab 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -17,10 +17,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index e0983f6926e..3c2752ca977 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -17,10 +17,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index c157eeff871..7754c7338e4 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -17,10 +17,10 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <asm/irc-regs.h>
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index c7e59dcadee..73abae767fd 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -24,12 +24,12 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/module.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
#include <asm/delay.h>
@@ -134,7 +134,7 @@ static struct irq_chip frv_cpu_pic = {
};
/*
- * handles all normal device IRQ's
+ * handles all normal device IRQs
* - registers are referred to by the __frame variable (GR28)
* - IRQ distribution is complicated in this arch because of the many PICs, the
* way they work and the way they cascade
diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c
index 8e182ced1a0..7ee3a147b47 100644
--- a/arch/frv/kernel/semaphore.c
+++ b/arch/frv/kernel/semaphore.c
@@ -139,7 +139,7 @@ void __up(struct semaphore *sem)
waiter = list_entry(sem->wait_list.next, struct sem_waiter, list);
/* We must be careful not to touch 'waiter' after we set ->task = NULL.
- * It is an allocated on the waiter's stack and may become invalid at
+ * It is allocated on the waiter's stack and may become invalid at
* any time after that point (due to a wakeup from another source).
*/
list_del_init(&waiter->list);
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index e83e0bccfab..925fb0199a0 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -66,7 +66,7 @@ static irqreturn_t timer_interrupt(int irq, void *dummy)
/*
* Here we are in the timer irq handler. We just have irqs locally
* disabled but we don't know if the timer_bh is running on the other
- * CPU. We need to avoid to SMP race with it. NOTE: we don' t need
+ * CPU. We need to avoid to SMP race with it. NOTE: we don't need
* the irq version of write_lock because as just said we have irq
* locally disabled. -arca
*/
@@ -126,7 +126,7 @@ void time_init(void)
/* FIX by dqg : Set to zero for platforms that don't have tod */
/* without this time is undefined and can overflow time_t, causing */
- /* very stange errors */
+ /* very strange errors */
year = 1980;
mon = day = 1;
hour = min = sec = 0;
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index e35f74e6e50..e2e9f57abe2 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -223,6 +223,8 @@ endmenu
source "fs/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/h8300/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug
index 996d97e953b..ee671c3f2c7 100644
--- a/arch/h8300/Kconfig.debug
+++ b/arch/h8300/Kconfig.debug
@@ -42,16 +42,16 @@ config SH_STANDARD_BIOS
Require eCos/RedBoot
config DEFAULT_CMDLINE
- bool "Use buildin commandline"
+ bool "Use builtin commandline"
default n
help
- buildin kernel commandline enabled.
+ builtin kernel commandline enabled.
config KERNEL_COMMAND
string "Buildin commmand string"
depends on DEFAULT_CMDLINE
help
- buildin kernel commandline strings.
+ builtin kernel commandline strings.
config BLKDEV_RESERVE
bool "BLKDEV Reserved Memory"
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c
index 43d21e93f41..8dec4dd57b4 100644
--- a/arch/h8300/kernel/irq.c
+++ b/arch/h8300/kernel/irq.c
@@ -68,7 +68,7 @@ static void h8300_shutdown_irq(unsigned int irq)
}
/*
- * h8300 interrupt controler implementation
+ * h8300 interrupt controller implementation
*/
struct irq_chip h8300irq_chip = {
.name = "H8300-INTC",
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index 330638220a2..e37c835e67c 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -53,7 +53,7 @@ void time_init(void)
/* FIX by dqg : Set to zero for platforms that don't have tod */
/* without this time is undefined and can overflow time_t, causing */
- /* very stange errors */
+ /* very strange errors */
year = 1980;
mon = day = 1;
hour = min = sec = 0;
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index f97183011c2..f8f7d7ea97f 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -5,7 +5,7 @@
* Cloned from Linux/m68k.
*
* No original Copyright holder listed,
- * Probabily original (C) Roman Zippel (assigned DJD, 1999)
+ * Probable original (C) Roman Zippel (assigned DJD, 1999)
*
* Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com>
*
diff --git a/arch/h8300/platform/h8s/ints.c b/arch/h8300/platform/h8s/ints.c
index a71d6e2a391..551fd5f30d8 100644
--- a/arch/h8300/platform/h8s/ints.c
+++ b/arch/h8300/platform/h8s/ints.c
@@ -179,7 +179,7 @@ int request_irq(unsigned int irq,
if (use_kmalloc)
irq_handle = kmalloc(sizeof(irq_handler_t), GFP_ATOMIC);
else {
- /* use bootmem allocater */
+ /* use bootmem allocator */
irq_handle = (irq_handler_t *)alloc_bootmem(sizeof(irq_handler_t));
irq_handle = (irq_handler_t *)((unsigned long)irq_handle | 0x80000000);
}
diff --git a/arch/h8300/platform/h8s/ints_h8s.c b/arch/h8300/platform/h8s/ints_h8s.c
index 93395d2a8a0..faa8a459d95 100644
--- a/arch/h8300/platform/h8s/ints_h8s.c
+++ b/arch/h8300/platform/h8s/ints_h8s.c
@@ -63,7 +63,7 @@ static const struct irq_pins irq_assign_table1[16]={
{H8300_GPIO_P2,H8300_GPIO_B6},{H8300_GPIO_P2,H8300_GPIO_B7},
};
-/* IRQ to GPIO pinno transrate */
+/* IRQ to GPIO pin translation */
#define IRQ_GPIO_MAP(irqbit,irq,port,bit) \
do { \
if (*(volatile unsigned short *)ITSR & irqbit) { \
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index b84d5050e92..f6e44fc5283 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -392,7 +392,7 @@ config X86_MCE_NONFATAL
will look at the machine check registers to see if anything happened.
Non-fatal problems automatically get corrected (but still logged).
Disable this if you don't want to see these messages.
- Seeing the messages this option prints out may be indicative of dying hardware,
+ Seeing the messages this option prints out may be indicative of dying
or out-of-spec (ie, overclocked) hardware.
This option only does something on certain CPUs.
(AMD Athlon/Duron and Intel Pentium 4)
@@ -631,7 +631,7 @@ config NUMA
default n if X86_PC
default y if (X86_NUMAQ || X86_SUMMIT)
help
- NUMA support for i386. This is currently high experimental
+ NUMA support for i386. This is currently highly experimental
and should be only used for kernel development. It might also
cause boot failures.
@@ -1080,7 +1080,9 @@ config APM_REAL_MODE_POWER_OFF
endif # APM
-source "arch/x86/kernel/cpu/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_32"
+
+source "drivers/cpuidle/Kconfig"
endmenu
@@ -1256,31 +1258,6 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-menuconfig INSTRUMENTATION
- bool "Instrumentation Support"
- default y
- ---help---
- Say Y here to get to see options related to performance measurement,
- debugging, and testing. This option alone does not add any kernel code.
-
- If you say N, all options in this submenu will be skipped and disabled.
-
-if INSTRUMENTATION
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes"
- depends on KALLSYMS && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
-endif # INSTRUMENTATION
-
source "arch/i386/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index f036d2dee3d..b88e47ca303 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -102,7 +102,7 @@ core-$(CONFIG_XEN) += arch/x86/xen/
# default subarch .h files
mflags-y += -Iinclude/asm-x86/mach-default
-head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task_32.o
+head-y := arch/x86/kernel/head_32.o arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
@@ -131,9 +131,9 @@ all: bzImage
zImage zlilo zdisk: KBUILD_IMAGE := arch/x86/boot/zImage
zImage bzImage: vmlinux
- $(Q)mkdir -p $(objtree)/arch/i386/boot
- $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
$(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
+ $(Q)mkdir -p $(objtree)/arch/i386/boot
+ $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/i386/boot/bzImage
compressed: zImage
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index c60532d93c5..bef47725d4a 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -452,9 +452,9 @@ config IA64_PALINFO
config IA64_MC_ERR_INJECT
tristate "MC error injection support"
help
- Selets whether support for MC error injection. By enabling the
- support, kernel provide sysfs interface for user application to
- call MC error injection PAL procedure to inject various errors.
+ Adds support for MC error injection. If enabled, the kernel
+ will provide a sysfs interface for user applications to
+ call MC error injection PAL procedures to inject various errors.
This is a useful tool for MCA testing.
If you're unsure, do not select this option.
@@ -491,7 +491,7 @@ config KEXEC
but it is independent of the system firmware. And like a reboot
you can start any kernel with it, not just Linux.
- The name comes from the similiarity to the exec system call.
+ The name comes from the similarity to the exec system call.
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
@@ -592,20 +592,7 @@ config IRQ_PER_CPU
source "arch/ia64/hp/sim/Kconfig"
-menu "Instrumentation Support"
-
-source "arch/ia64/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes"
- depends on KALLSYMS && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
source "arch/ia64/Kconfig.debug"
diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig
index 449d3e75bfc..75fd90dc76a 100644
--- a/arch/ia64/configs/sn2_defconfig
+++ b/arch/ia64/configs/sn2_defconfig
@@ -26,6 +26,7 @@ CONFIG_TASK_IO_ACCOUNTING=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=20
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 3c95f4184b9..bc859a311ea 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -246,7 +246,7 @@ static int reserve_sba_gart = 1;
static SBA_INLINE void sba_mark_invalid(struct ioc *, dma_addr_t, size_t);
static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
-#define sba_sg_address(sg) (page_address((sg)->page) + (sg)->offset)
+#define sba_sg_address(sg) sg_virt((sg))
#ifdef FULL_VALID_PDIR
static u64 prefetch_spill_page;
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index a3a558a0675..6ef9b521993 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -131,7 +131,7 @@ simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
stat.fd = desc[sc->device->id];
scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
- req.addr = __pa(page_address(sl->page) + sl->offset);
+ req.addr = __pa(sg_virt(sl));
req.len = sl->length;
if (DBG)
printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
@@ -212,7 +212,7 @@ static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
if (!len)
break;
thislen = min(len, slp->length);
- memcpy(page_address(slp->page) + slp->offset, buf, thislen);
+ memcpy(sg_virt(slp), buf, thislen);
len -= thislen;
}
}
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index a3405b3c1ee..d025a22eb22 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -773,7 +773,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if (flags & MAP_SHARED)
printk(KERN_INFO
"%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n",
- current->comm, current->pid, start);
+ current->comm, task_pid_nr(current), start);
ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags,
off);
if (IS_ERR((void *) ret))
@@ -786,7 +786,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if (flags & MAP_SHARED)
printk(KERN_INFO
"%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n",
- current->comm, current->pid, end);
+ current->comm, task_pid_nr(current), end);
ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags,
(off + len) - offset_in_page(end));
if (IS_ERR((void *) ret))
@@ -816,7 +816,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro
if ((flags & MAP_SHARED) && !is_congruent)
printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap "
- "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off);
+ "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off);
DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend,
is_congruent ? "congruent" : "not congruent", poff);
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 73ca86d0381..3f7ea13358e 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -967,7 +967,7 @@ find_memmap_space (void)
* to use. We can allocate partial granules only if the unavailable
* parts exist, and are WB.
*/
-void
+unsigned long
efi_memmap_init(unsigned long *s, unsigned long *e)
{
struct kern_memdesc *k, *prev = NULL;
@@ -1084,11 +1084,14 @@ efi_memmap_init(unsigned long *s, unsigned long *e)
/* reserve the memory we are using for kern_memmap */
*s = (u64)kern_memmap;
*e = (u64)++k;
+
+ return total_mem;
}
void
efi_initialize_iomem_resources(struct resource *code_resource,
- struct resource *data_resource)
+ struct resource *data_resource,
+ struct resource *bss_resource)
{
struct resource *res;
void *efi_map_start, *efi_map_end, *p;
@@ -1169,6 +1172,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
*/
insert_resource(res, code_resource);
insert_resource(res, data_resource);
+ insert_resource(res, bss_resource);
#ifdef CONFIG_KEXEC
insert_resource(res, &efi_memmap_res);
insert_resource(res, &boot_param_res);
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index f55fa07849c..59169bf7145 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -158,14 +158,14 @@
*/
#define PROTECT_CTX(c, f) \
do { \
- DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \
+ DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \
spin_lock_irqsave(&(c)->ctx_lock, f); \
- DPRINT(("spinlocked ctx %p by [%d]\n", c, current->pid)); \
+ DPRINT(("spinlocked ctx %p by [%d]\n", c, task_pid_nr(current))); \
} while(0)
#define UNPROTECT_CTX(c, f) \
do { \
- DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \
+ DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \
spin_unlock_irqrestore(&(c)->ctx_lock, f); \
} while(0)
@@ -227,12 +227,12 @@
#ifdef PFM_DEBUGGING
#define DPRINT(a) \
do { \
- if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+ if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
} while (0)
#define DPRINT_ovfl(a) \
do { \
- if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
+ if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \
} while (0)
#endif
@@ -913,7 +913,7 @@ pfm_mask_monitoring(struct task_struct *task)
unsigned long mask, val, ovfl_mask;
int i;
- DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid));
+ DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task)));
ovfl_mask = pmu_conf->ovfl_val;
/*
@@ -992,12 +992,12 @@ pfm_restore_monitoring(struct task_struct *task)
ovfl_mask = pmu_conf->ovfl_val;
if (task != current) {
- printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
+ printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current));
return;
}
if (ctx->ctx_state != PFM_CTX_MASKED) {
printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
- task->pid, current->pid, ctx->ctx_state);
+ task_pid_nr(task), task_pid_nr(current), ctx->ctx_state);
return;
}
psr = pfm_get_psr();
@@ -1051,7 +1051,8 @@ pfm_restore_monitoring(struct task_struct *task)
if ((mask & 0x1) == 0UL) continue;
ctx->th_pmcs[i] = ctx->ctx_pmcs[i];
ia64_set_pmc(i, ctx->th_pmcs[i]);
- DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i]));
+ DPRINT(("[%d] pmc[%d]=0x%lx\n",
+ task_pid_nr(task), i, ctx->th_pmcs[i]));
}
ia64_srlz_d();
@@ -1370,7 +1371,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
error_conflict:
DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
- pfm_sessions.pfs_sys_session[cpu]->pid,
+ task_pid_nr(pfm_sessions.pfs_sys_session[cpu]),
cpu));
abort:
UNLOCK_PFS(flags);
@@ -1442,7 +1443,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
/* sanity checks */
if (task->mm == NULL || size == 0UL || vaddr == NULL) {
- printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm);
+ printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm);
return -EINVAL;
}
@@ -1459,7 +1460,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz
up_write(&task->mm->mmap_sem);
if (r !=0) {
- printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size);
+ printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size);
}
DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
@@ -1501,7 +1502,7 @@ pfm_free_smpl_buffer(pfm_context_t *ctx)
return 0;
invalid_free:
- printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current));
return -EINVAL;
}
#endif
@@ -1547,13 +1548,13 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
return -EINVAL;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current));
return -EINVAL;
}
@@ -1607,7 +1608,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
PROTECT_CTX(ctx, flags);
}
- DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret));
+ DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret));
set_current_state(TASK_RUNNING);
remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
@@ -1616,7 +1617,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
ret = -EINVAL;
msg = pfm_get_next_msg(ctx);
if (msg == NULL) {
- printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid);
+ printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current));
goto abort_locked;
}
@@ -1647,13 +1648,13 @@ pfm_poll(struct file *filp, poll_table * wait)
unsigned int mask = 0;
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current));
return 0;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current));
return 0;
}
@@ -1692,7 +1693,7 @@ pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on)
ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
- current->pid,
+ task_pid_nr(current),
fd,
on,
ctx->ctx_async_queue, ret));
@@ -1707,13 +1708,13 @@ pfm_fasync(int fd, struct file *filp, int on)
int ret;
if (PFM_IS_FILE(filp) == 0) {
- printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current));
return -EBADF;
}
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
}
/*
@@ -1759,7 +1760,7 @@ pfm_syswide_force_stop(void *info)
if (owner != ctx->ctx_task) {
printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
smp_processor_id(),
- owner->pid, ctx->ctx_task->pid);
+ task_pid_nr(owner), task_pid_nr(ctx->ctx_task));
return;
}
if (GET_PMU_CTX() != ctx) {
@@ -1769,7 +1770,7 @@ pfm_syswide_force_stop(void *info)
return;
}
- DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), ctx->ctx_task->pid));
+ DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task)));
/*
* the context is already protected in pfm_close(), we simply
* need to mask interrupts to avoid a PMU interrupt race on
@@ -1821,7 +1822,7 @@ pfm_flush(struct file *filp, fl_owner_t id)
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
}
@@ -1969,7 +1970,7 @@ pfm_close(struct inode *inode, struct file *filp)
ctx = (pfm_context_t *)filp->private_data;
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid);
+ printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current));
return -EBADF;
}
@@ -2066,7 +2067,7 @@ pfm_close(struct inode *inode, struct file *filp)
*/
ctx->ctx_state = PFM_CTX_ZOMBIE;
- DPRINT(("zombie ctx for [%d]\n", task->pid));
+ DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task)));
/*
* cannot free the context on the spot. deferred until
* the task notices the ZOMBIE state
@@ -2472,7 +2473,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
/* invoke and lock buffer format, if found */
fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id);
if (fmt == NULL) {
- DPRINT(("[%d] cannot find buffer format\n", task->pid));
+ DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task)));
return -EINVAL;
}
@@ -2483,7 +2484,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t
ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
- DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret));
+ DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret));
if (ret) goto error;
@@ -2605,23 +2606,23 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
* no kernel task or task not owner by caller
*/
if (task->mm == NULL) {
- DPRINT(("task [%d] has not memory context (kernel thread)\n", task->pid));
+ DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task)));
return -EPERM;
}
if (pfm_bad_permissions(task)) {
- DPRINT(("no permission to attach to [%d]\n", task->pid));
+ DPRINT(("no permission to attach to [%d]\n", task_pid_nr(task)));
return -EPERM;
}
/*
* cannot block in self-monitoring mode
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
- DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid));
+ DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task)));
return -EINVAL;
}
if (task->exit_state == EXIT_ZOMBIE) {
- DPRINT(("cannot attach to zombie task [%d]\n", task->pid));
+ DPRINT(("cannot attach to zombie task [%d]\n", task_pid_nr(task)));
return -EBUSY;
}
@@ -2631,7 +2632,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
if (task == current) return 0;
if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
- DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task->pid, task->state));
+ DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state));
return -EBUSY;
}
/*
@@ -3512,7 +3513,7 @@ pfm_use_debug_registers(struct task_struct *task)
if (pmu_conf->use_rr_dbregs == 0) return 0;
- DPRINT(("called for [%d]\n", task->pid));
+ DPRINT(("called for [%d]\n", task_pid_nr(task)));
/*
* do it only once
@@ -3543,7 +3544,7 @@ pfm_use_debug_registers(struct task_struct *task)
DPRINT(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n",
pfm_sessions.pfs_ptrace_use_dbregs,
pfm_sessions.pfs_sys_use_dbregs,
- task->pid, ret));
+ task_pid_nr(task), ret));
UNLOCK_PFS(flags);
@@ -3568,7 +3569,7 @@ pfm_release_debug_registers(struct task_struct *task)
LOCK_PFS(flags);
if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
- printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
+ printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task));
ret = -1;
} else {
pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -3620,7 +3621,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* sanity check */
if (unlikely(task == NULL)) {
- printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid);
+ printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current));
return -EINVAL;
}
@@ -3629,7 +3630,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
fmt = ctx->ctx_buf_fmt;
DPRINT(("restarting self %d ovfl=0x%lx\n",
- task->pid,
+ task_pid_nr(task),
ctx->ctx_ovfl_regs[0]));
if (CTX_HAS_SMPL(ctx)) {
@@ -3653,11 +3654,11 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
if (rst_ctrl.bits.mask_monitoring == 0) {
- DPRINT(("resuming monitoring for [%d]\n", task->pid));
+ DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task)));
if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task);
} else {
- DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+ DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task)));
// cannot use pfm_stop_monitoring(task, regs);
}
@@ -3714,10 +3715,10 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* "self-monitoring".
*/
if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) {
- DPRINT(("unblocking [%d] \n", task->pid));
+ DPRINT(("unblocking [%d] \n", task_pid_nr(task)));
complete(&ctx->ctx_restart_done);
} else {
- DPRINT(("[%d] armed exit trap\n", task->pid));
+ DPRINT(("[%d] armed exit trap\n", task_pid_nr(task)));
ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
@@ -3805,7 +3806,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
* don't bother if we are loaded and task is being debugged
*/
if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
- DPRINT(("debug registers already in use for [%d]\n", task->pid));
+ DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task)));
return -EBUSY;
}
@@ -3846,7 +3847,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_
* is shared by all processes running on it
*/
if (first_time && can_access_pmu) {
- DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid));
+ DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task)));
for (i=0; i < pmu_conf->num_ibrs; i++) {
ia64_set_ibr(i, 0UL);
ia64_dv_serialize_instruction();
@@ -4035,7 +4036,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
return -EBUSY;
}
DPRINT(("task [%d] ctx_state=%d is_system=%d\n",
- PFM_CTX_TASK(ctx)->pid,
+ task_pid_nr(PFM_CTX_TASK(ctx)),
state,
is_system));
/*
@@ -4093,7 +4094,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
* monitoring disabled in kernel at next reschedule
*/
ctx->ctx_saved_psr_up = 0;
- DPRINT(("task=[%d]\n", task->pid));
+ DPRINT(("task=[%d]\n", task_pid_nr(task)));
}
return 0;
}
@@ -4298,11 +4299,12 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
if (is_system) {
if (pfm_sessions.pfs_ptrace_use_dbregs) {
- DPRINT(("cannot load [%d] dbregs in use\n", task->pid));
+ DPRINT(("cannot load [%d] dbregs in use\n",
+ task_pid_nr(task)));
ret = -EBUSY;
} else {
pfm_sessions.pfs_sys_use_dbregs++;
- DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task->pid, pfm_sessions.pfs_sys_use_dbregs));
+ DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs));
set_dbregs = 1;
}
}
@@ -4394,7 +4396,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
/* allow user level control */
ia64_psr(regs)->sp = 0;
- DPRINT(("clearing psr.sp for [%d]\n", task->pid));
+ DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task)));
SET_LAST_CPU(ctx, smp_processor_id());
INC_ACTIVATION();
@@ -4429,7 +4431,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
*/
SET_PMU_OWNER(task, ctx);
- DPRINT(("context loaded on PMU for [%d]\n", task->pid));
+ DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task)));
} else {
/*
* when not current, task MUST be stopped, so this is safe
@@ -4493,7 +4495,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
int prev_state, is_system;
int ret;
- DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+ DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1));
prev_state = ctx->ctx_state;
is_system = ctx->ctx_fl_system;
@@ -4568,7 +4570,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
*/
ia64_psr(regs)->sp = 1;
- DPRINT(("setting psr.sp for [%d]\n", task->pid));
+ DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task)));
}
/*
* save PMDs to context
@@ -4608,7 +4610,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg
ctx->ctx_fl_can_restart = 0;
ctx->ctx_fl_going_zombie = 0;
- DPRINT(("disconnected [%d] from context\n", task->pid));
+ DPRINT(("disconnected [%d] from context\n", task_pid_nr(task)));
return 0;
}
@@ -4631,7 +4633,7 @@ pfm_exit_thread(struct task_struct *task)
PROTECT_CTX(ctx, flags);
- DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid));
+ DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task)));
state = ctx->ctx_state;
switch(state) {
@@ -4640,13 +4642,13 @@ pfm_exit_thread(struct task_struct *task)
* only comes to this function if pfm_context is not NULL, i.e., cannot
* be in unloaded state
*/
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task));
break;
case PFM_CTX_LOADED:
case PFM_CTX_MASKED:
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
}
DPRINT(("ctx unloaded for current state was %d\n", state));
@@ -4655,12 +4657,12 @@ pfm_exit_thread(struct task_struct *task)
case PFM_CTX_ZOMBIE:
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret);
}
free_ok = 1;
break;
default:
- printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task->pid, state);
+ printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state);
break;
}
UNPROTECT_CTX(ctx, flags);
@@ -4744,7 +4746,7 @@ recheck:
DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
ctx->ctx_fd,
state,
- task->pid,
+ task_pid_nr(task),
task->state, PFM_CMD_STOPPED(cmd)));
/*
@@ -4791,7 +4793,7 @@ recheck:
*/
if (PFM_CMD_STOPPED(cmd)) {
if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) {
- DPRINT(("[%d] task not in stopped state\n", task->pid));
+ DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task)));
return -EBUSY;
}
/*
@@ -4884,7 +4886,7 @@ restart_args:
* limit abuse to min page size
*/
if (unlikely(sz > PFM_MAX_ARGSIZE)) {
- printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz);
+ printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz);
return -E2BIG;
}
@@ -5031,11 +5033,11 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
{
int ret;
- DPRINT(("entering for [%d]\n", current->pid));
+ DPRINT(("entering for [%d]\n", task_pid_nr(current)));
ret = pfm_context_unload(ctx, NULL, 0, regs);
if (ret) {
- printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", current->pid, ret);
+ printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret);
}
/*
@@ -5072,7 +5074,7 @@ pfm_handle_work(void)
ctx = PFM_GET_CTX(current);
if (ctx == NULL) {
- printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
+ printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current));
return;
}
@@ -5269,7 +5271,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s "
"used_pmds=0x%lx\n",
pmc0,
- task ? task->pid: -1,
+ task ? task_pid_nr(task): -1,
(regs ? regs->cr_iip : 0),
CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
ctx->ctx_used_pmds[0]));
@@ -5458,7 +5460,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
}
DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n",
- GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1,
+ GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1,
PFM_GET_WORK_PENDING(task),
ctx->ctx_fl_trap_reason,
ovfl_pmds,
@@ -5483,7 +5485,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
sanity_check:
printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
smp_processor_id(),
- task ? task->pid : -1,
+ task ? task_pid_nr(task) : -1,
pmc0);
return;
@@ -5516,7 +5518,7 @@ stop_monitoring:
*
* Overall pretty hairy stuff....
*/
- DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1));
+ DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1));
pfm_clear_psr_up();
ia64_psr(regs)->up = 0;
ia64_psr(regs)->sp = 1;
@@ -5577,13 +5579,13 @@ pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
report_spurious1:
printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n",
- this_cpu, task->pid);
+ this_cpu, task_pid_nr(task));
pfm_unfreeze_pmu();
return -1;
report_spurious2:
printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n",
this_cpu,
- task->pid);
+ task_pid_nr(task));
pfm_unfreeze_pmu();
return -1;
}
@@ -5870,7 +5872,8 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
ia64_psr(regs)->sp = 1;
if (GET_PMU_OWNER() == task) {
- DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid));
+ DPRINT(("cleared ownership for [%d]\n",
+ task_pid_nr(ctx->ctx_task)));
SET_PMU_OWNER(NULL, NULL);
}
@@ -5882,7 +5885,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
task->thread.pfm_context = NULL;
task->thread.flags &= ~IA64_THREAD_PM_VALID;
- DPRINT(("force cleanup for [%d]\n", task->pid));
+ DPRINT(("force cleanup for [%d]\n", task_pid_nr(task)));
}
@@ -6426,7 +6429,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
if (PMD_IS_COUNTING(i)) {
DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
- task->pid,
+ task_pid_nr(task),
i,
ctx->ctx_pmds[i].val,
val & ovfl_val));
@@ -6448,11 +6451,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
*/
if (pmc0 & (1UL << i)) {
val += 1 + ovfl_val;
- DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i));
+ DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i));
}
}
- DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val));
+ DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val));
if (is_self) ctx->th_pmds[i] = pmd_val;
@@ -6793,14 +6796,14 @@ dump_pmu_state(const char *from)
printk("CPU%d from %s() current [%d] iip=0x%lx %s\n",
this_cpu,
from,
- current->pid,
+ task_pid_nr(current),
regs->cr_iip,
current->comm);
task = GET_PMU_OWNER();
ctx = GET_PMU_CTX();
- printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task->pid : -1, ctx);
+ printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx);
psr = pfm_get_psr();
@@ -6848,7 +6851,7 @@ pfm_inherit(struct task_struct *task, struct pt_regs *regs)
{
struct thread_struct *thread;
- DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task->pid));
+ DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task)));
thread = &task->thread;
diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
index ff80eab83b3..a7af1cb419f 100644
--- a/arch/ia64/kernel/perfmon_default_smpl.c
+++ b/arch/ia64/kernel/perfmon_default_smpl.c
@@ -44,11 +44,11 @@ default_validate(struct task_struct *task, unsigned int flags, int cpu, void *da
int ret = 0;
if (data == NULL) {
- DPRINT(("[%d] no argument passed\n", task->pid));
+ DPRINT(("[%d] no argument passed\n", task_pid_nr(task)));
return -EINVAL;
}
- DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu));
+ DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu));
/*
* must hold at least the buffer header + one minimally sized entry
@@ -88,7 +88,7 @@ default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, v
hdr->hdr_count = 0UL;
DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n",
- task->pid,
+ task_pid_nr(task),
buf,
hdr->hdr_buf_size,
sizeof(*hdr),
@@ -245,7 +245,7 @@ default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, stru
static int
default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
{
- DPRINT(("[%d] exit(%p)\n", task->pid, buf));
+ DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf));
return 0;
}
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index c613fc0e91c..2418289ee5c 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -105,7 +105,8 @@ show_regs (struct pt_regs *regs)
unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
print_modules();
- printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
+ printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current),
+ smp_processor_id(), current->comm);
printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
print_symbol("ip is at %s\n", ip);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index c5cfcfa4c87..ae6c3c02e11 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -90,7 +90,12 @@ static struct resource code_resource = {
.name = "Kernel code",
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};
-extern char _text[], _end[], _etext[];
+
+static struct resource bss_resource = {
+ .name = "Kernel bss",
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+extern char _text[], _end[], _etext[], _edata[], _bss[];
unsigned long ia64_max_cacheline_size;
@@ -200,14 +205,59 @@ static int __init register_memory(void)
code_resource.start = ia64_tpa(_text);
code_resource.end = ia64_tpa(_etext) - 1;
data_resource.start = ia64_tpa(_etext);
- data_resource.end = ia64_tpa(_end) - 1;
- efi_initialize_iomem_resources(&code_resource, &data_resource);
+ data_resource.end = ia64_tpa(_edata) - 1;
+ bss_resource.start = ia64_tpa(_bss);
+ bss_resource.end = ia64_tpa(_end) - 1;
+ efi_initialize_iomem_resources(&code_resource, &data_resource,
+ &bss_resource);
return 0;
}
__initcall(register_memory);
+
+#ifdef CONFIG_KEXEC
+static void __init setup_crashkernel(unsigned long total, int *n)
+{
+ unsigned long long base = 0, size = 0;
+ int ret;
+
+ ret = parse_crashkernel(boot_command_line, total,
+ &size, &base);
+ if (ret == 0 && size > 0) {
+ if (!base) {
+ sort_regions(rsvd_region, *n);
+ base = kdump_find_rsvd_region(size,
+ rsvd_region, *n);
+ }
+ if (base != ~0UL) {
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(size >> 20),
+ (unsigned long)(base >> 20),
+ (unsigned long)(total >> 20));
+ rsvd_region[*n].start =
+ (unsigned long)__va(base);
+ rsvd_region[*n].end =
+ (unsigned long)__va(base + size);
+ (*n)++;
+ crashk_res.start = base;
+ crashk_res.end = base + size - 1;
+ }
+ }
+ efi_memmap_res.start = ia64_boot_param->efi_memmap;
+ efi_memmap_res.end = efi_memmap_res.start +
+ ia64_boot_param->efi_memmap_size;
+ boot_param_res.start = __pa(ia64_boot_param);
+ boot_param_res.end = boot_param_res.start +
+ sizeof(*ia64_boot_param);
+}
+#else
+static inline void __init setup_crashkernel(unsigned long total, int *n)
+{}
+#endif
+
/**
* reserve_memory - setup reserved memory areas
*
@@ -219,6 +269,7 @@ void __init
reserve_memory (void)
{
int n = 0;
+ unsigned long total_memory;
/*
* none of the entries in this table overlap
@@ -254,50 +305,11 @@ reserve_memory (void)
n++;
#endif
- efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
+ total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end);
n++;
-#ifdef CONFIG_KEXEC
- /* crashkernel=size@offset specifies the size to reserve for a crash
- * kernel. If offset is 0, then it is determined automatically.
- * By reserving this memory we guarantee that linux never set's it
- * up as a DMA target.Useful for holding code to do something
- * appropriate after a kernel panic.
- */
- {
- char *from = strstr(boot_command_line, "crashkernel=");
- unsigned long base, size;
- if (from) {
- size = memparse(from + 12, &from);
- if (*from == '@')
- base = memparse(from+1, &from);
- else
- base = 0;
- if (size) {
- if (!base) {
- sort_regions(rsvd_region, n);
- base = kdump_find_rsvd_region(size,
- rsvd_region, n);
- }
- if (base != ~0UL) {
- rsvd_region[n].start =
- (unsigned long)__va(base);
- rsvd_region[n].end =
- (unsigned long)__va(base + size);
- n++;
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- }
- }
- efi_memmap_res.start = ia64_boot_param->efi_memmap;
- efi_memmap_res.end = efi_memmap_res.start +
- ia64_boot_param->efi_memmap_size;
- boot_param_res.start = __pa(ia64_boot_param);
- boot_param_res.end = boot_param_res.start +
- sizeof(*ia64_boot_param);
- }
-#endif
+ setup_crashkernel(total_memory, &n);
+
/* end of memory marker */
rsvd_region[n].start = ~0UL;
rsvd_region[n].end = ~0UL;
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index aeec8184e86..cdb64cc4d9c 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -227,7 +227,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
+ si.si_pid = task_pid_vnr(current);
si.si_uid = current->uid;
si.si_addr = sc;
force_sig_info(SIGSEGV, &si, current);
@@ -332,7 +332,7 @@ force_sigsegv_info (int sig, void __user *addr)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
+ si.si_pid = task_pid_vnr(current);
si.si_uid = current->uid;
si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current);
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
index 3aeaf15e468..78d65cb947d 100644
--- a/arch/ia64/kernel/traps.c
+++ b/arch/ia64/kernel/traps.c
@@ -61,7 +61,7 @@ die (const char *str, struct pt_regs *regs, long err)
if (++die.lock_owner_depth < 3) {
printk("%s[%d]: %s %ld [%d]\n",
- current->comm, current->pid, str, err, ++die_counter);
+ current->comm, task_pid_nr(current), str, err, ++die_counter);
(void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV);
show_regs(regs);
} else
@@ -315,7 +315,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr)
last.time = current_jiffies + 5 * HZ;
printk(KERN_WARNING
"%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
- current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
+ current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr);
}
}
}
@@ -453,7 +453,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa,
if (code == 8) {
# ifdef CONFIG_IA64_PRINT_HAZARDS
printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
regs.cr_iip + ia64_psr(&regs)->ri, regs.pr);
# endif
return;
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index fe6aa5a9f8f..2173de9fe91 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1340,7 +1340,8 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
size_t len;
len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, "
- "ip=0x%016lx\n\r", current->comm, current->pid,
+ "ip=0x%016lx\n\r", current->comm,
+ task_pid_nr(current),
ifa, regs->cr_iip + ipsr->ri);
/*
* Don't call tty_write_message() if we're in the kernel; we might
@@ -1363,7 +1364,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
"administrator\n"
"echo 0 > /proc/sys/kernel/ignore-"
"unaligned-usertrap to re-enable\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
}
}
} else {
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 32f26253c4e..7571076a16a 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -274,7 +274,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index 3e10152abbf..c6c19bf11be 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -127,8 +127,8 @@ ia64_init_addr_space (void)
vma->vm_mm = current->mm;
vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
vma->vm_end = vma->vm_start + PAGE_SIZE;
- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
down_write(&current->mm->mmap_sem);
if (insert_vm_struct(current->mm, vma)) {
up_write(&current->mm->mmap_sem);
diff --git a/arch/ia64/oprofile/Kconfig b/arch/ia64/oprofile/Kconfig
deleted file mode 100644
index 97271ab484d..00000000000
--- a/arch/ia64/oprofile/Kconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- Due to firmware bugs, you may need to use the "nohalt" boot
- option if you're using OProfile with the hardware performance
- counters.
-
- If unsure, say N.
-
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index ecd8a52b9b9..511db2fd7bf 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -16,7 +16,7 @@
#include <asm/sn/pcidev.h>
#include <asm/sn/sn_sal.h>
-#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
#define SG_ENT_PHYS_ADDRESS(SG) virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
/**
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index bd5fe76401f..ab9a264cb19 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -426,7 +426,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/m32r/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/m32r/Kconfig.debug"
diff --git a/arch/m32r/kernel/irq.c b/arch/m32r/kernel/irq.c
index f8d8650383e..d0c5b0b7da2 100644
--- a/arch/m32r/kernel/irq.c
+++ b/arch/m32r/kernel/irq.c
@@ -71,7 +71,7 @@ skip:
}
/*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
index 916faf6070a..a753d79c4e8 100644
--- a/arch/m32r/kernel/signal.c
+++ b/arch/m32r/kernel/signal.c
@@ -358,7 +358,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- /* Reenable any watchpoints before delivering the
+ /* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
* inside the kernel.
diff --git a/arch/m32r/kernel/smp.c b/arch/m32r/kernel/smp.c
index 360129174b2..c837bc13b01 100644
--- a/arch/m32r/kernel/smp.c
+++ b/arch/m32r/kernel/smp.c
@@ -202,7 +202,7 @@ void smp_flush_cache_all_interrupt(void)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* TLB flush request Routins */
+/* TLB flush request Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -378,7 +378,7 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
* Name: flush_tlb_others
*
* Description: This routine requests other CPU to execute flush TLB.
- * 1.Setup parmeters.
+ * 1.Setup parameters.
* 2.Send 'INVALIDATE_TLB_IPI' to other CPU.
* Request other CPU to execute 'smp_invalidate_interrupt()'.
* 3.Wait for other CPUs operation finished.
@@ -502,7 +502,7 @@ void smp_invalidate_interrupt(void)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Stop CPU request Routins */
+/* Stop CPU request Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -566,7 +566,7 @@ static void stop_this_cpu(void *dummy)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Call function Routins */
+/* Call function Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -690,7 +690,7 @@ void smp_call_function_interrupt(void)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Timer Routins */
+/* Timer Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -802,7 +802,7 @@ void smp_local_timer_interrupt(void)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Send IPI Routins */
+/* Send IPI Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -814,7 +814,7 @@ void smp_local_timer_interrupt(void)
*
* Arguments: ipi_num - Number of IPI
* try - 0 : Send IPI certainly.
- * !0 : The following IPI is not sended when Target CPU
+ * !0 : The following IPI is not sent when Target CPU
* has not received the before IPI.
*
* Returns: void (cannot fail)
@@ -844,7 +844,7 @@ void send_IPI_allbutself(int ipi_num, int try)
* Arguments: cpu_mask - Bitmap of target CPUs logical ID
* ipi_num - Number of IPI
* try - 0 : Send IPI certainly.
- * !0 : The following IPI is not sended when Target CPU
+ * !0 : The following IPI is not sent when Target CPU
* has not received the before IPI.
*
* Returns: void (cannot fail)
@@ -885,7 +885,7 @@ static void send_IPI_mask(cpumask_t cpumask, int ipi_num, int try)
* Arguments: cpu_mask - Bitmap of target CPUs physical ID
* ipi_num - Number of IPI
* try - 0 : Send IPI certainly.
- * !0 : The following IPI is not sended when Target CPU
+ * !0 : The following IPI is not sent when Target CPU
* has not received the before IPI.
*
* Returns: IPICRi regster value.
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index 9dae410014d..0e383da158e 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -133,7 +133,7 @@ static void map_cpu_to_physid(int, int);
static void unmap_cpu_to_physid(int, int);
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up APs Routins : BSP */
+/* Boot up APs Routines : BSP */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
void __devinit smp_prepare_boot_cpu(void)
{
@@ -404,7 +404,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Activate a secondary processor Routins */
+/* Activate a secondary processor Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
/*==========================================================================*
@@ -509,7 +509,7 @@ static void __init smp_online(void)
}
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
-/* Boot up CPUs common Routins */
+/* Boot up CPUs common Routines */
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
static void __init show_mp_info(int nr_cpu)
{
diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c
index 0fc2efec18f..6d7a80fdad4 100644
--- a/arch/m32r/kernel/sys_m32r.c
+++ b/arch/m32r/kernel/sys_m32r.c
@@ -214,7 +214,7 @@ asmlinkage int sys_uname(struct old_utsname __user * name)
asmlinkage int sys_cacheflush(void *addr, int bytes, int cache)
{
- /* This should flush more selectivly ... */
+ /* This should flush more selectively ... */
_flush_cache_all();
return 0;
}
diff --git a/arch/m32r/kernel/traps.c b/arch/m32r/kernel/traps.c
index 97e0b1c0830..89ba4a0b5d5 100644
--- a/arch/m32r/kernel/traps.c
+++ b/arch/m32r/kernel/traps.c
@@ -196,7 +196,7 @@ static void show_registers(struct pt_regs *regs)
printk("SPI: %08lx\n", sp);
}
printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)",
- current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current);
+ current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current);
/*
* When in-kernel, we also print out the stack and code at the
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 70a766aad3e..4a71df4c1b3 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -271,7 +271,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(tsk)) {
+ if (is_global_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/m32r/oprofile/Kconfig b/arch/m32r/oprofile/Kconfig
deleted file mode 100644
index 19d37730b66..00000000000
--- a/arch/m32r/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 20a9c08e59c..01dee84f840 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -683,6 +683,8 @@ endmenu
source "fs/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/m68k/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/m68k/amiga/pcmcia.c b/arch/m68k/amiga/pcmcia.c
index fc57c6e72ac..186662ca1a8 100644
--- a/arch/m68k/amiga/pcmcia.c
+++ b/arch/m68k/amiga/pcmcia.c
@@ -33,7 +33,7 @@ void pcmcia_reset(void)
/* copy a tuple, including tuple header. return nb bytes copied */
-/* be carefull as this may trigger a GAYLE_IRQ_WR interrupt ! */
+/* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */
int pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len)
{
diff --git a/arch/m68k/ifpsp060/CHANGES b/arch/m68k/ifpsp060/CHANGES
index c1e712dfc2e..ba96596910f 100644
--- a/arch/m68k/ifpsp060/CHANGES
+++ b/arch/m68k/ifpsp060/CHANGES
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/MISC b/arch/m68k/ifpsp060/MISC
index b7e644b94ae..1a63913daa1 100644
--- a/arch/m68k/ifpsp060/MISC
+++ b/arch/m68k/ifpsp060/MISC
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/README b/arch/m68k/ifpsp060/README
index e3bced429bd..f6f8f5c5941 100644
--- a/arch/m68k/ifpsp060/README
+++ b/arch/m68k/ifpsp060/README
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/TEST.DOC b/arch/m68k/ifpsp060/TEST.DOC
index 5e5900cb2dc..1ba3aef1500 100644
--- a/arch/m68k/ifpsp060/TEST.DOC
+++ b/arch/m68k/ifpsp060/TEST.DOC
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fplsp.doc b/arch/m68k/ifpsp060/fplsp.doc
index fb637c43676..89730a934c5 100644
--- a/arch/m68k/ifpsp060/fplsp.doc
+++ b/arch/m68k/ifpsp060/fplsp.doc
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fpsp.doc b/arch/m68k/ifpsp060/fpsp.doc
index 408315209e6..23d513f72ed 100644
--- a/arch/m68k/ifpsp060/fpsp.doc
+++ b/arch/m68k/ifpsp060/fpsp.doc
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/fskeleton.S b/arch/m68k/ifpsp060/fskeleton.S
index a45a4ff9d2a..0a1ae4f4413 100644
--- a/arch/m68k/ifpsp060/fskeleton.S
+++ b/arch/m68k/ifpsp060/fskeleton.S
@@ -4,7 +4,7 @@
|M68060 Software Package
|Production Release P1.00 -- October 10, 1994
|
-|M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
|
|THE SOFTWARE is provided on an "AS IS" basis and without warranty.
|To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/ilsp.doc b/arch/m68k/ifpsp060/ilsp.doc
index f6fae6d900a..4e6292f095a 100644
--- a/arch/m68k/ifpsp060/ilsp.doc
+++ b/arch/m68k/ifpsp060/ilsp.doc
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/iskeleton.S b/arch/m68k/ifpsp060/iskeleton.S
index b2dbdf5ee30..91a9c65fee8 100644
--- a/arch/m68k/ifpsp060/iskeleton.S
+++ b/arch/m68k/ifpsp060/iskeleton.S
@@ -4,7 +4,7 @@
|M68060 Software Package
|Production Release P1.00 -- October 10, 1994
|
-|M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
|
|THE SOFTWARE is provided on an "AS IS" basis and without warranty.
|To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/isp.doc b/arch/m68k/ifpsp060/isp.doc
index 5a90fded3f0..9dadd727fc5 100644
--- a/arch/m68k/ifpsp060/isp.doc
+++ b/arch/m68k/ifpsp060/isp.doc
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/os.S b/arch/m68k/ifpsp060/os.S
index aa4df87a6c4..7a0d6e42806 100644
--- a/arch/m68k/ifpsp060/os.S
+++ b/arch/m68k/ifpsp060/os.S
@@ -4,7 +4,7 @@
|M68060 Software Package
|Production Release P1.00 -- October 10, 1994
|
-|M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+|M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
|
|THE SOFTWARE is provided on an "AS IS" basis and without warranty.
|To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/fplsp.S b/arch/m68k/ifpsp060/src/fplsp.S
index fdb79b927ef..3b7ea2dc9f1 100644
--- a/arch/m68k/ifpsp060/src/fplsp.S
+++ b/arch/m68k/ifpsp060/src/fplsp.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/fpsp.S b/arch/m68k/ifpsp060/src/fpsp.S
index 3b597a9bbf4..6c1a9a21788 100644
--- a/arch/m68k/ifpsp060/src/fpsp.S
+++ b/arch/m68k/ifpsp060/src/fpsp.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/ftest.S b/arch/m68k/ifpsp060/src/ftest.S
index 2edcbae0fd5..1f947915d81 100644
--- a/arch/m68k/ifpsp060/src/ftest.S
+++ b/arch/m68k/ifpsp060/src/ftest.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/ilsp.S b/arch/m68k/ifpsp060/src/ilsp.S
index afa7422cddb..970abaf3303 100644
--- a/arch/m68k/ifpsp060/src/ilsp.S
+++ b/arch/m68k/ifpsp060/src/ilsp.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/isp.S b/arch/m68k/ifpsp060/src/isp.S
index b269091d9df..6dccda766e2 100644
--- a/arch/m68k/ifpsp060/src/isp.S
+++ b/arch/m68k/ifpsp060/src/isp.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/itest.S b/arch/m68k/ifpsp060/src/itest.S
index ba4a30cbcbe..beca47e7d51 100644
--- a/arch/m68k/ifpsp060/src/itest.S
+++ b/arch/m68k/ifpsp060/src/itest.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/ifpsp060/src/pfpsp.S b/arch/m68k/ifpsp060/src/pfpsp.S
index 0c997c436be..51b9f7d879d 100644
--- a/arch/m68k/ifpsp060/src/pfpsp.S
+++ b/arch/m68k/ifpsp060/src/pfpsp.S
@@ -4,7 +4,7 @@ M68000 Hi-Performance Microprocessor Division
M68060 Software Package
Production Release P1.00 -- October 10, 1994
-M68060 Software Package Copyright 1993, 1994 Motorola Inc. All rights reserved.
+M68060 Software Package Copyright © 1993, 1994 Motorola Inc. All rights reserved.
THE SOFTWARE is provided on an "AS IS" basis and without warranty.
To the maximum extent permitted by applicable law,
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 9d4e4b5b6bd..ef490e1ce60 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -121,7 +121,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
int i;
for (i = 0; i < nents; sg++, i++) {
- sg->dma_address = page_to_phys(sg->page) + sg->offset;
+ sg->dma_address = sg_phys(sg);
dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
}
return nents;
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index 4e2752a0e89..97f556fa493 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -900,7 +900,7 @@ void show_registers(struct pt_regs *regs)
regs->d4, regs->d5, regs->a0, regs->a1);
printk("Process %s (pid: %d, task=%p)\n",
- current->comm, current->pid, current);
+ current->comm, task_pid_nr(current), current);
addr = (unsigned long)&fp->un;
printk("Frame format=%X ", regs->format);
switch (regs->format) {
@@ -1038,7 +1038,7 @@ void bad_super_trap (struct frame *fp)
fp->un.fmtb.daddr, space_names[ssw & DFC],
fp->ptregs.pc);
}
- printk ("Current process id is %d\n", current->pid);
+ printk ("Current process id is %d\n", task_pid_nr(current));
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 8547dbc5e8d..01b468b9392 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -284,7 +284,7 @@ static struct mac_model mac_data_table[] = {
},
/*
- * Weirdified MacII hardware - all subtley different. Gee thanks
+ * Weirdified MacII hardware - all subtly different. Gee thanks
* Apple. All these boxes seem to have VIA2 in a different place to
* the MacII (+1A000 rather than +4000)
* CSA: see http://developer.apple.com/technotes/hw/hw_09.html
@@ -707,7 +707,7 @@ static struct mac_model mac_data_table[] = {
* All of these probably have onboard SONIC in the Dock which
* means we'll have to probe for it eventually.
*
- * Are these reallly MAC_VIA_IIci? The developer notes for the
+ * Are these really MAC_VIA_IIci? The developer notes for the
* Duos show pretty much the same custom parts as in most of
* the other PowerBooks which would imply MAC_VIA_QUADRA.
*/
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 0cea21f5819..5b2799eb96a 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -100,7 +100,7 @@
* finished; this function moves the message state to MSG_COMPLETE and signals
* the IOP. This two-step process is provided to allow the handler to defer
* message processing to a bottom-half handler if the processing will take
- * a signifigant amount of time (handlers are called at interrupt time so they
+ * a significant amount of time (handlers are called at interrupt time so they
* should execute quickly.)
*/
@@ -120,7 +120,7 @@
/*#define DEBUG_IOP*/
-/* Set to nonezero if the IOPs are present. Set by iop_init() */
+/* Set to non-zero if the IOPs are present. Set by iop_init() */
int iop_scc_present,iop_ism_present;
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index d7be16917ef..50603d3dce8 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -8,7 +8,7 @@
*
* 990502 (jmt) - Major rewrite for new interrupt architecture as well as some
* recent insights into OSS operational details.
- * 990610 (jmt) - Now taking fulll advantage of the OSS. Interrupts are mapped
+ * 990610 (jmt) - Now taking full advantage of the OSS. Interrupts are mapped
* to mostly match the A/UX interrupt scheme supported on the
* VIA side. Also added support for enabling the ISM irq again
* since we now have a functional IOP manager.
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index d5cac72eb3d..8df270e950f 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -1,7 +1,7 @@
/*
* 6522 Versatile Interface Adapter (VIA)
*
- * There are two of these on the Mac II. Some IRQ's are vectored
+ * There are two of these on the Mac II. Some IRQs are vectored
* via them as are assorted bits and bobs - eg RTC, ADB.
*
* CSA: Motorola seems to have removed documentation on the 6522 from
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index 87b4f015856..b1033ae0d6f 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -65,7 +65,7 @@ fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
fp_copy_ext(&src2, dest);
/*
- * The taylor row arround a for sqrt(x) is:
+ * The taylor row around a for sqrt(x) is:
* sqrt(x) = sqrt(a) + 1/(2*sqrt(a))*(x-a) + R
* With a=1 this gives:
* sqrt(x) = 1 + 1/2*(x-1)
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index eaa61868115..f493f03231d 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -180,7 +180,7 @@ good_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/m68k/q40/q40ints.c b/arch/m68k/q40/q40ints.c
index ad3ed1fb887..46161cef08b 100644
--- a/arch/m68k/q40/q40ints.c
+++ b/arch/m68k/q40/q40ints.c
@@ -184,7 +184,7 @@ static struct IRQ_TABLE eirqs[] = {
};
/* complain only this many times about spurious ints : */
-static int ccleirq=60; /* ISA dev IRQ's*/
+static int ccleirq=60; /* ISA dev IRQs*/
/*static int cclirq=60;*/ /* internal */
/* FIXME: add shared ints,mask,unmask,probing.... */
@@ -234,7 +234,7 @@ static void q40_irq_handler(unsigned int irq, struct pt_regs *fp)
* There is a little mess wrt which IRQ really caused this irq request. The
* main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
* are read - which is long after the request came in. In theory IRQs should
- * not just go away but they occassionally do
+ * not just go away but they occasionally do
*/
if (irq > 4 && irq <= 15 && mext_disabled) {
/*aliased_irq++;*/
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 7a0e3a22068..fb0f6a20cc3 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -239,7 +239,7 @@ void clear_context(unsigned long context)
/* gets an empty context. if full, kills the next context listed to
die first */
/* This context invalidation scheme is, well, totally arbitrary, I'm
- sure it could be much more intellegent... but it gets the job done
+ sure it could be much more intelligent... but it gets the job done
for now without much overhead in making it's decision. */
/* todo: come up with optimized scheme for flushing contexts */
unsigned long get_free_context(struct mm_struct *mm)
diff --git a/arch/m68k/tools/amiga/dmesg.c b/arch/m68k/tools/amiga/dmesg.c
index e892748e738..7340f5b6cf6 100644
--- a/arch/m68k/tools/amiga/dmesg.c
+++ b/arch/m68k/tools/amiga/dmesg.c
@@ -3,7 +3,7 @@
* in Chip RAM with the kernel command
* line option `debug=mem'.
*
- * Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
+ * © Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
*
*
* Usage:
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 185906b54cb..f52c627bdad 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -696,6 +696,8 @@ source "drivers/Kconfig"
source "fs/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/m68knommu/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/m68knommu/platform/5307/pit.c b/arch/m68knommu/platform/5307/pit.c
index e53c446d10e..f18352fa35a 100644
--- a/arch/m68knommu/platform/5307/pit.c
+++ b/arch/m68knommu/platform/5307/pit.c
@@ -83,7 +83,7 @@ unsigned long coldfire_pit_offset(void)
/*
* If we are still in the first half of the upcount and a
- * timer interupt is pending, then add on a ticks worth of time.
+ * timer interrupt is pending, then add on a ticks worth of time.
*/
offset = ((pmr - pcntr) * (1000000 / HZ)) / pmr;
if ((offset < (1000000 / HZ / 2)) && (*ipr & MCFPIT_IMR_IBIT))
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index cb027580cd1..61262c5f9c6 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -66,6 +66,7 @@ config BCM47XX
config MIPS_COBALT
bool "Cobalt Server"
select CEVT_R4K
+ select CEVT_GT641XX
select DMA_NONCOHERENT
select HW_HAS_PCI
select I8253
@@ -729,6 +730,9 @@ config ARCH_MAY_HAVE_PC_FDC
config BOOT_RAW
bool
+config CEVT_GT641XX
+ bool
+
config CEVT_R4K
bool
@@ -1812,7 +1816,7 @@ config KEXEC
but it is independent of the system firmware. And like a reboot
you can start any kernel with it, not just Linux.
- The name comes from the similiarity to the exec system call.
+ The name comes from the similarity to the exec system call.
It is an ongoing process to be certain the hardware in a machine
is properly shutdown, so do not be surprised if this code does not
@@ -2005,7 +2009,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/mips/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/mips/Kconfig.debug"
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug
index 3efe117721a..fd7124c1b75 100644
--- a/arch/mips/Kconfig.debug
+++ b/arch/mips/Kconfig.debug
@@ -6,18 +6,6 @@ config TRACE_IRQFLAGS_SUPPORT
source "lib/Kconfig.debug"
-config CROSSCOMPILE
- bool "Are you using a crosscompiler"
- help
- Say Y here if you are compiling the kernel on a different
- architecture than the one it is intended to run on. This is just a
- convenience option which will select the appropriate value for
- the CROSS_COMPILE make variable which otherwise has to be passed on
- the command line from mips-linux-, mipsel-linux-, mips64-linux- and
- mips64el-linux- as appropriate for a particular kernel configuration.
- You will have to pass the value for CROSS_COMPILE manually if the
- name prefix for your tools is different.
-
config CMDLINE
string "Default kernel command string"
default ""
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 14164c2b879..23c17755eca 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -18,15 +18,15 @@ cflags-y :=
# Select the object file format to substitute into the linker script.
#
ifdef CONFIG_CPU_LITTLE_ENDIAN
-32bit-tool-prefix = mipsel-linux-
-64bit-tool-prefix = mips64el-linux-
+32bit-tool-archpref = mipsel
+64bit-tool-archpref = mips64el
32bit-bfd = elf32-tradlittlemips
64bit-bfd = elf64-tradlittlemips
32bit-emul = elf32ltsmip
64bit-emul = elf64ltsmip
else
-32bit-tool-prefix = mips-linux-
-64bit-tool-prefix = mips64-linux-
+32bit-tool-archpref = mips
+64bit-tool-archpref = mips64
32bit-bfd = elf32-tradbigmips
64bit-bfd = elf64-tradbigmips
32bit-emul = elf32btsmip
@@ -34,16 +34,18 @@ else
endif
ifdef CONFIG_32BIT
-tool-prefix = $(32bit-tool-prefix)
+tool-archpref = $(32bit-tool-archpref)
UTS_MACHINE := mips
endif
ifdef CONFIG_64BIT
-tool-prefix = $(64bit-tool-prefix)
+tool-archpref = $(64bit-tool-archpref)
UTS_MACHINE := mips64
endif
-ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE := $(tool-prefix)
+ifneq ($(SUBARCH),$(ARCH))
+ ifeq ($(CROSS_COMPILE),)
+ CROSS_COMPILE := $(call cc-cross-prefix, $(tool-archpref)-linux- $(tool-archpref)-gnu-linux- $(tool-archpref)-unknown-gnu-linux-)
+ endif
endif
ifdef CONFIG_32BIT
diff --git a/arch/mips/au1000/pb1200/irqmap.c b/arch/mips/au1000/pb1200/irqmap.c
index 5f48b060379..bdf00e2a35e 100644
--- a/arch/mips/au1000/pb1200/irqmap.c
+++ b/arch/mips/au1000/pb1200/irqmap.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/delay.h>
+#include <linux/bitops.h>
-#include <asm/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
diff --git a/arch/mips/basler/excite/excite_irq.c b/arch/mips/basler/excite/excite_irq.c
index 1ecab635042..4903e067916 100644
--- a/arch/mips/basler/excite/excite_irq.c
+++ b/arch/mips/basler/excite/excite_irq.c
@@ -29,7 +29,7 @@
#include <linux/timex.h>
#include <linux/slab.h>
#include <linux/random.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 0ab4676c8bd..0c6f47b3fd9 100644
--- a/arch/mips/bcm47xx/time.c
+++ b/arch/mips/bcm47xx/time.c
@@ -46,10 +46,3 @@ void __init plat_time_init(void)
/* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
mips_hpt_frequency = hz;
}
-
-void __init
-plat_timer_setup(struct irqaction *irq)
-{
- /* Enable the timer interrupt */
- setup_irq(7, irq);
-}
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 6b83f4ddc8f..d73833b7c78 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -2,7 +2,7 @@
# Makefile for the Cobalt micro systems family specific parts of the kernel
#
-obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o
+obj-y := buttons.o irq.o led.o reset.o rtc.o serial.o setup.o time.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_EARLY_PRINTK) += console.o
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c
index d11bb1bc7b6..dd23beb8604 100644
--- a/arch/mips/cobalt/setup.c
+++ b/arch/mips/cobalt/setup.c
@@ -9,19 +9,17 @@
* Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv)
*
*/
-#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
#include <linux/pm.h>
#include <asm/bootinfo.h>
-#include <asm/time.h>
-#include <asm/i8253.h>
-#include <asm/io.h>
#include <asm/reboot.h>
#include <asm/gt64120.h>
#include <cobalt.h>
-#include <irq.h>
extern void cobalt_machine_restart(char *command);
extern void cobalt_machine_halt(void);
@@ -41,17 +39,6 @@ const char *get_system_type(void)
return "MIPS Cobalt";
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- /* Load timer value for HZ (TCLK is 50MHz) */
- GT_WRITE(GT_TC0_OFS, 50*1000*1000 / HZ);
-
- /* Enable timer0 */
- GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
-
- setup_irq(GT641XX_TIMER0_IRQ, irq);
-}
-
/*
* Cobalt doesn't have PS/2 keyboard/mouse interfaces,
* keyboard conntroller is never used.
@@ -84,11 +71,6 @@ static struct resource cobalt_reserved_resources[] = {
},
};
-void __init plat_time_init(void)
-{
- setup_pit_timer();
-}
-
void __init plat_mem_setup(void)
{
int i;
diff --git a/arch/mips/cobalt/time.c b/arch/mips/cobalt/time.c
new file mode 100644
index 00000000000..fa819fccd5d
--- /dev/null
+++ b/arch/mips/cobalt/time.c
@@ -0,0 +1,35 @@
+/*
+ * Cobalt time initialization.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/init.h>
+
+#include <asm/gt64120.h>
+#include <asm/i8253.h>
+#include <asm/time.h>
+
+#define GT641XX_BASE_CLOCK 50000000 /* 50MHz */
+
+void __init plat_time_init(void)
+{
+ setup_pit_timer();
+
+ gt641xx_set_base_clock(GT641XX_BASE_CLOCK);
+
+ mips_timer_state = gt641xx_timer0_state;
+}
diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig
index 49bcc58929b..892d4c38fd0 100644
--- a/arch/mips/configs/ip27_defconfig
+++ b/arch/mips/configs/ip27_defconfig
@@ -175,6 +175,7 @@ CONFIG_POSIX_MQUEUE=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig
index 86dcb746435..61b72f5a953 100644
--- a/arch/mips/configs/mipssim_defconfig
+++ b/arch/mips/configs/mipssim_defconfig
@@ -1,71 +1,68 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.20
-# Tue Feb 20 21:47:35 2007
+# Linux kernel version: 2.6.23
+# Thu Oct 18 22:45:52 2007
#
CONFIG_MIPS=y
#
# Machine selection
#
-CONFIG_ZONE_DMA=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_PB1200 is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_DB1200 is not set
-# CONFIG_MIPS_MIRAGE is not set
+# CONFIG_MACH_ALCHEMY is not set
# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
# CONFIG_MIPS_ATLAS is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SEAD is not set
-# CONFIG_WR_PPMC is not set
CONFIG_MIPS_SIM=y
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_MIPS_XXS1500 is not set
+# CONFIG_MARKEINS is not set
+# CONFIG_MACH_VR41XX is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
-# CONFIG_MACH_VR41XX is not set
+# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_QEMU is not set
-# CONFIG_MARKEINS is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP32 is not set
-# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_PTSWARM is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SNI_RM is not set
# CONFIG_TOSHIBA_JMR3927 is not set
# CONFIG_TOSHIBA_RBTX4927 is not set
# CONFIG_TOSHIBA_RBTX4938 is not set
+# CONFIG_WR_PPMC is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_BOOT_RAW=y
+CONFIG_CEVT_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_DMA_NEED_PCI_MAP_STATE=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
# CONFIG_CPU_BIG_ENDIAN is not set
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
@@ -76,6 +73,11 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_CPU_LOONGSON2 is not set
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
@@ -115,8 +117,8 @@ CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_SYS_SUPPORTS_MULTITHREADING=y
# CONFIG_MIPS_VPE_LOADER is not set
-# CONFIG_64BIT_PHYS_ADDR is not set
CONFIG_CPU_HAS_LLSC=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
@@ -130,50 +132,52 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_RESOURCES_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=1
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
# CONFIG_HZ_48 is not set
-# CONFIG_HZ_100 is not set
+CONFIG_HZ_100=y
# CONFIG_HZ_128 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_256 is not set
-CONFIG_HZ_1000=y
+# CONFIG_HZ_1000 is not set
# CONFIG_HZ_1024 is not set
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_HZ=1000
+CONFIG_HZ=100
CONFIG_PREEMPT_NONE=y
# CONFIG_PREEMPT_VOLUNTARY is not set
# CONFIG_PREEMPT is not set
# CONFIG_KEXEC is not set
+# CONFIG_SECCOMP is not set
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
+# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
@@ -187,31 +191,29 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_KMOD=y
-
-#
-# Block layer
-#
CONFIG_BLOCK=y
# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -229,18 +231,11 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_MMU=y
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
# CONFIG_PCCARD is not set
#
-# PCI Hotplug Support
-#
-
-#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
@@ -250,9 +245,8 @@ CONFIG_TRAD_SIGNALS=y
#
# Power management options
#
-CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
-# CONFIG_PM_DEBUG is not set
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
#
# Networking
@@ -262,75 +256,50 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-CONFIG_XFRM_MIGRATE=y
-CONFIG_NET_KEY=y
-CONFIG_NET_KEY_MIGRATE=y
+# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
CONFIG_IP_FIB_HASH=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set
-CONFIG_IP_ROUTE_VERBOSE=y
+# CONFIG_IP_MULTIPLE_TABLES is not set
+# CONFIG_IP_ROUTE_MULTIPATH is not set
+# CONFIG_IP_ROUTE_VERBOSE is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
+# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
+# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
-CONFIG_TCP_MD5SIG=y
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
-CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-# CONFIG_SCTP_DBG_OBJCNT is not set
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -347,44 +316,7 @@ CONFIG_SCTP_HMAC_MD5=y
#
# QoS and/or fair queueing
#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=y
-CONFIG_NET_SCH_CLK_JIFFIES=y
-# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set
-# CONFIG_NET_SCH_CLK_CPU is not set
-
-#
-# Queueing/Scheduling
-#
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_NETEM=m
-CONFIG_NET_SCH_INGRESS=m
-
-#
-# Classification
-#
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_BASIC=m
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-# CONFIG_NET_CLS_FW is not set
-# CONFIG_NET_CLS_U32 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_POLICE is not set
-CONFIG_NET_ESTIMATOR=y
+# CONFIG_NET_SCHED is not set
#
# Network testing
@@ -393,8 +325,17 @@ CONFIG_NET_ESTIMATOR=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
-CONFIG_FIB_RULES=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -403,52 +344,25 @@ CONFIG_FIB_RULES=y
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNPACPI is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+# CONFIG_MISC_DEVICES is not set
# CONFIG_IDE is not set
#
@@ -456,48 +370,29 @@ CONFIG_BLK_DEV_NBD=y
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
+# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
+# CONFIG_AX88796 is not set
CONFIG_MIPS_SIM_NET=y
# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -513,49 +408,18 @@ CONFIG_MIPS_SIM_NET=y
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
+# CONFIG_INPUT is not set
#
# Hardware I/O ports
#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_LIBPS2 is not set
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
#
@@ -581,31 +445,13 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
#
@@ -613,118 +459,60 @@ CONFIG_LEGACY_PTY_COUNT=256
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
#
-# Dallas's 1-wire bus
+# Sonics Silicon Backplane
#
-# CONFIG_W1 is not set
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Hardware Monitoring support
+# Multifunction device drivers
#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
# Graphics support
#
-# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Sound
+# Display device support
#
-# CONFIG_SOUND is not set
+# CONFIG_DISPLAY_SUPPORT is not set
#
-# HID Devices
-#
-# CONFIG_HID is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
+# Sound
#
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
-
-#
-# LED devices
-#
# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
+CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
+# Userspace I/O
#
+# CONFIG_UIO is not set
#
# File systems
#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
@@ -732,6 +520,7 @@ CONFIG_EXT2_FS=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
CONFIG_ROMFS_FS=y
# CONFIG_INOTIFY is not set
@@ -760,10 +549,11 @@ CONFIG_ROMFS_FS=y
CONFIG_PROC_FS=y
# CONFIG_PROC_KCORE is not set
CONFIG_PROC_SYSCTL=y
-# CONFIG_SYSFS is not set
-# CONFIG_TMPFS is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
@@ -781,10 +571,7 @@ CONFIG_RAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
@@ -796,6 +583,7 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -803,22 +591,14 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
+# CONFIG_DLM is not set
#
# Profiling support
@@ -833,20 +613,22 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_ENABLE_MUST_CHECK=y
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=14
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -854,7 +636,9 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_CROSSCOMPILE=y
CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# CONFIG_DEBUG_STACK_USAGE is not set
@@ -865,60 +649,20 @@ CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp"
# Security options
#
# CONFIG_KEYS is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_MANAGER=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=m
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_LRW=m
-# CONFIG_CRYPTO_DES is not set
-CONFIG_CRYPTO_FCRYPT=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-CONFIG_CRYPTO_CAMELLIA=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
#
# Library routines
#
-CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
-CONFIG_CRC16=y
-CONFIG_CRC32=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 3ed991ae0eb..49dfcef2518 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -196,6 +196,7 @@ CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_UTS_NS is not set
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c
index 5e1da53b04a..82f9e9013e7 100644
--- a/arch/mips/emma2rh/markeins/setup.c
+++ b/arch/mips/emma2rh/markeins/setup.c
@@ -104,12 +104,6 @@ void __init plat_time_init(void)
mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2;
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- /* we are using the cpu counter for timer interrupts */
- setup_irq(CPU_IRQ_BASE + 7, irq);
-}
-
static void markeins_board_init(void);
extern void markeins_irq_setup(void);
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index a3afa39faae..d7745c8976f 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -9,6 +9,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
time.o topology.o traps.o unaligned.o
obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
+obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \
irix5sys.o sysirix.o
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
new file mode 100644
index 00000000000..4c651b2680f
--- /dev/null
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -0,0 +1,144 @@
+/*
+ * GT641xx clockevent routines.
+ *
+ * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#include <asm/gt64120.h>
+#include <asm/time.h>
+
+#include <irq.h>
+
+static DEFINE_SPINLOCK(gt641xx_timer_lock);
+static unsigned int gt641xx_base_clock;
+
+void gt641xx_set_base_clock(unsigned int clock)
+{
+ gt641xx_base_clock = clock;
+}
+
+int gt641xx_timer0_state(void)
+{
+ if (GT_READ(GT_TC0_OFS))
+ return 0;
+
+ GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+ GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
+
+ return 1;
+}
+
+static int gt641xx_timer0_set_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+ u32 ctrl;
+
+ spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
+ ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+
+ GT_WRITE(GT_TC0_OFS, delta);
+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+ spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+
+ return 0;
+}
+
+static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+ u32 ctrl;
+
+ spin_lock_irqsave(&gt641xx_timer_lock, flags);
+
+ ctrl = GT_READ(GT_TC_CONTROL_OFS);
+ ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ ctrl |= GT_TC_CONTROL_ENTC0_MSK;
+ break;
+ default:
+ break;
+ }
+
+ GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
+
+ spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+}
+
+static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device gt641xx_timer0_clockevent = {
+ .name = "gt641xx-timer0",
+ .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+ .cpumask = CPU_MASK_CPU0,
+ .irq = GT641XX_TIMER0_IRQ,
+ .set_next_event = gt641xx_timer0_set_next_event,
+ .set_mode = gt641xx_timer0_set_mode,
+ .event_handler = gt641xx_timer0_event_handler,
+};
+
+static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &gt641xx_timer0_clockevent;
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction gt641xx_timer0_irqaction = {
+ .handler = gt641xx_timer0_interrupt,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "gt641xx_timer0",
+};
+
+static int __init gt641xx_timer0_clockevent_init(void)
+{
+ struct clock_event_device *cd;
+
+ if (!gt641xx_base_clock)
+ return 0;
+
+ GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
+
+ cd = &gt641xx_timer0_clockevent;
+ cd->rating = 200 + gt641xx_base_clock / 10000000;
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ clockevent_set_clock(cd, gt641xx_base_clock);
+
+ clockevents_register_device(&gt641xx_timer0_clockevent);
+
+ return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
+}
+arch_initcall(gt641xx_timer0_clockevent_init);
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index 08b84d476c8..ae2984fff58 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -10,6 +10,7 @@
#include <linux/interrupt.h>
#include <linux/percpu.h>
+#include <asm/smtc_ipi.h>
#include <asm/time.h>
static int mips_next_event(unsigned long delta,
@@ -185,7 +186,7 @@ static int c0_compare_int_usable(void)
* IP7 already pending? Try to clear it by acking the timer.
*/
if (c0_compare_int_pending()) {
- write_c0_compare(read_c0_compare());
+ write_c0_compare(read_c0_count());
irq_disable_hazard();
if (c0_compare_int_pending())
return 0;
@@ -201,7 +202,7 @@ static int c0_compare_int_usable(void)
if (!c0_compare_int_pending())
return 0;
- write_c0_compare(read_c0_compare());
+ write_c0_compare(read_c0_count());
irq_disable_hazard();
if (c0_compare_int_pending())
return 0;
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index b997af713eb..7852c7cdf29 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1172,8 +1172,8 @@ static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, u
prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid;
- psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current);
- psinfo.pr_sid = prstatus.pr_sid = process_session(current);
+ psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_nr(current);
+ psinfo.pr_sid = prstatus.pr_sid = task_session_nr(current);
if (current->pid == current->tgid) {
/*
* This is the record for the group leader. Add in the
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 85c2e389edd..a0a91056fda 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -609,7 +609,7 @@ repeat:
p = list_entry(_p, struct task_struct, sibling);
if ((type == IRIX_P_PID) && p->pid != pid)
continue;
- if ((type == IRIX_P_PGID) && process_group(p) != pid)
+ if ((type == IRIX_P_PGID) && task_pgrp_nr(p) != pid)
continue;
if ((p->exit_signal != SIGCHLD))
continue;
diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c
index cb0801437b6..e7ed0ac4853 100644
--- a/arch/mips/kernel/module.c
+++ b/arch/mips/kernel/module.c
@@ -381,7 +381,7 @@ const struct exception_table_entry *search_module_dbetables(unsigned long addr)
return e;
}
-/* Put in dbe list if neccessary. */
+/* Put in dbe list if necessary. */
int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index ee7790d9deb..4c477c7ff74 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -763,11 +763,11 @@ asmlinkage int irix_setpgrp(int flags)
printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags);
#endif
if(!flags)
- error = process_group(current);
+ error = task_pgrp_nr(current);
else
error = sys_setsid();
#ifdef DEBUG_PROCGRPS
- printk("returning %d\n", process_group(current));
+ printk("returning %d\n", task_pgrp_nr(current));
#endif
return error;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index ea7cfe766a8..6c6849a8f13 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -40,17 +40,6 @@
#include <irq.h>
/*
- * The integer part of the number of usecs per jiffy is taken from tick,
- * but the fractional part is not recorded, so we calculate it using the
- * initial value of HZ. This aids systems where tick isn't really an
- * integer (e.g. for HZ = 128).
- */
-#define USECS_PER_JIFFY TICK_SIZE
-#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ))
-
-#define TICK_SIZE (tick_nsec / 1000)
-
-/*
* forward reference
*/
DEFINE_SPINLOCK(rtc_lock);
@@ -182,84 +171,59 @@ struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init init_mips_clocksource(void)
+void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock)
{
u64 temp;
u32 shift;
- if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
- return;
-
- /* Calclate a somewhat reasonable rating value */
- clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
/* Find a shift value */
for (shift = 32; shift > 0; shift--) {
temp = (u64) NSEC_PER_SEC << shift;
- do_div(temp, mips_hpt_frequency);
+ do_div(temp, clock);
if ((temp >> 32) == 0)
break;
}
- clocksource_mips.shift = shift;
- clocksource_mips.mult = (u32)temp;
-
- clocksource_register(&clocksource_mips);
+ cs->shift = shift;
+ cs->mult = (u32) temp;
}
-void __init __weak plat_time_init(void)
+void __cpuinit clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock)
{
+ u64 temp;
+ u32 shift;
+
+ /* Find a shift value */
+ for (shift = 32; shift > 0; shift--) {
+ temp = (u64) clock << shift;
+ do_div(temp, NSEC_PER_SEC);
+ if ((temp >> 32) == 0)
+ break;
+ }
+ cd->shift = shift;
+ cd->mult = (u32) temp;
}
-void __init __weak plat_timer_setup(struct irqaction *irq)
+static void __init init_mips_clocksource(void)
{
-}
+ if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read)
+ return;
-#ifdef CONFIG_MIPS_MT_SMTC
-DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+ /* Calclate a somewhat reasonable rating value */
+ clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
-static void smtc_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
+ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+
+ clocksource_register(&clocksource_mips);
}
-static void mips_broadcast(cpumask_t mask)
+void __init __weak plat_time_init(void)
{
- unsigned int cpu;
-
- for_each_cpu_mask(cpu, mask)
- smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
}
-static void setup_smtc_dummy_clockevent_device(void)
+void __init __weak plat_timer_setup(struct irqaction *irq)
{
- //uint64_t mips_freq = mips_hpt_^frequency;
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *cd;
-
- cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
-
- cd->name = "SMTC";
- cd->features = CLOCK_EVT_FEAT_DUMMY;
-
- /* Calculate the min / max delta */
- cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
- cd->shift = 0; //32;
- cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd);
-
- cd->rating = 200;
- cd->irq = 17; //-1;
-// if (cpu)
-// cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu);
-// else
- cd->cpumask = cpumask_of_cpu(cpu);
-
- cd->set_mode = smtc_set_mode;
-
- cd->broadcast = mips_broadcast;
-
- clockevents_register_device(cd);
}
-#endif
void __init time_init(void)
{
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 7b78d137259..fa500787152 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -314,7 +314,7 @@ void show_registers(const struct pt_regs *regs)
__show_regs(regs);
print_modules();
printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n",
- current->comm, current->pid, current_thread_info(), current);
+ current->comm, task_pid_nr(current), current_thread_info(), current);
show_stacktrace(current, regs);
show_code((unsigned int __user *) regs->cp0_epc);
printk("\n");
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c
index 09314a20f9f..2cc6745991a 100644
--- a/arch/mips/lemote/lm2e/setup.c
+++ b/arch/mips/lemote/lm2e/setup.c
@@ -53,11 +53,6 @@ unsigned long bus_clock;
unsigned int memsize;
unsigned int highmemsize = 0;
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(MIPS_CPU_IRQ_BASE + 7, irq);
-}
-
void __init plat_time_init(void)
{
/* setup mips r4k timer */
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 1d00b778ff1..9d6243a8c15 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -147,21 +147,8 @@ void __init plat_time_init(void)
#endif
}
-//static irqreturn_t mips_perf_interrupt(int irq, void *dev_id)
-//{
-// return perf_irq();
-//}
-
-//static struct irqaction perf_irqaction = {
-// .handler = mips_perf_interrupt,
-// .flags = IRQF_DISABLED | IRQF_PERCPU,
-// .name = "performance",
-//};
-
void __init plat_perf_setup(void)
{
-// struct irqaction *irq = &perf_irqaction;
-
cp0_perfcount_irq = -1;
#ifdef MSC01E_INT_BASE
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 98b5e5bac02..b0b034c4654 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -165,12 +165,11 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
for (i = 0; i < nents; i++, sg++) {
unsigned long addr;
- addr = (unsigned long) page_address(sg->page);
+ addr = (unsigned long) sg_virt(sg);
if (!plat_device_is_coherent(dev) && addr)
- __dma_sync(addr + sg->offset, sg->length, direction);
+ __dma_sync(addr, sg->length, direction);
sg->dma_address = plat_map_dma_mem(dev,
- (void *)(addr + sg->offset),
- sg->length);
+ (void *)addr, sg->length);
}
return nents;
@@ -223,10 +222,9 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
for (i = 0; i < nhwentries; i++, sg++) {
if (!plat_device_is_coherent(dev) &&
direction != DMA_TO_DEVICE) {
- addr = (unsigned long) page_address(sg->page);
+ addr = (unsigned long) sg_virt(sg);
if (addr)
- __dma_sync(addr + sg->offset, sg->length,
- direction);
+ __dma_sync(addr, sg->length, direction);
}
plat_unmap_dma_mem(sg->dma_address);
}
@@ -304,7 +302,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync((unsigned long)page_address(sg->page),
+ __dma_sync((unsigned long)page_address(sg_page(sg)),
sg->length, direction);
plat_unmap_dma_mem(sg->dma_address);
}
@@ -322,7 +320,7 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nele
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
if (!plat_device_is_coherent(dev))
- __dma_sync((unsigned long)page_address(sg->page),
+ __dma_sync((unsigned long)page_address(sg_page(sg)),
sg->length, direction);
plat_unmap_dma_mem(sg->dma_address);
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 5699c7713e2..fa636fc6b7b 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -173,7 +173,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(tsk)) {
+ if (is_global_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
deleted file mode 100644
index fb6f235348b..00000000000
--- a/arch/mips/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/mips/pci/pci-excite.c b/arch/mips/pci/pci-excite.c
index 3c86c77cb74..8a56876afcc 100644
--- a/arch/mips/pci/pci-excite.c
+++ b/arch/mips/pci/pci-excite.c
@@ -131,7 +131,7 @@ static int __init basler_excite_pci_setup(void)
ocd_writel(0x00000000, bar + 0x100);
}
- /* Finally, enable the PCI interupt */
+ /* Finally, enable the PCI interrupt */
#if USB_IRQ > 7
set_c0_intcontrol(1 << USB_IRQ);
#else
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_time.c b/arch/mips/pmc-sierra/msp71xx/msp_time.c
index f221d476362..7cfeda5a651 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_time.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_time.c
@@ -86,8 +86,5 @@ void __init plat_timer_setup(struct irqaction *irq)
#ifdef CONFIG_IRQ_MSP_CIC
/* we are using the vpe0 counter for timer interrupts */
setup_irq(MSP_INT_VPE0_TIMER, irq);
-#else
- /* we are using the mips counter for timer interrupts */
- setup_irq(MSP_INT_TIMER, irq);
#endif
}
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 015fcc363dc..855977ca51c 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -137,11 +137,6 @@ int rtc_mips_set_time(unsigned long tim)
return 0;
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(7, irq);
-}
-
void __init plat_time_init(void)
{
mips_hpt_frequency = cpu_clock_freq / 2;
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c
index 681b593071c..3305fa9ae66 100644
--- a/arch/mips/sgi-ip27/ip27-init.c
+++ b/arch/mips/sgi-ip27/ip27-init.c
@@ -110,7 +110,7 @@ static void __init per_hub_init(cnodeid_t cnode)
}
}
-void __init per_cpu_init(void)
+void __cpuinit per_cpu_init(void)
{
int cpu = smp_processor_id();
int slice = LOCAL_HUB_L(PI_CPU_NUM);
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index d467bf4f6c3..f5dccf01da1 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -111,8 +111,24 @@ unsigned long read_persistent_clock(void)
return mktime(year, month, date, hour, min, sec);
}
-static int rt_set_next_event(unsigned long delta,
- struct clock_event_device *evt)
+static void enable_rt_irq(unsigned int irq)
+{
+}
+
+static void disable_rt_irq(unsigned int irq)
+{
+}
+
+static struct irq_chip rt_irq_type = {
+ .name = "SN HUB RT timer",
+ .ack = disable_rt_irq,
+ .mask = disable_rt_irq,
+ .mask_ack = disable_rt_irq,
+ .unmask = enable_rt_irq,
+ .eoi = enable_rt_irq,
+};
+
+static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
{
unsigned int cpu = smp_processor_id();
int slice = cputoslice(cpu) == 0;
@@ -129,50 +145,24 @@ static void rt_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
+ case CLOCK_EVT_MODE_ONESHOT:
/* The only mode supported */
break;
+ case CLOCK_EVT_MODE_PERIODIC:
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
- case CLOCK_EVT_MODE_ONESHOT:
case CLOCK_EVT_MODE_RESUME:
/* Nothing to do */
break;
}
}
-struct clock_event_device rt_clock_event_device = {
- .name = "HUB-RT",
- .features = CLOCK_EVT_FEAT_ONESHOT,
-
- .rating = 300,
- .set_next_event = rt_set_next_event,
- .set_mode = rt_set_mode,
-};
-
-static void enable_rt_irq(unsigned int irq)
-{
-}
-
-static void disable_rt_irq(unsigned int irq)
-{
-}
-
-static struct irq_chip rt_irq_type = {
- .name = "SN HUB RT timer",
- .ack = disable_rt_irq,
- .mask = disable_rt_irq,
- .mask_ack = disable_rt_irq,
- .unmask = enable_rt_irq,
- .eoi = enable_rt_irq,
-};
-
unsigned int rt_timer_irq;
-static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id)
+static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
{
- struct clock_event_device *cd = &rt_clock_event_device;
+ struct clock_event_device *cd = dev_id;
unsigned int cpu = smp_processor_id();
int slice = cputoslice(cpu) == 0;
@@ -182,11 +172,10 @@ static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static struct irqaction rt_irqaction = {
- .handler = (irq_handler_t) ip27_rt_timer_interrupt,
- .flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
- .name = "timer"
+struct irqaction hub_rt_irqaction = {
+ .handler = hub_rt_counter_handler,
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .name = "hub-rt",
};
/*
@@ -200,32 +189,48 @@ static struct irqaction rt_irqaction = {
#define NSEC_PER_CYCLE 800
#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE)
-static void __init ip27_rt_clock_event_init(void)
+static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent);
+static DEFINE_PER_CPU(char [11], hub_rt_name);
+
+static void __cpuinit hub_rt_clock_event_init(void)
{
- struct clock_event_device *cd = &rt_clock_event_device;
unsigned int cpu = smp_processor_id();
- int irq = allocate_irqno();
-
- if (irq < 0)
- panic("Can't allocate interrupt number for timer interrupt");
-
- rt_timer_irq = irq;
-
+ struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu);
+ unsigned char *name = per_cpu(hub_rt_name, cpu);
+ int irq = rt_timer_irq;
+
+ sprintf(name, "hub-rt %d", cpu);
+ cd->name = "HUB-RT",
+ cd->features = CLOCK_EVT_FEAT_ONESHOT,
+ clockevent_set_clock(cd, CYCLES_PER_SEC);
+ cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ cd->rating = 200,
cd->irq = irq,
cd->cpumask = cpumask_of_cpu(cpu),
-
- /*
- * Calculate the min / max delta
- */
- cd->mult =
- div_sc((unsigned long) CYCLES_PER_SEC, NSEC_PER_SEC, 32);
- cd->shift = 32;
- cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
- cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+ cd->rating = 300,
+ cd->set_next_event = rt_next_event,
+ cd->set_mode = rt_set_mode,
clockevents_register_device(cd);
+}
+
+static void __init hub_rt_clock_event_global_init(void)
+{
+ unsigned int irq;
+
+ do {
+ smp_wmb();
+ irq = rt_timer_irq;
+ if (irq)
+ break;
+
+ irq = allocate_irqno();
+ if (irq < 0)
+ panic("Allocation of irq number for timer failed");
+ } while (xchg(&rt_timer_irq, irq));
set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
- setup_irq(irq, &rt_irqaction);
+ setup_irq(irq, &hub_rt_irqaction);
}
static cycle_t hub_rt_read(void)
@@ -233,27 +238,29 @@ static cycle_t hub_rt_read(void)
return REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT);
}
-struct clocksource ht_rt_clocksource = {
+struct clocksource hub_rt_clocksource = {
.name = "HUB-RT",
.rating = 200,
.read = hub_rt_read,
.mask = CLOCKSOURCE_MASK(52),
- .shift = 32,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static void __init ip27_rt_clocksource_init(void)
+static void __init hub_rt_clocksource_init(void)
{
- clocksource_register(&ht_rt_clocksource);
+ struct clocksource *cs = &hub_rt_clocksource;
+
+ clocksource_set_clock(cs, CYCLES_PER_SEC);
+ clocksource_register(cs);
}
void __init plat_time_init(void)
{
- ip27_rt_clock_event_init();
- ip27_rt_clocksource_init();
+ hub_rt_clocksource_init();
+ hub_rt_clock_event_global_init();
}
-void __init cpu_time_init(void)
+void __cpuinit cpu_time_init(void)
{
lboard_t *board;
klcpu_t *cpu;
@@ -271,6 +278,7 @@ void __init cpu_time_init(void)
printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
+ hub_rt_clock_event_init();
set_c0_status(SRB_TIMOCLK);
}
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 7aa79bf63c4..10299bafeab 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -452,6 +452,43 @@ static void bcm1480_kgdb_interrupt(void)
extern void bcm1480_mailbox_interrupt(void);
+static inline void dispatch_ip4(void)
+{
+ int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_TIMER_0 + cpu;
+
+ /* Reset the timer */
+ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+
+ do_IRQ(irq);
+}
+
+static inline void dispatch_ip2(void)
+{
+ unsigned long long mask_h, mask_l;
+ unsigned int cpu = smp_processor_id();
+ unsigned long base;
+
+ /*
+ * Default...we've hit an IP[2] interrupt, which means we've got to
+ * check the 1480 interrupt registers to figure out what to do. Need
+ * to detect which CPU we're on, now that smp_affinity is supported.
+ */
+ base = A_BCM1480_IMR_MAPPER(cpu);
+ mask_h = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
+ mask_l = __raw_readq(
+ IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
+
+ if (mask_h) {
+ if (mask_h ^ 1)
+ do_IRQ(fls64(mask_h) - 1);
+ else if (mask_l)
+ do_IRQ(63 + fls64(mask_l));
+ }
+}
+
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending;
@@ -469,17 +506,8 @@ asmlinkage void plat_irq_dispatch(void)
else
#endif
- if (pending & CAUSEF_IP4) {
- int cpu = smp_processor_id();
- int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
- /* Reset the timer */
- __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
- do_IRQ(irq);
- }
-
+ if (pending & CAUSEF_IP4)
+ dispatch_ip4();
#ifdef CONFIG_SMP
else if (pending & CAUSEF_IP3)
bcm1480_mailbox_interrupt();
@@ -490,27 +518,6 @@ asmlinkage void plat_irq_dispatch(void)
bcm1480_kgdb_interrupt(); /* KGDB (uart 1) */
#endif
- else if (pending & CAUSEF_IP2) {
- unsigned long long mask_h, mask_l;
- unsigned long base;
-
- /*
- * Default...we've hit an IP[2] interrupt, which means we've
- * got to check the 1480 interrupt registers to figure out what
- * to do. Need to detect which CPU we're on, now that
- * smp_affinity is supported.
- */
- base = A_BCM1480_IMR_MAPPER(smp_processor_id());
- mask_h = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H));
- mask_l = __raw_readq(
- IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L));
-
- if (mask_h) {
- if (mask_h ^ 1)
- do_IRQ(fls64(mask_h) - 1);
- else
- do_IRQ(63 + fls64(mask_l));
- }
- }
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
}
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index 6eac36d1b8c..436ba78359a 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -58,7 +58,7 @@ static void *mailbox_0_regs[] = {
/*
* SMP init and finish on secondary CPUs
*/
-void bcm1480_smp_init(void)
+void __cpuinit bcm1480_smp_init(void)
{
unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
STATUSF_IP1 | STATUSF_IP0;
@@ -67,10 +67,11 @@ void bcm1480_smp_init(void)
change_c0_status(ST0_IM, imask);
}
-void bcm1480_smp_finish(void)
+void __cpuinit bcm1480_smp_finish(void)
{
- extern void bcm1480_time_init(void);
- bcm1480_time_init();
+ extern void sb1480_clockevent_init(void);
+
+ sb1480_clockevent_init();
local_irq_enable();
}
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index 5b4bfbbb5a2..610f0253954 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -15,23 +15,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-
-/*
- * These are routines to set up and handle interrupts from the
- * bcm1480 general purpose timer 0. We're using the timer as a
- * system clock, so we set it up to run at 100 Hz. On every
- * interrupt, we update our idea of what the time of day is,
- * then call do_timer() in the architecture-independent kernel
- * code to do general bookkeeping (e.g. update jiffies, run
- * bottom halves, etc.)
- */
#include <linux/clockchips.h>
#include <linux/interrupt.h>
-#include <linux/sched.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
#include <linux/spinlock.h>
-#include <linux/kernel_stat.h>
-#include <asm/irq.h>
#include <asm/addrspace.h>
#include <asm/time.h>
#include <asm/io.h>
@@ -48,33 +37,10 @@
#define IMR_IP3_VAL K_BCM1480_INT_MAP_I1
#define IMR_IP4_VAL K_BCM1480_INT_MAP_I2
-#ifdef CONFIG_SIMULATION
-#define BCM1480_HPT_VALUE 50000
-#else
-#define BCM1480_HPT_VALUE 1000000
-#endif
-
extern int bcm1480_steal_irq(int irq);
-void __init plat_time_init(void)
-{
- unsigned int cpu = smp_processor_id();
- unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
-
- BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
-
- bcm1480_mask_irq(cpu, irq);
-
- /* Map the timer interrupt to ip[4] of this cpu */
- __raw_writeq(IMR_IP4_VAL, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H)
- + (irq<<3)));
-
- bcm1480_unmask_irq(cpu, irq);
- bcm1480_steal_irq(irq);
-}
-
/*
- * The general purpose timer ticks at 1 Mhz independent if
+ * The general purpose timer ticks at 1MHz independent if
* the rest of the system
*/
static void sibyte_set_mode(enum clock_event_mode mode,
@@ -89,7 +55,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
__raw_writeq(0, timer_cfg);
- __raw_writeq(BCM1480_HPT_VALUE / HZ - 1, timer_init);
+ __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
__raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
timer_cfg);
break;
@@ -101,76 +67,117 @@ static void sibyte_set_mode(enum clock_event_mode mode,
break;
case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
+ case CLOCK_EVT_MODE_RESUME:
;
}
}
-struct clock_event_device sibyte_hpt_clockevent = {
- .name = "bcm1480-counter",
- .features = CLOCK_EVT_FEAT_PERIODIC,
- .set_mode = sibyte_set_mode,
- .shift = 32,
- .irq = 0,
-};
+static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd)
+{
+ unsigned int cpu = smp_processor_id();
+ void __iomem *timer_init;
+ unsigned int cnt;
+ int res;
+
+ timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
+ cnt = __raw_readq(timer_init);
+ cnt += delta;
+ __raw_writeq(cnt, timer_init);
+ res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0;
+
+ return res;
+}
static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
{
- struct clock_event_device *cd = &sibyte_hpt_clockevent;
unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd = dev_id;
+ void __iomem *timer_cfg;
+
+ timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
/* Reset the timer */
- __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ timer_cfg);
cd->event_handler(cd);
return IRQ_HANDLED;
}
-static struct irqaction sibyte_counter_irqaction = {
- .handler = sibyte_counter_handler,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
- .name = "timer",
-};
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
-/*
- * This interrupt is "special" in that it doesn't use the request_irq
- * way to hook the irq line. The timer interrupt is initialized early
- * enough to make this a major pain, and it's also firing enough to
- * warrant a bit of special case code. bcm1480_timer_interrupt is
- * called directly from irq_handler.S when IP[4] is set during an
- * interrupt
- */
-static void __init sb1480_clockevent_init(void)
+void __cpuinit sb1480_clockevent_init(void)
{
unsigned int cpu = smp_processor_id();
unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu;
+ struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+ struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+ unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
- setup_irq(irq, &sibyte_counter_irqaction);
-}
+ BUG_ON(cpu > 3); /* Only have 4 general purpose timers */
-void bcm1480_timer_interrupt(void)
-{
- int cpu = smp_processor_id();
- int irq = K_BCM1480_INT_TIMER_0 + cpu;
+ sprintf(name, "bcm1480-counter %d", cpu);
+ cd->name = name;
+ cd->features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_MODE_ONESHOT;
+ clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(1, cd);
+ cd->rating = 200;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of_cpu(cpu);
+ cd->set_next_event = sibyte_next_event;
+ cd->set_mode = sibyte_set_mode;
+ clockevents_register_device(cd);
- /* Reset the timer */
- __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
+ bcm1480_mask_irq(cpu, irq);
+
+ /*
+ * Map timer interrupt to IP[4] of this cpu
+ */
+ __raw_writeq(IMR_IP4_VAL,
+ IOADDR(A_BCM1480_IMR_REGISTER(cpu,
+ R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
+
+ bcm1480_unmask_irq(cpu, irq);
+ bcm1480_steal_irq(irq);
- ll_timer_interrupt(irq);
+ action->handler = sibyte_counter_handler;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU;
+ action->name = name;
+ action->dev_id = cd;
+ setup_irq(irq, action);
}
static cycle_t bcm1480_hpt_read(void)
{
- /* We assume this function is called xtime_lock held. */
- unsigned long count =
- __raw_readq(IOADDR(A_SCD_TIMER_REGISTER(0, R_SCD_TIMER_CNT)));
- return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count;
+ return (cycle_t) __raw_readq(IOADDR(A_SCD_ZBBUS_CYCLE_COUNT));
}
-void __init bcm1480_hpt_setup(void)
+struct clocksource bcm1480_clocksource = {
+ .name = "zbbus-cycles",
+ .rating = 200,
+ .read = bcm1480_hpt_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1480_clocksource_init(void)
+{
+ struct clocksource *cs = &bcm1480_clocksource;
+ unsigned int plldiv;
+ unsigned long zbbus;
+
+ plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
+ zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
+ clocksource_set_clock(cs, zbbus);
+ clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
{
- clocksource_mips.read = bcm1480_hpt_read;
- mips_hpt_frequency = BCM1480_HPT_VALUE;
+ sb1480_clocksource_init();
sb1480_clockevent_init();
}
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 7659174819c..53780a179d1 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -400,43 +400,27 @@ static void sb1250_kgdb_interrupt(void)
#endif /* CONFIG_KGDB */
-static inline void sb1250_timer_interrupt(void)
-{
- int cpu = smp_processor_id();
- int irq = K_INT_TIMER_0 + cpu;
-
- irq_enter();
- kstat_this_cpu.irqs[irq]++;
-
- write_seqlock(&xtime_lock);
-
- /* ACK interrupt */
- ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
-
- /*
- * call the generic timer interrupt handling
- */
- do_timer(1);
+extern void sb1250_mailbox_interrupt(void);
- write_sequnlock(&xtime_lock);
+static inline void dispatch_ip2(void)
+{
+ unsigned int cpu = smp_processor_id();
+ unsigned long long mask;
/*
- * In UP mode, we call local_timer_interrupt() to do profiling
- * and process accouting.
- *
- * In SMP mode, local_timer_interrupt() is invoked by appropriate
- * low-level local timer interrupt handler.
+ * Default...we've hit an IP[2] interrupt, which means we've got to
+ * check the 1250 interrupt registers to figure out what to do. Need
+ * to detect which CPU we're on, now that smp_affinity is supported.
*/
- local_timer_interrupt(irq);
-
- irq_exit();
+ mask = __raw_readq(IOADDR(A_IMR_REGISTER(cpu,
+ R_IMR_INTERRUPT_STATUS_BASE)));
+ if (mask)
+ do_IRQ(fls64(mask) - 1);
}
-extern void sb1250_mailbox_interrupt(void);
-
asmlinkage void plat_irq_dispatch(void)
{
+ unsigned int cpu = smp_processor_id();
unsigned int pending;
/*
@@ -454,7 +438,7 @@ asmlinkage void plat_irq_dispatch(void)
if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */
do_IRQ(MIPS_CPU_IRQ_BASE + 7);
else if (pending & CAUSEF_IP4)
- sb1250_timer_interrupt();
+ do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */
#ifdef CONFIG_SMP
else if (pending & CAUSEF_IP3)
@@ -466,21 +450,8 @@ asmlinkage void plat_irq_dispatch(void)
sb1250_kgdb_interrupt();
#endif
- else if (pending & CAUSEF_IP2) {
- unsigned long long mask;
-
- /*
- * Default...we've hit an IP[2] interrupt, which means we've
- * got to check the 1250 interrupt registers to figure out what
- * to do. Need to detect which CPU we're on, now that
- * smp_affinity is supported.
- */
- mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(),
- R_IMR_INTERRUPT_STATUS_BASE)));
- if (mask)
- do_IRQ(fls64(mask) - 1);
- else
- spurious_interrupt();
- } else
+ else if (pending & CAUSEF_IP2)
+ dispatch_ip2();
+ else
spurious_interrupt();
}
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index c38e1f34460..3f52c95a4eb 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -46,7 +46,7 @@ static void *mailbox_regs[] = {
/*
* SMP init and finish on secondary CPUs
*/
-void sb1250_smp_init(void)
+void __cpuinit sb1250_smp_init(void)
{
unsigned int imask = STATUSF_IP4 | STATUSF_IP3 | STATUSF_IP2 |
STATUSF_IP1 | STATUSF_IP0;
@@ -55,10 +55,11 @@ void sb1250_smp_init(void)
change_c0_status(ST0_IM, imask);
}
-void sb1250_smp_finish(void)
+void __cpuinit sb1250_smp_finish(void)
{
- extern void sb1250_time_init(void);
- sb1250_time_init();
+ extern void sb1250_clockevent_init(void);
+
+ sb1250_clockevent_init();
local_irq_enable();
}
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index fe11fed8e0d..a41e908bc21 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -52,26 +52,6 @@
extern int sb1250_steal_irq(int irq);
-static cycle_t sb1250_hpt_read(void);
-
-void __init sb1250_hpt_setup(void)
-{
- int cpu = smp_processor_id();
-
- if (!cpu) {
- /* Setup hpt using timer #3 but do not enable irq for it */
- __raw_writeq(0, IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
- __raw_writeq(SB1250_HPT_VALUE,
- IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_INIT)));
- __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM, R_SCD_TIMER_CFG)));
-
- mips_hpt_frequency = V_SCD_TIMER_FREQ;
- clocksource_mips.read = sb1250_hpt_read;
- clocksource_mips.mask = M_SCD_TIMER_INIT;
- }
-}
-
/*
* The general purpose timer ticks at 1 Mhz independent if
* the rest of the system
@@ -100,6 +80,7 @@ static void sibyte_set_mode(enum clock_event_mode mode,
break;
case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
+ case CLOCK_EVT_MODE_RESUME:
;
}
}
@@ -120,90 +101,14 @@ sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
return 0;
}
-struct clock_event_device sibyte_hpt_clockevent = {
- .name = "sb1250-counter",
- .features = CLOCK_EVT_FEAT_PERIODIC,
- .set_mode = sibyte_set_mode,
- .set_next_event = sibyte_next_event,
- .shift = 32,
- .irq = 0,
-};
-
static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
{
- struct clock_event_device *cd = &sibyte_hpt_clockevent;
-
- cd->event_handler(cd);
-
- return IRQ_HANDLED;
-}
-
-static struct irqaction sibyte_irqaction = {
- .handler = sibyte_counter_handler,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
- .name = "timer",
-};
-
-/*
- * The general purpose timer ticks at 1 Mhz independent if
- * the rest of the system
- */
-static void sibyte_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
unsigned int cpu = smp_processor_id();
- void __iomem *timer_cfg, *timer_init;
+ struct clock_event_device *cd = dev_id;
- timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
- timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- __raw_writeq(0, timer_cfg);
- __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init);
- __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
- timer_cfg);
- break;
-
- case CLOCK_EVT_MODE_ONESHOT:
- /* Stop the timer until we actually program a shot */
- case CLOCK_EVT_MODE_SHUTDOWN:
- __raw_writeq(0, timer_cfg);
- break;
-
- case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */
- ;
- }
-}
-
-static int
-sibyte_next_event(unsigned long delta, struct clock_event_device *evt)
-{
- unsigned int cpu = smp_processor_id();
- void __iomem *timer_cfg, *timer_init;
-
- timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG));
- timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT));
-
- __raw_writeq(0, timer_cfg);
- __raw_writeq(delta, timer_init);
- __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg);
-
- return 0;
-}
-
-struct clock_event_device sibyte_hpt_clockevent = {
- .name = "sb1250-counter",
- .features = CLOCK_EVT_FEAT_PERIODIC,
- .set_mode = sibyte_set_mode,
- .set_next_event = sibyte_next_event,
- .shift = 32,
- .irq = 0,
-};
-
-static irqreturn_t sibyte_counter_handler(int irq, void *dev_id)
-{
- struct clock_event_device *cd = &sibyte_hpt_clockevent;
+ /* ACK interrupt */
+ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)));
cd->event_handler(cd);
@@ -216,15 +121,35 @@ static struct irqaction sibyte_irqaction = {
.name = "timer",
};
-static void __init sb1250_clockevent_init(void)
+static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent);
+static DEFINE_PER_CPU(struct irqaction, sibyte_hpt_irqaction);
+static DEFINE_PER_CPU(char [18], sibyte_hpt_name);
+
+void __cpuinit sb1250_clockevent_init(void)
{
- struct clock_event_device *cd = &sibyte_hpt_clockevent;
unsigned int cpu = smp_processor_id();
- int irq = K_INT_TIMER_0 + cpu;
+ unsigned int irq = K_INT_TIMER_0 + cpu;
+ struct irqaction *action = &per_cpu(sibyte_hpt_irqaction, cpu);
+ struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu);
+ unsigned char *name = per_cpu(sibyte_hpt_name, cpu);
/* Only have 4 general purpose timers, and we use last one as hpt */
BUG_ON(cpu > 2);
+ sprintf(name, "bcm1480-counter %d", cpu);
+ cd->name = name;
+ cd->features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_MODE_ONESHOT;
+ clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(1, cd);
+ cd->rating = 200;
+ cd->irq = irq;
+ cd->cpumask = cpumask_of_cpu(cpu);
+ cd->set_next_event = sibyte_next_event;
+ cd->set_mode = sibyte_set_mode;
+ clockevents_register_device(cd);
+
sb1250_mask_irq(cpu, irq);
/* Map the timer interrupt to ip[4] of this cpu */
@@ -236,23 +161,11 @@ static void __init sb1250_clockevent_init(void)
sb1250_unmask_irq(cpu, irq);
sb1250_steal_irq(irq);
- /*
- * This interrupt is "special" in that it doesn't use the request_irq
- * way to hook the irq line. The timer interrupt is initialized early
- * enough to make this a major pain, and it's also firing enough to
- * warrant a bit of special case code. sb1250_timer_interrupt is
- * called directly from irq_handler.S when IP[4] is set during an
- * interrupt
- */
+ action->handler = sibyte_counter_handler;
+ action->flags = IRQF_DISABLED | IRQF_PERCPU;
+ action->name = name;
+ action->dev_id = cd;
setup_irq(irq, &sibyte_irqaction);
-
- clockevents_register_device(cd);
-}
-
-void __init plat_time_init(void)
-{
- sb1250_clocksource_init();
- sb1250_clockevent_init();
}
/*
@@ -267,3 +180,36 @@ static cycle_t sb1250_hpt_read(void)
return SB1250_HPT_VALUE - count;
}
+
+struct clocksource bcm1250_clocksource = {
+ .name = "MIPS",
+ .rating = 200,
+ .read = sb1250_hpt_read,
+ .mask = CLOCKSOURCE_MASK(23),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init sb1250_clocksource_init(void)
+{
+ struct clocksource *cs = &bcm1250_clocksource;
+
+ /* Setup hpt using timer #3 but do not enable irq for it */
+ __raw_writeq(0,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_CFG)));
+ __raw_writeq(SB1250_HPT_VALUE,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_INIT)));
+ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS,
+ IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
+ R_SCD_TIMER_CFG)));
+
+ clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
+ clocksource_register(cs);
+}
+
+void __init plat_time_init(void)
+{
+ sb1250_clocksource_init();
+ sb1250_clockevent_init();
+}
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index 8b3ef0e4cd5..080c966263b 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -69,31 +69,6 @@ const char *get_system_type(void)
return "SiByte " SIBYTE_BOARD_NAME;
}
-void __init plat_time_init(void)
-{
-#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
- /* Setup HPT */
- sb1250_hpt_setup();
-#endif
-}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
- /*
- * we don't set up irqaction, because we will deliver timer
- * interrupts through low-level (direct) meachanism.
- */
-
- /* We only need to setup the generic timer */
-#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
- bcm1480_time_init();
-#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
- sb1250_time_init();
-#else
-#error invalid SiByte board configuration
-#endif
-}
-
int swarm_be_handler(struct pt_regs *regs, int is_fixup)
{
if (!is_fixup && (regs->cp0_cause & 4)) {
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index 39bb15f1f2a..4df070f2ff5 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -246,7 +246,7 @@ static void pcimt_hwint1(void)
/*
* Note: ASIC PCI's builtin interrupt achknowledge feature is
* broken. Using it may result in loss of some or all i8259
- * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
+ * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
*/
irq = i8259_irq();
if (unlikely(irq < 0))
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index b80877349d3..0910b35cb71 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -121,15 +121,6 @@ void __init plat_time_init(void)
setup_pit_timer();
}
-/*
- * R4k counter based timer interrupt. Works on RM200-225 and possibly
- * others but not on RM400
- */
-static void __init sni_cpu_timer_setup(struct irqaction *irq)
-{
- setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq);
-}
-
void __init plat_timer_setup(struct irqaction *irq)
{
switch (sni_brd_type) {
@@ -139,15 +130,6 @@ void __init plat_timer_setup(struct irqaction *irq)
case SNI_BRD_MINITOWER:
sni_a20r_timer_setup(irq);
break;
-
- case SNI_BRD_PCI_TOWER:
- case SNI_BRD_RM200:
- case SNI_BRD_PCI_MTOWER:
- case SNI_BRD_PCI_DESKTOP:
- case SNI_BRD_PCI_TOWER_CPLUS:
- case SNI_BRD_PCI_MTOWER_CPLUS:
- sni_cpu_timer_setup(irq);
- break;
}
}
diff --git a/arch/mips/tx4927/common/tx4927_setup.c b/arch/mips/tx4927/common/tx4927_setup.c
index 8ce0989671d..36c5f200eb3 100644
--- a/arch/mips/tx4927/common/tx4927_setup.c
+++ b/arch/mips/tx4927/common/tx4927_setup.c
@@ -72,22 +72,6 @@ void __init plat_time_init(void)
#endif
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(TX4927_IRQ_CPU_TIMER, irq);
-
-#ifdef CONFIG_TOSHIBA_RBTX4927
- {
- extern void toshiba_rbtx4927_timer_setup(struct irqaction
- *irq);
- toshiba_rbtx4927_timer_setup(irq);
- }
-#endif
-
- return;
-}
-
-
#ifdef DEBUG
void print_cp0(char *key, int num, char *name, u32 val)
{
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index b97102a1c63..c7470fba618 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -94,7 +94,6 @@
#define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 )
#define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 )
#define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 )
-#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 )
#define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 )
#define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 )
#define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 )
@@ -108,7 +107,6 @@ static const u32 toshiba_rbtx4927_setup_debug_flag =
(TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO |
TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR |
TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP |
- TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP
| TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 |
TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66);
#endif
@@ -947,14 +945,6 @@ toshiba_rbtx4927_time_init(void)
}
-void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq)
-{
- TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
- "-\n");
- TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP,
- "+\n");
-}
-
static int __init toshiba_rbtx4927_rtc_init(void)
{
static struct resource __initdata res = {
diff --git a/arch/mips/tx4938/common/setup.c b/arch/mips/tx4938/common/setup.c
index ab408226755..3ba4101d141 100644
--- a/arch/mips/tx4938/common/setup.c
+++ b/arch/mips/tx4938/common/setup.c
@@ -24,7 +24,7 @@
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/irq.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/bootinfo.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -43,8 +43,3 @@ plat_mem_setup(void)
{
toshiba_rbtx4938_setup();
}
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(TX4938_IRQ_CPU_TIMER, irq);
-}
diff --git a/arch/mips/vr41xx/common/init.c b/arch/mips/vr41xx/common/init.c
index 407cec203b2..8d760df686c 100644
--- a/arch/mips/vr41xx/common/init.c
+++ b/arch/mips/vr41xx/common/init.c
@@ -48,11 +48,6 @@ void __init plat_time_init(void)
mips_hpt_frequency = tclock / 4;
}
-void __init plat_timer_setup(struct irqaction *irq)
-{
- setup_irq(TIMER_IRQ, irq);
-}
-
void __init plat_mem_setup(void)
{
vr41xx_calculate_clock_frequency();
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 3d73545e8c4..b8ef1787a19 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -267,7 +267,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/parisc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/parisc/Kconfig.debug"
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index f3d0d7c7097..ae4a9b3d4fd 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -19,26 +19,27 @@
NM = sh $(srctree)/arch/parisc/nm
CHECKFLAGS += -D__hppa__=1
+MACHINE := $(shell uname -m)
+ifeq ($(MACHINE),parisc*)
+NATIVE := 1
+endif
+
ifdef CONFIG_64BIT
-CROSS_COMPILE := $(shell if [ -x /usr/bin/hppa64-linux-gnu-gcc ]; then \
- echo hppa64-linux-gnu-; else echo hppa64-linux-; fi)
UTS_MACHINE := parisc64
CHECKFLAGS += -D__LP64__=1 -m64
-else
-MACHINE := $(subst 64,,$(shell uname -m))
-ifneq ($(MACHINE),parisc)
-CROSS_COMPILE := hppa-linux-
-endif
+WIDTH := 64
+CROSS_COMPILE := hppa64-linux-gnu-
+else # 32-bit
+WIDTH :=
endif
-FINAL_LD=$(CROSS_COMPILE)ld --warn-common --warn-section-align
+# attempt to help out folks who are cross-compiling
+ifeq ($(NATIVE),1)
+CROSS_COMPILE := hppa$(WIDTH)-linux-
+endif
OBJCOPY_FLAGS =-O binary -R .note -R .comment -S
-ifneq ($(call cc-ifversion, -lt, 0303, "bad"),)
-$(error Sorry, GCC v3.3 or above is required.)
-endif
-
cflags-y := -pipe
# These flags should be implied by an hppa-linux configuration, but they
@@ -69,7 +70,7 @@ kernel-y := mm/ kernel/ math-emu/ kernel/init_task.o
kernel-$(CONFIG_HPUX) += hpux/
core-y += $(addprefix arch/parisc/, $(kernel-y))
-libs-y += arch/parisc/lib/ `$(CC) -print-libgcc-file-name`
+libs-y += arch/parisc/lib/
drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/
@@ -77,27 +78,27 @@ PALO := $(shell if which palo; then : ; \
elif [ -x /sbin/palo ]; then echo /sbin/palo; \
fi)
+PALOCONF := $(shell if [ -f $(src)/palo.conf ]; then echo $(src)/palo.conf; \
+ else echo $(obj)/palo.conf; \
+ fi)
+
palo: vmlinux
- @if [ -x $PALO ]; then \
+ @if test ! -x "$(PALO)"; then \
echo 'ERROR: Please install palo first (apt-get install palo)';\
echo 'or build it from source and install it somewhere in your $$PATH';\
false; \
fi
- @if [ ! -f ./palo.conf ]; then \
- cp arch/parisc/defpalo.conf palo.conf; \
- echo 'A generic palo config file (./palo.conf) has been created for you.'; \
+ @if test ! -f "$(PALOCONF)"; then \
+ cp $(src)/arch/parisc/defpalo.conf $(obj)/palo.conf; \
+ echo 'A generic palo config file ($(obj)/palo.conf) has been created for you.'; \
echo 'You should check it and re-run "make palo".'; \
echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \
false; \
fi
- $(PALO) -f ./palo.conf
-
-oldpalo: vmlinux
- export TOPDIR=`pwd`; \
- unset STRIP LDFLAGS CPP CPPFLAGS AFLAGS CFLAGS CC LD; cd ../palo && make lifimage
+ $(PALO) -f $(PALOCONF)
-# Shorthands for known targets not supported by parisc, use palo as default
-Image zImage bzImage: palo
+# Shorthands for known targets not supported by parisc, use vmlinux as default
+Image zImage bzImage: vmlinux
kernel_install: vmlinux
sh $(src)/arch/parisc/install.sh \
@@ -116,3 +117,12 @@ define archhelp
@echo ' (distribution) /sbin/installkernel or'
@echo ' copy to $$(INSTALL_PATH)'
endef
+
+# we require gcc 3.3 or above to compile the kernel
+archprepare: checkbin
+checkbin:
+ @if test "$(call cc-version)" -lt "0303"; then \
+ echo -n "Sorry, GCC v3.3 or above is required to build " ; \
+ echo "the kernel." ; \
+ false ; \
+ fi
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
index 41fd0696bbe..9fc96e72716 100644
--- a/arch/parisc/configs/712_defconfig
+++ b/arch/parisc/configs/712_defconfig
@@ -1,39 +1,51 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 19:59:51 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:00:07 2007
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -91,6 +101,9 @@ CONFIG_PA7100LC=y
# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
# CONFIG_SMP is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
# CONFIG_PREEMPT_NONE is not set
@@ -98,6 +111,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SELECT_MEMORY_MODEL=y
@@ -108,6 +122,9 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
# CONFIG_HPUX is not set
#
@@ -120,6 +137,7 @@ CONFIG_GSC_LASI=y
# CONFIG_GSC_WAX is not set
# CONFIG_EISA is not set
# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
#
# PCCARD (PCMCIA/CardBus) support
@@ -127,14 +145,11 @@ CONFIG_GSC_LASI=y
# CONFIG_PCCARD is not set
#
-# PCI Hotplug Support
-#
-
-#
# PA-RISC specific drivers
#
CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
CONFIG_PDC_STABLE=y
#
@@ -151,13 +166,15 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -174,17 +191,23 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IP_VS is not set
# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
@@ -192,37 +215,18 @@ CONFIG_NETFILTER=y
# Core Netfilter Configuration
#
# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
#
# IP: Netfilter Configuration
#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -234,7 +238,6 @@ CONFIG_LLC2=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -250,7 +253,17 @@ CONFIG_NET_PKTGEN=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -259,39 +272,24 @@ CONFIG_NET_PKTGEN=m
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=m
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_NOT_PC=y
CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
@@ -300,13 +298,11 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
CONFIG_ATA_OVER_ETH=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
# CONFIG_IDE is not set
#
@@ -314,6 +310,9 @@ CONFIG_ATA_OVER_ETH=m
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -333,104 +332,61 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
CONFIG_SCSI_LASI700=y
CONFIG_53C700_LE_ON_BE=y
# CONFIG_SCSI_ZALON is not set
CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_RAID1=m
# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-
-#
-# PHY device support
-#
+# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
CONFIG_LASI_82596=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
# CONFIG_NET_POCKET is not set
+CONFIG_NETDEV_1000=y
+CONFIG_NETDEV_10000=y
#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ATMEL is not set
-# CONFIG_HOSTAP is not set
-
-#
-# Wan interfaces
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
@@ -442,26 +398,22 @@ CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -486,14 +438,22 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_HIL_OLD is not set
CONFIG_KEYBOARD_HIL=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_VSXXXAA is not set
CONFIG_MOUSE_HIL=m
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -516,6 +476,7 @@ CONFIG_SERIO_LIBPS2=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -523,6 +484,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
CONFIG_SERIAL_8250_NR_UARTS=17
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
@@ -545,36 +507,15 @@ CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
CONFIG_PPDEV=m
# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
# CONFIG_I2C is not set
#
@@ -582,46 +523,59 @@ CONFIG_MAX_RAW_DEVS=256
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
-# Misc devices
+# Sonics Silicon Backplane
#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
CONFIG_FB_STI=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_VIRTUAL is not set
@@ -633,6 +587,7 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=128
CONFIG_DUMMY_CONSOLE_ROWS=48
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_STI_CONSOLE=y
CONFIG_FONTS=y
@@ -646,16 +601,11 @@ CONFIG_FONT_8x16=y
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -673,9 +623,11 @@ CONFIG_SND_SEQUENCER=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -685,8 +637,10 @@ CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
#
# GSC devices
@@ -694,15 +648,25 @@ CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_HARMONY=y
#
-# Open Sound System
+# System on Chip audio support
#
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SND_SOC is not set
#
-# USB support
+# SoC Audio support for SuperH
#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+CONFIG_USB_SUPPORT=y
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -712,19 +676,28 @@ CONFIG_SND_HARMONY=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
#
-# CONFIG_MMC is not set
#
-# InfiniBand support
+# DMA Devices
#
+# CONFIG_AUXDISPLAY is not set
#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# Userspace I/O
#
+# CONFIG_UIO is not set
#
# File systems
@@ -734,6 +707,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
@@ -744,15 +718,16 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -783,11 +758,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -795,6 +771,7 @@ CONFIG_RAMFS=y
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -806,6 +783,8 @@ CONFIG_RAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
CONFIG_UFS_FS=m
+# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
#
# Network File Systems
@@ -827,6 +806,7 @@ CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
CONFIG_SMB_FS=m
@@ -834,12 +814,13 @@ CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -892,6 +873,11 @@ CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -901,21 +887,32 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_RODATA=y
#
@@ -924,12 +921,13 @@ CONFIG_DEBUG_RODATA=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
@@ -938,9 +936,18 @@ CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_GF128MUL is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
@@ -949,21 +956,28 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
index f3b812f0459..ea071218a3e 100644
--- a/arch/parisc/configs/a500_defconfig
+++ b/arch/parisc/configs/a500_defconfig
@@ -1,73 +1,98 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.14-rc5-pa1
-# Fri Oct 21 23:04:54 2005
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:12:44 2007
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_TIME_LOW_RES=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
# CONFIG_CPUSETS is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
+CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
#
# Processor type and features
@@ -80,11 +105,23 @@ CONFIG_PA8X00=y
CONFIG_PA20=y
CONFIG_PREFETCH=y
CONFIG_64BIT=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_NODES_SHIFT=3
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_PREEMPT_BKL=y
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SELECT_MEMORY_MODEL=y
@@ -95,7 +132,10 @@ CONFIG_DISCONTIGMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_NEED_MULTIPLE_NODES=y
# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_PREEMPT is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
CONFIG_COMPAT=y
CONFIG_NR_CPUS=8
@@ -104,7 +144,7 @@ CONFIG_NR_CPUS=8
#
# CONFIG_GSC is not set
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
@@ -124,13 +164,14 @@ CONFIG_CARDBUS=y
# PC-card bridges
#
CONFIG_YENTA=m
+CONFIG_YENTA_O2=y
+CONFIG_YENTA_RICOH=y
+CONFIG_YENTA_TI=y
+CONFIG_YENTA_ENE_TUNE=y
+CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=m
CONFIG_I82092=m
CONFIG_PCCARD_NONSTATIC=m
-
-#
-# PCI Hotplug Support
-#
# CONFIG_HOTPLUG_PCI is not set
#
@@ -139,6 +180,7 @@ CONFIG_PCCARD_NONSTATIC=m
# CONFIG_SUPERIO is not set
# CONFIG_CHASSIS_LCD_LED is not set
CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
CONFIG_PDC_STABLE=y
#
@@ -160,7 +202,10 @@ CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -177,97 +222,97 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IP_VS is not set
CONFIG_IPV6=m
# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
#
# IP: Netfilter Configuration
#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-CONFIG_IP_NF_CONNTRACK_MARK=y
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-CONFIG_IP_NF_CT_PROTO_SCTP=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
CONFIG_IP_NF_MATCH_TOS=m
CONFIG_IP_NF_MATCH_RECENT=m
CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
+# CONFIG_IP_NF_MATCH_AH is not set
CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
CONFIG_IP_NF_MATCH_OWNER=m
# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-CONFIG_IP_NF_MATCH_SCTP=m
-# CONFIG_IP_NF_MATCH_DCCP is not set
-CONFIG_IP_NF_MATCH_COMMENT=m
-CONFIG_IP_NF_MATCH_CONNMARK=m
-CONFIG_IP_NF_MATCH_HASHLIMIT=m
-# CONFIG_IP_NF_MATCH_STRING is not set
CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_TARGET_NFQUEUE is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_TARGET_NETMAP=m
-CONFIG_IP_NF_TARGET_SAME=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_NAT_AMANDA=m
CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_TOS=m
CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_CLASSIFY=m
# CONFIG_IP_NF_TARGET_TTL is not set
-CONFIG_IP_NF_TARGET_CONNMARK=m
-CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_TARGET_NOTRACK=m
CONFIG_IP_NF_ARPTABLES=m
CONFIG_IP_NF_ARPFILTER=m
CONFIG_IP_NF_ARP_MANGLE=m
@@ -277,48 +322,38 @@ CONFIG_IP_NF_ARP_MANGLE=m
#
# CONFIG_IP6_NF_QUEUE is not set
CONFIG_IP6_NF_IPTABLES=m
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-CONFIG_IP6_NF_MATCH_MAC=m
CONFIG_IP6_NF_MATCH_RT=m
CONFIG_IP6_NF_MATCH_OPTS=m
CONFIG_IP6_NF_MATCH_FRAG=m
CONFIG_IP6_NF_MATCH_HL=m
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
+# CONFIG_IP6_NF_MATCH_AH is not set
+# CONFIG_IP6_NF_MATCH_MH is not set
# CONFIG_IP6_NF_MATCH_EUI64 is not set
CONFIG_IP6_NF_FILTER=m
CONFIG_IP6_NF_TARGET_LOG=m
CONFIG_IP6_NF_TARGET_REJECT=m
-# CONFIG_IP6_NF_TARGET_NFQUEUE is not set
CONFIG_IP6_NF_MANGLE=m
-# CONFIG_IP6_NF_TARGET_MARK is not set
# CONFIG_IP6_NF_TARGET_HL is not set
CONFIG_IP6_NF_RAW=m
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
CONFIG_IP_DCCP=m
CONFIG_INET_DCCP_DIAG=m
+CONFIG_IP_DCCP_ACKVEC=y
#
# DCCP CCIDs Configuration (EXPERIMENTAL)
#
+CONFIG_IP_DCCP_CCID2=m
+# CONFIG_IP_DCCP_CCID2_DEBUG is not set
# CONFIG_IP_DCCP_CCID3 is not set
#
# DCCP Kernel Hacking
#
# CONFIG_IP_DCCP_DEBUG is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
@@ -329,11 +364,13 @@ CONFIG_LLC2=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
+
+#
+# QoS and/or fair queueing
+#
# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
#
# Network testing
@@ -342,7 +379,17 @@ CONFIG_NET_PKTGEN=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -351,34 +398,17 @@ CONFIG_NET_PKTGEN=m
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -391,21 +421,14 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
# CONFIG_IDE is not set
#
@@ -413,6 +436,9 @@ CONFIG_IOSCHED_CFQ=y
#
CONFIG_RAID_ATTRS=m
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+CONFIG_SCSI_NETLINK=y
CONFIG_SCSI_PROC_FS=y
#
@@ -432,18 +458,18 @@ CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
CONFIG_SCSI_FC_ATTRS=m
CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SAS_ATTRS=m
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -451,59 +477,40 @@ CONFIG_SCSI_SAS_ATTRS=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-CONFIG_SCSI_QLOGIC_FC=m
-# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set
+CONFIG_SCSI_SYM53C8XX_MMIO=y
CONFIG_SCSI_QLOGIC_1280=m
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-CONFIG_SCSI_QLA2300=m
-CONFIG_SCSI_QLA2322=m
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA24XX is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
CONFIG_SCSI_DEBUG=m
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_QLOGIC=m
-CONFIG_PCMCIA_SYM53C500=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -517,39 +524,25 @@ CONFIG_FUSION_FC=m
# CONFIG_FUSION_SAS is not set
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_HAPPYMEAL is not set
@@ -558,10 +551,6 @@ CONFIG_MII=m
CONFIG_NET_VENDOR_3COM=y
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
-
-#
-# Tulip family network device support
-#
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=y
@@ -573,15 +562,18 @@ CONFIG_TULIP_MMIO=y
# CONFIG_DM9102 is not set
# CONFIG_ULI526X is not set
CONFIG_PCMCIA_XIRCOM=m
-# CONFIG_PCMCIA_XIRTULIP is not set
CONFIG_HP100=m
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NET_PCI=y
CONFIG_PCNET32=m
+# CONFIG_PCNET32_NAPI is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=m
# CONFIG_FEALNX is not set
@@ -593,84 +585,46 @@ CONFIG_E100=m
# CONFIG_EPIC100 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
CONFIG_ACENIC=m
CONFIG_ACENIC_OMIT_TIGON_I=y
# CONFIG_DL2K is not set
CONFIG_E1000=m
CONFIG_E1000_NAPI=y
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=m
# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-CONFIG_PLX_HERMES=m
-CONFIG_TMD_HERMES=m
-# CONFIG_NORTEL_HERMES is not set
-CONFIG_PCI_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-# CONFIG_PCMCIA_SPECTRUM is not set
-CONFIG_AIRO_CS=m
-CONFIG_PCMCIA_WL3501=m
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
CONFIG_NET_PCMCIA=y
CONFIG_PCMCIA_3C589=m
CONFIG_PCMCIA_3C574=m
@@ -680,10 +634,6 @@ CONFIG_PCMCIA_3C574=m
CONFIG_PCMCIA_SMC91C92=m
CONFIG_PCMCIA_XIRC2PS=m
# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -694,28 +644,25 @@ CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -732,6 +679,7 @@ CONFIG_INPUT=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -747,6 +695,7 @@ CONFIG_INPUT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -754,8 +703,10 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_CS=m
CONFIG_SERIAL_8250_NR_UARTS=17
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y
@@ -765,83 +716,73 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_MUX is not set
CONFIG_PDC_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+CONFIG_AGP=y
+CONFIG_AGP_PARISC=y
# CONFIG_DRM is not set
#
# PCMCIA character devices
#
# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
-# Dallas's 1-wire bus
+# SPI support
#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
-# Misc devices
+# Sonics Silicon Backplane
#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
#
@@ -856,34 +797,47 @@ CONFIG_DUMMY_CONSOLE_ROWS=64
# Sound
#
# CONFIG_SOUND is not set
-
-#
-# USB support
-#
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
#
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
#
-# InfiniBand support
+# DMA Clients
#
-# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# DMA Devices
#
#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -891,6 +845,7 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
@@ -901,14 +856,16 @@ CONFIG_JFS_FS=m
# CONFIG_JFS_STATISTICS is not set
CONFIG_FS_POSIX_ACL=y
CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -939,18 +896,20 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
+# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -963,6 +922,7 @@ CONFIG_RAMFS=y
# CONFIG_SYSV_FS is not set
CONFIG_UFS_FS=m
# CONFIG_UFS_FS_WRITE is not set
+# CONFIG_UFS_DEBUG is not set
#
# Network File Systems
@@ -983,6 +943,7 @@ CONFIG_EXPORTFS=m
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=m
CONFIG_SUNRPC_GSS=m
+# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=m
CONFIG_RPCSEC_GSS_SPKM3=m
CONFIG_SMB_FS=m
@@ -990,12 +951,13 @@ CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1048,6 +1010,11 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_UTF8=m
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -1057,19 +1024,34 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
-CONFIG_DEBUG_KERNEL=y
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
-# CONFIG_DEBUG_FS is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_RWLOCK is not set
+# CONFIG_DEBUG_RODATA is not set
#
# Security options
@@ -1077,12 +1059,13 @@ CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
@@ -1091,32 +1074,47 @@ CONFIG_CRYPTO_SHA1=m
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=m
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
+CONFIG_CRYPTO_CAST5=m
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_MICHAEL_MIC is not set
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
index 35093612ad2..1bf22c9a461 100644
--- a/arch/parisc/configs/b180_defconfig
+++ b/arch/parisc/configs/b180_defconfig
@@ -1,38 +1,47 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc1-pa0
-# Tue Jan 17 08:21:01 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:16:46 2007
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
# CONFIG_EXPERIMENTAL is not set
-CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -42,30 +51,27 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
# CONFIG_KMOD is not set
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
#
# IO Schedulers
@@ -89,16 +95,26 @@ CONFIG_PA7100LC=y
# CONFIG_PA7300LC is not set
# CONFIG_PA8X00 is not set
CONFIG_PA11=y
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
# CONFIG_SMP is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PREEMPT is not set
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
# CONFIG_HPUX is not set
#
@@ -113,7 +129,7 @@ CONFIG_EISA=y
CONFIG_EISA_NAMES=y
CONFIG_ISA=y
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_GSC_DINO=y
# CONFIG_PCI_LBA is not set
@@ -124,14 +140,11 @@ CONFIG_GSC_DINO=y
# CONFIG_PCCARD is not set
#
-# PCI Hotplug Support
-#
-
-#
# PA-RISC specific drivers
#
CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
CONFIG_PDC_STABLE=y
#
@@ -151,6 +164,8 @@ CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -167,18 +182,32 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
# CONFIG_INET6_IPCOMP is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_BRIDGE is not set
# CONFIG_VLAN_8021Q is not set
@@ -199,7 +228,14 @@ CONFIG_IPV6=y
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
#
# Device Drivers
@@ -208,39 +244,24 @@ CONFIG_IPV6=y
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
# CONFIG_PARPORT_SERIAL is not set
-CONFIG_PARPORT_NOT_PC=y
CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
+CONFIG_PARPORT_NOT_PC=y
# CONFIG_PNP is not set
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
@@ -251,15 +272,13 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_CDROM_PKTCDVD=m
CONFIG_CDROM_PKTCDVD_BUFFERS=8
-# CONFIG_CDROM_PKTCDVD_WCACHE is not set
CONFIG_ATA_OVER_ETH=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
# CONFIG_IDE is not set
#
@@ -267,6 +286,8 @@ CONFIG_ATA_OVER_ETH=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -286,18 +307,17 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
@@ -308,12 +328,14 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
@@ -327,23 +349,22 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_NCR53C406A is not set
CONFIG_SCSI_LASI700=y
CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
CONFIG_SCSI_ZALON=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
CONFIG_SCSI_NCR53C8XX_SYNC=40
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_SYM53C416 is not set
@@ -351,22 +372,14 @@ CONFIG_SCSI_NCR53C8XX_SYNC=40
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
# CONFIG_BLK_DEV_DM is not set
@@ -382,35 +395,21 @@ CONFIG_MD_RAID6=y
#
# IEEE 1394 (FireWire) support
#
-# CONFIG_IEEE1394 is not set
#
-# I2O device support
+# An alternative FireWire stack is available with EXPERIMENTAL=y
#
+# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
CONFIG_LASI_82596=y
@@ -420,10 +419,6 @@ CONFIG_LASI_82596=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
CONFIG_NET_TULIP=y
CONFIG_TULIP=y
# CONFIG_TULIP_MMIO is not set
@@ -435,62 +430,47 @@ CONFIG_TULIP=y
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
# CONFIG_SK98LIN is not set
+# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
+# Wireless LAN
#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
@@ -501,24 +481,19 @@ CONFIG_PPP=y
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=y
# CONFIG_NET_FC is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -543,19 +518,31 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_HIL_OLD is not set
CONFIG_KEYBOARD_HIL=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set
# CONFIG_MOUSE_VSXXXAA is not set
CONFIG_MOUSE_HIL=y
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_POWERMATE is not set
# CONFIG_INPUT_UINPUT is not set
# CONFIG_HP_SDC_RTC is not set
@@ -579,6 +566,7 @@ CONFIG_SERIO_LIBPS2=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -586,17 +574,20 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=13
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
# CONFIG_SERIAL_8250_FOURPORT is not set
# CONFIG_SERIAL_8250_ACCENT is not set
# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
# CONFIG_SERIAL_8250_HUB6 is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
#
# Non-8250 serial port support
@@ -605,6 +596,7 @@ CONFIG_SERIAL_MUX=y
CONFIG_SERIAL_MUX_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
@@ -612,35 +604,18 @@ CONFIG_PRINTER=y
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
@@ -648,46 +623,59 @@ CONFIG_GEN_RTC=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
-# Misc devices
+# Sonics Silicon Backplane
#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
@@ -698,16 +686,18 @@ CONFIG_FB_STI=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -717,21 +707,17 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_STI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
CONFIG_LOGO_LINUX_MONO=y
CONFIG_LOGO_LINUX_VGA16=y
CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -749,8 +735,11 @@ CONFIG_SND_SEQUENCER=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -760,13 +749,16 @@ CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
#
# PCI devices
#
# CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -778,6 +770,18 @@ CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -791,11 +795,13 @@ CONFIG_SND_SUPPORT_OLD_API=y
# CONFIG_SND_ICE1712 is not set
# CONFIG_SND_ICE1724 is not set
# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_INTEL8X0M is not set
# CONFIG_SND_KORG1212 is not set
# CONFIG_SND_MAESTRO3 is not set
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
@@ -812,15 +818,25 @@ CONFIG_SND_SUPPORT_OLD_API=y
CONFIG_SND_HARMONY=y
#
-# Open Sound System
+# System on Chip audio support
#
-# CONFIG_SOUND_PRIME is not set
+# CONFIG_SND_SOC is not set
#
-# USB support
+# SoC Audio support for SuperH
+#
+
+#
+# Open Sound System
#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
@@ -831,20 +847,29 @@ CONFIG_USB_ARCH_HAS_OHCI=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
#
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
#
-# InfiniBand support
+# DMA Clients
#
-# CONFIG_INFINIBAND is not set
#
-# SN Devices
+# DMA Devices
#
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
#
# File systems
@@ -860,9 +885,11 @@ CONFIG_JBD=y
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -889,11 +916,12 @@ CONFIG_JOLIET=y
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
#
# Miscellaneous filesystems
@@ -912,6 +940,7 @@ CONFIG_RAMFS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_DIRECTIO is not set
CONFIG_NFSD=y
CONFIG_NFSD_V3=y
# CONFIG_NFSD_V3_ACL is not set
@@ -982,22 +1011,32 @@ CONFIG_NLS_UTF8=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_IOREMAP is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_RODATA is not set
#
@@ -1007,13 +1046,10 @@ CONFIG_FORCED_INLINING=y
CONFIG_SECURITY=y
# CONFIG_SECURITY_NETWORK is not set
CONFIG_SECURITY_CAPABILITIES=y
-# CONFIG_SECURITY_SECLVL is not set
-# CONFIG_SECURITY_SELINUX is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_MD4 is not set
@@ -1023,7 +1059,12 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1034,19 +1075,26 @@ CONFIG_CRYPTO=y
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_HW=y
#
# Library routines
#
+CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
index eb2f9a3d515..c6def3c1d20 100644
--- a/arch/parisc/configs/c3000_defconfig
+++ b/arch/parisc/configs/c3000_defconfig
@@ -1,39 +1,50 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa6
-# Sun Mar 26 20:03:29 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 21:24:00 2007
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +54,29 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -93,6 +102,9 @@ CONFIG_PA8X00=y
CONFIG_PA20=y
CONFIG_PREFETCH=y
# CONFIG_64BIT is not set
+CONFIG_PARISC_PAGE_SIZE_4KB=y
+# CONFIG_PARISC_PAGE_SIZE_16KB is not set
+# CONFIG_PARISC_PAGE_SIZE_64KB is not set
# CONFIG_SMP is not set
CONFIG_ARCH_FLATMEM_ENABLE=y
# CONFIG_PREEMPT_NONE is not set
@@ -100,6 +112,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SELECT_MEMORY_MODEL=y
@@ -110,6 +123,9 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
# CONFIG_HPUX is not set
#
@@ -117,7 +133,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
#
# CONFIG_GSC is not set
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_PCI_LBA=y
CONFIG_IOSAPIC=y
@@ -127,10 +143,6 @@ CONFIG_IOMMU_SBA=y
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
-
-#
-# PCI Hotplug Support
-#
# CONFIG_HOTPLUG_PCI is not set
#
@@ -139,6 +151,7 @@ CONFIG_IOMMU_SBA=y
CONFIG_SUPERIO=y
CONFIG_CHASSIS_LCD_LED=y
# CONFIG_PDC_CHASSIS is not set
+CONFIG_PDC_CHASSIS_WARN=y
CONFIG_PDC_STABLE=y
#
@@ -155,13 +168,15 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -178,22 +193,36 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
# CONFIG_INET_DIAG is not set
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-
-#
-# IP: Virtual Server Configuration
-#
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
# CONFIG_IP_VS is not set
CONFIG_IPV6=m
# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
# CONFIG_INET6_AH is not set
# CONFIG_INET6_ESP is not set
CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
CONFIG_NETFILTER=y
CONFIG_NETFILTER_DEBUG=y
@@ -201,42 +230,24 @@ CONFIG_NETFILTER_DEBUG=y
# Core Netfilter Configuration
#
# CONFIG_NETFILTER_NETLINK is not set
+# CONFIG_NF_CONNTRACK_ENABLED is not set
+# CONFIG_NF_CONNTRACK is not set
# CONFIG_NETFILTER_XTABLES is not set
#
# IP: Netfilter Configuration
#
-CONFIG_IP_NF_CONNTRACK=m
-# CONFIG_IP_NF_CT_ACCT is not set
-# CONFIG_IP_NF_CONNTRACK_MARK is not set
-# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
-# CONFIG_IP_NF_CT_PROTO_SCTP is not set
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_NETBIOS_NS is not set
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_AMANDA=m
-# CONFIG_IP_NF_PPTP is not set
CONFIG_IP_NF_QUEUE=m
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
#
# IPv6: Netfilter Configuration (EXPERIMENTAL)
#
# CONFIG_IP6_NF_QUEUE is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
+# CONFIG_IP6_NF_IPTABLES is not set
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -247,7 +258,6 @@ CONFIG_IP_NF_QUEUE=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -263,7 +273,17 @@ CONFIG_NET_PKTGEN=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -272,33 +292,17 @@ CONFIG_NET_PKTGEN=m
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
@@ -310,14 +314,15 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
CONFIG_IDE=y
+CONFIG_IDE_MAX_HWIFS=4
CONFIG_BLK_DEV_IDE=y
#
@@ -331,19 +336,26 @@ CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDEFLOPPY is not set
CONFIG_BLK_DEV_IDESCSI=y
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
@@ -354,8 +366,10 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -365,10 +379,10 @@ CONFIG_BLK_DEV_SIIMAGE=m
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -376,6 +390,9 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -395,18 +412,17 @@ CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
CONFIG_SCSI_ISCSI_ATTRS=m
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
@@ -415,66 +431,53 @@ CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-CONFIG_SCSI_ATA_PIIX=m
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-CONFIG_SCSI_SATA_PROMISE=m
-# CONFIG_SCSI_SATA_SX4 is not set
-CONFIG_SCSI_SATA_SIL=m
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-CONFIG_SCSI_SATA_VIA=m
-# CONFIG_SCSI_SATA_VITESSE is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
CONFIG_SCSI_DEBUG=m
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_RAID6 is not set
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=m
+# CONFIG_DM_DEBUG is not set
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
# CONFIG_DM_MULTIPATH_EMC is not set
+# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_DELAY is not set
#
# Fusion MPT device support
@@ -485,49 +488,31 @@ CONFIG_FUSION_SPI=m
# CONFIG_FUSION_SAS is not set
CONFIG_FUSION_MAX_SGE=128
CONFIG_FUSION_CTL=m
+# CONFIG_FUSION_LOGGING is not set
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNGEM is not set
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
CONFIG_NET_TULIP=y
CONFIG_DE2104X=m
CONFIG_TULIP=y
@@ -539,13 +524,16 @@ CONFIG_TULIP_MMIO=y
# CONFIG_DM9102 is not set
# CONFIG_ULI526X is not set
# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
CONFIG_E100=m
# CONFIG_FEALNX is not set
@@ -558,16 +546,15 @@ CONFIG_E100=m
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+# CONFIG_SC92031 is not set
+CONFIG_NETDEV_1000=y
CONFIG_ACENIC=m
# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
CONFIG_E1000=m
# CONFIG_E1000_NAPI is not set
# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -579,27 +566,36 @@ CONFIG_E1000=m
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=m
# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
+# Wireless LAN
#
-# CONFIG_NET_RADIO is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
-# Wan interfaces
+# USB Network Adapters
#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -612,27 +608,23 @@ CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
# CONFIG_PPP_MPPE is not set
CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -655,11 +647,14 @@ CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
CONFIG_INPUT_MOUSE=y
# CONFIG_MOUSE_PS2 is not set
# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -679,6 +674,7 @@ CONFIG_SERIO_LIBPS2=m
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -686,6 +682,7 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=13
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
@@ -704,38 +701,19 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
# CONFIG_DRM is not set
CONFIG_RAW_DRIVER=y
CONFIG_MAX_RAW_DEVS=256
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
@@ -743,46 +721,59 @@ CONFIG_MAX_RAW_DEVS=256
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
-# Misc devices
+# Sonics Silicon Backplane
#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
@@ -793,17 +784,20 @@ CONFIG_FB_STI=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -813,21 +807,17 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=160
CONFIG_DUMMY_CONSOLE_ROWS=64
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_STI_CONSOLE=y
# CONFIG_FONTS is not set
CONFIG_FONT_8x8=y
CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -845,9 +835,11 @@ CONFIG_SND_SEQUENCER=y
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
# CONFIG_SND_DYNAMIC_MINORS is not set
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
@@ -855,7 +847,6 @@ CONFIG_SND_SUPPORT_OLD_API=y
# Generic devices
#
CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
@@ -866,7 +857,7 @@ CONFIG_SND_AC97_BUS=y
# PCI devices
#
CONFIG_SND_AD1889=y
-# CONFIG_SND_AD1889_OPL3 is not set
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -879,6 +870,18 @@ CONFIG_SND_AD1889=y
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -898,6 +901,7 @@ CONFIG_SND_AD1889=y
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
@@ -907,22 +911,43 @@ CONFIG_SND_AD1889=y
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
#
-# USB support
+# USB Input Devices
#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
CONFIG_USB_DEBUG=y
@@ -930,7 +955,7 @@ CONFIG_USB_DEBUG=y
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
@@ -940,15 +965,16 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=m
@@ -970,54 +996,14 @@ CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_LIBUSUAL is not set
#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
# USB Imaging devices
#
CONFIG_USB_MDC800=m
CONFIG_USB_MICROTEK=m
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
# CONFIG_USB_MON is not set
#
@@ -1034,16 +1020,22 @@ CONFIG_USB_MICROTEK=m
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
CONFIG_USB_LEGOTOWER=m
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
#
@@ -1054,22 +1046,30 @@ CONFIG_USB_LEGOTOWER=m
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
#
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
#
-# InfiniBand support
+# DMA Clients
#
-# CONFIG_INFINIBAND is not set
#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Devices
#
#
+# Userspace I/O
+#
+# CONFIG_UIO is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -1077,21 +1077,23 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_XFS_FS=m
-CONFIG_XFS_EXPORT=y
# CONFIG_XFS_QUOTA is not set
# CONFIG_XFS_SECURITY is not set
# CONFIG_XFS_POSIX_ACL is not set
# CONFIG_XFS_RT is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
# CONFIG_AUTOFS_FS is not set
@@ -1121,11 +1123,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -1164,6 +1167,7 @@ CONFIG_LOCKD_V4=y
CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -1171,7 +1175,6 @@ CONFIG_SUNRPC=y
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1224,6 +1227,11 @@ CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_UTF8=m
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -1233,21 +1241,32 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_RODATA=y
#
@@ -1255,12 +1274,12 @@ CONFIG_DEBUG_RODATA=y
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_MANAGER=m
# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=m
@@ -1269,7 +1288,15 @@ CONFIG_CRYPTO_MD5=m
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_WP512 is not set
# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=m
# CONFIG_CRYPTO_TWOFISH is not set
# CONFIG_CRYPTO_SERPENT is not set
@@ -1280,21 +1307,28 @@ CONFIG_CRYPTO_BLOWFISH=m
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_MICHAEL_MIC is not set
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=m
CONFIG_ZLIB_DEFLATE=m
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig
index b38b58eb9dc..448a757b06c 100644
--- a/arch/parisc/defconfig
+++ b/arch/parisc/defconfig
@@ -1,39 +1,51 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-pa10
-# Sun Apr 2 15:26:38 2006
+# Linux kernel version: 2.6.23
+# Fri Oct 12 20:54:57 2007
#
CONFIG_PARISC=y
CONFIG_MMU=y
CONFIG_STACK_GROWSUP=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -43,31 +55,29 @@ CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
+CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
-
-#
-# Block layer
-#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
#
# IO Schedulers
@@ -101,6 +111,7 @@ CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=250
CONFIG_SELECT_MEMORY_MODEL=y
@@ -111,6 +122,9 @@ CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
# CONFIG_HPUX is not set
#
@@ -125,7 +139,7 @@ CONFIG_EISA=y
CONFIG_EISA_NAMES=y
# CONFIG_ISA is not set
CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCI_DEBUG is not set
CONFIG_GSC_DINO=y
CONFIG_PCI_LBA=y
@@ -154,10 +168,6 @@ CONFIG_YENTA_TOSHIBA=y
CONFIG_PD6729=y
CONFIG_I82092=y
CONFIG_PCCARD_NONSTATIC=y
-
-#
-# PCI Hotplug Support
-#
# CONFIG_HOTPLUG_PCI is not set
#
@@ -166,6 +176,7 @@ CONFIG_PCCARD_NONSTATIC=y
CONFIG_SUPERIO=y
CONFIG_CHASSIS_LCD_LED=y
CONFIG_PDC_CHASSIS=y
+CONFIG_PDC_CHASSIS_WARN=y
CONFIG_PDC_STABLE=y
#
@@ -182,13 +193,15 @@ CONFIG_NET=y
#
# Networking options
#
-# CONFIG_NETDEBUG is not set
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -205,33 +218,39 @@ CONFIG_IP_PNP_BOOTP=y
CONFIG_INET_AH=m
CONFIG_INET_ESP=m
# CONFIG_INET_IPCOMP is not set
-CONFIG_INET_TUNNEL=m
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=m
CONFIG_INET_TCP_DIAG=m
# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
CONFIG_INET6_AH=y
CONFIG_INET6_ESP=y
CONFIG_INET6_IPCOMP=y
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=y
CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
@@ -243,7 +262,6 @@ CONFIG_LLC2=m
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -259,7 +277,17 @@ CONFIG_LLC2=m
# CONFIG_HAMRADIO is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
#
# Device Drivers
@@ -268,41 +296,26 @@ CONFIG_LLC2=m
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
# CONFIG_STANDALONE is not set
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
CONFIG_FW_LOADER=y
# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=m
# CONFIG_PARPORT_SERIAL is not set
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
CONFIG_PARPORT_PC_PCMCIA=m
-CONFIG_PARPORT_NOT_PC=y
CONFIG_PARPORT_GSC=y
+# CONFIG_PARPORT_AX88796 is not set
CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
+CONFIG_PARPORT_NOT_PC=y
+CONFIG_BLK_DEV=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
@@ -317,13 +330,14 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y
@@ -334,24 +348,32 @@ CONFIG_BLK_DEV_IDE=y
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_DELKIN is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
CONFIG_BLK_DEV_IDESCSI=y
# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
#
# IDE chipset support/bugfixes
#
CONFIG_IDE_GENERIC=y
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
+CONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_BLK_DEV_GENERIC=y
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
+CONFIG_IDEDMA_ONLYDISK=y
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
@@ -362,8 +384,10 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8213 is not set
# CONFIG_BLK_DEV_IT821X is not set
CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
@@ -373,10 +397,10 @@ CONFIG_BLK_DEV_NS87415=y
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
# CONFIG_BLK_DEV_HD is not set
#
@@ -384,6 +408,9 @@ CONFIG_BLK_DEV_IDEDMA=y
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
CONFIG_SCSI_PROC_FS=y
#
@@ -403,18 +430,17 @@ CONFIG_CHR_DEV_SG=y
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
#
-# SCSI Transport Attributes
+# SCSI Transports
#
CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
@@ -424,11 +450,13 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
+# CONFIG_SCSI_HPTIOP is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -438,55 +466,45 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_IMM is not set
CONFIG_SCSI_LASI700=y
CONFIG_53C700_LE_ON_BE=y
+# CONFIG_SCSI_STEX is not set
CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
CONFIG_SCSI_ZALON=y
CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y
CONFIG_MD_RAID0=y
CONFIG_MD_RAID1=y
CONFIG_MD_RAID10=y
-CONFIG_MD_RAID5=y
-CONFIG_MD_RAID6=y
+# CONFIG_MD_RAID456 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_MD_FAULTY is not set
CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
# CONFIG_DM_CRYPT is not set
# CONFIG_DM_SNAPSHOT is not set
# CONFIG_DM_MIRROR is not set
# CONFIG_DM_ZERO is not set
# CONFIG_DM_MULTIPATH is not set
+# CONFIG_DM_DELAY is not set
#
# Fusion MPT device support
@@ -499,35 +517,20 @@ CONFIG_BLK_DEV_DM=y
#
# IEEE 1394 (FireWire) support
#
+# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
# CONFIG_I2O is not set
-
-#
-# Network device support
-#
CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
CONFIG_BONDING=m
+# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=m
-
-#
-# ARCnet devices
-#
+# CONFIG_VETH is not set
+# CONFIG_IP1000 is not set
# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
CONFIG_LASI_82596=y
@@ -536,10 +539,6 @@ CONFIG_LASI_82596=y
# CONFIG_CASSINI is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_NET_VENDOR_SMC is not set
-
-#
-# Tulip family network device support
-#
CONFIG_NET_TULIP=y
# CONFIG_DE2104X is not set
CONFIG_TULIP=y
@@ -554,6 +553,10 @@ CONFIG_TULIP=y
# CONFIG_PCMCIA_XIRTULIP is not set
# CONFIG_DEPCA is not set
# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_AMD8111_ETH is not set
@@ -561,7 +564,6 @@ CONFIG_NET_PCI=y
# CONFIG_AC3200 is not set
# CONFIG_B44 is not set
# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
# CONFIG_EEPRO100 is not set
# CONFIG_E100 is not set
# CONFIG_LNE390 is not set
@@ -577,15 +579,14 @@ CONFIG_NET_PCI=y
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_SC92031 is not set
# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
+CONFIG_NETDEV_1000=y
CONFIG_ACENIC=y
# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
@@ -597,64 +598,36 @@ CONFIG_ACENIC=y
# CONFIG_VIA_VELOCITY is not set
CONFIG_TIGON3=y
# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+# CONFIG_CHELSIO_T3 is not set
+# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
+# CONFIG_MYRI10GE is not set
+# CONFIG_NETXEN_NIC is not set
+# CONFIG_NIU is not set
+# CONFIG_MLX4_CORE is not set
+# CONFIG_TEHUTI is not set
# CONFIG_TR is not set
#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=y
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
+# Wireless LAN
#
-CONFIG_PCMCIA_HERMES=y
-CONFIG_PCMCIA_SPECTRUM=y
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-# CONFIG_HOSTAP is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
+# USB Network Adapters
#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET_MII is not set
+# CONFIG_USB_USBNET is not set
CONFIG_NET_PCMCIA=y
# CONFIG_PCMCIA_3C589 is not set
# CONFIG_PCMCIA_3C574 is not set
@@ -664,10 +637,6 @@ CONFIG_NET_PCMCIA=y
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -681,27 +650,23 @@ CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
# CONFIG_PPP_MPPE is not set
CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
+CONFIG_SLHC=m
# CONFIG_NET_FC is not set
# CONFIG_SHAPER is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
# CONFIG_PHONE is not set
#
# Input device support
#
CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
#
# Userland interfaces
@@ -726,14 +691,23 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y
# CONFIG_KEYBOARD_LKKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
# CONFIG_KEYBOARD_HIL_OLD is not set
CONFIG_KEYBOARD_HIL=y
CONFIG_INPUT_MOUSE=y
CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=y
+# CONFIG_MOUSE_APPLETOUCH is not set
# CONFIG_MOUSE_VSXXXAA is not set
CONFIG_MOUSE_HIL=y
# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set
@@ -757,6 +731,7 @@ CONFIG_SERIO_LIBPS2=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
@@ -764,6 +739,8 @@ CONFIG_HW_CONSOLE=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_GSC=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_CS=y
CONFIG_SERIAL_8250_NR_UARTS=17
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
@@ -788,25 +765,14 @@ CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
CONFIG_PPDEV=m
# CONFIG_TIPAR is not set
-
-#
-# IPMI
-#
# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
CONFIG_GEN_RTC=y
CONFIG_GEN_RTC_X=y
-# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
+# CONFIG_AGP is not set
# CONFIG_DRM is not set
#
@@ -816,16 +782,8 @@ CONFIG_GEN_RTC_X=y
# CONFIG_CARDMAN_4000 is not set
# CONFIG_CARDMAN_4040 is not set
# CONFIG_RAW_DRIVER is not set
-
-#
-# TPM devices
-#
# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
+CONFIG_DEVPORT=y
# CONFIG_I2C is not set
#
@@ -833,46 +791,59 @@ CONFIG_GEN_RTC_X=y
#
# CONFIG_SPI is not set
# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
#
-# Misc devices
+# Sonics Silicon Backplane
#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
#
-# Multimedia Capabilities Port drivers
+# Multifunction device drivers
#
+# CONFIG_MFD_SM501 is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
#
-# Digital Video Broadcasting Devices
+# Graphics support
#
-# CONFIG_DVB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
-# Graphics support
+# Display device support
#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_SYS_FOPS is not set
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y
+
+#
+# Frame buffer hardware drivers
+#
# CONFIG_FB_CIRRUS is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_CYBER2000 is not set
@@ -883,17 +854,20 @@ CONFIG_FB_STI=y
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
# CONFIG_FB_SAVAGE is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_KYRO is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
# CONFIG_FB_VIRTUAL is not set
#
@@ -903,6 +877,7 @@ CONFIG_DUMMY_CONSOLE=y
CONFIG_DUMMY_CONSOLE_COLUMNS=128
CONFIG_DUMMY_CONSOLE_ROWS=48
CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
CONFIG_STI_CONSOLE=y
CONFIG_FONTS=y
@@ -916,16 +891,11 @@ CONFIG_FONT_8x16=y
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_FONT_10x18 is not set
-
-#
-# Logo configuration
-#
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
# CONFIG_LOGO_LINUX_CLUT224 is not set
CONFIG_LOGO_PARISC_CLUT224=y
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Sound
@@ -938,35 +908,36 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_TIMER=y
CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
CONFIG_SND_SEQUENCER=y
# CONFIG_SND_SEQ_DUMMY is not set
CONFIG_SND_OSSEMUL=y
CONFIG_SND_MIXER_OSS=y
CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
CONFIG_SND_SEQUENCER_OSS=y
CONFIG_SND_DYNAMIC_MINORS=y
CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
# CONFIG_SND_VERBOSE_PRINTK is not set
# CONFIG_SND_DEBUG is not set
#
# Generic devices
#
-CONFIG_SND_OPL3_LIB=y
CONFIG_SND_AC97_CODEC=y
-CONFIG_SND_AC97_BUS=y
# CONFIG_SND_DUMMY is not set
# CONFIG_SND_VIRMIDI is not set
# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_MTS64 is not set
# CONFIG_SND_SERIAL_U16550 is not set
# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_PORTMAN2X4 is not set
#
# PCI devices
#
CONFIG_SND_AD1889=y
-CONFIG_SND_AD1889_OPL3=y
+# CONFIG_SND_ALS300 is not set
# CONFIG_SND_ALI5451 is not set
# CONFIG_SND_ATIIXP is not set
# CONFIG_SND_ATIIXP_MODEM is not set
@@ -979,6 +950,18 @@ CONFIG_SND_AD1889_OPL3=y
# CONFIG_SND_CMIPCI is not set
# CONFIG_SND_CS4281 is not set
# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_DARLA20 is not set
+# CONFIG_SND_GINA20 is not set
+# CONFIG_SND_LAYLA20 is not set
+# CONFIG_SND_DARLA24 is not set
+# CONFIG_SND_GINA24 is not set
+# CONFIG_SND_LAYLA24 is not set
+# CONFIG_SND_MONA is not set
+# CONFIG_SND_MIA is not set
+# CONFIG_SND_ECHO3G is not set
+# CONFIG_SND_INDIGO is not set
+# CONFIG_SND_INDIGOIO is not set
+# CONFIG_SND_INDIGODJ is not set
# CONFIG_SND_EMU10K1 is not set
# CONFIG_SND_EMU10K1X is not set
# CONFIG_SND_ENS1370 is not set
@@ -998,6 +981,7 @@ CONFIG_SND_AD1889_OPL3=y
# CONFIG_SND_MIXART is not set
# CONFIG_SND_NM256 is not set
# CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
# CONFIG_SND_RME32 is not set
# CONFIG_SND_RME96 is not set
# CONFIG_SND_RME9652 is not set
@@ -1007,15 +991,19 @@ CONFIG_SND_AD1889_OPL3=y
# CONFIG_SND_VIA82XX_MODEM is not set
# CONFIG_SND_VX222 is not set
# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_AC97_POWER_SAVE is not set
#
# USB devices
#
# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
#
# PCMCIA devices
#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
#
# GSC devices
@@ -1023,15 +1011,34 @@ CONFIG_SND_AD1889_OPL3=y
CONFIG_SND_HARMONY=y
#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+
+#
+# SoC Audio support for SuperH
+#
+
+#
# Open Sound System
#
# CONFIG_SOUND_PRIME is not set
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
#
-# USB support
+# USB Input Devices
#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
@@ -1039,7 +1046,7 @@ CONFIG_USB=y
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
+CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
@@ -1049,15 +1056,16 @@ CONFIG_USB_DEVICEFS=y
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
#
# USB Device Class drivers
#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
@@ -1072,52 +1080,10 @@ CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_LIBUSUAL is not set
#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_ZD1201 is not set
CONFIG_USB_MON=y
#
@@ -1135,16 +1101,22 @@ CONFIG_USB_MON=y
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
+# CONFIG_USB_PHIDGET is not set
# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
#
@@ -1155,20 +1127,29 @@ CONFIG_USB_MON=y
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_RTC_CLASS is not set
#
-# MMC/SD Card support
+# DMA Engine support
#
-# CONFIG_MMC is not set
+# CONFIG_DMA_ENGINE is not set
#
-# InfiniBand support
+# DMA Clients
#
-# CONFIG_INFINIBAND is not set
#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+# DMA Devices
+#
+# CONFIG_AUXDISPLAY is not set
+
+#
+# Userspace I/O
#
+# CONFIG_UIO is not set
#
# File systems
@@ -1178,16 +1159,19 @@ CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
CONFIG_FS_POSIX_ACL=y
# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
@@ -1217,11 +1201,12 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
@@ -1229,6 +1214,7 @@ CONFIG_RAMFS=y
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
@@ -1261,6 +1247,7 @@ CONFIG_EXPORTFS=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=y
+# CONFIG_SUNRPC_BIND34 is not set
CONFIG_RPCSEC_GSS_KRB5=y
CONFIG_RPCSEC_GSS_SPKM3=m
CONFIG_SMB_FS=m
@@ -1268,12 +1255,13 @@ CONFIG_SMB_NLS_DEFAULT=y
CONFIG_SMB_NLS_REMOTE="cp437"
CONFIG_CIFS=m
# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
# CONFIG_CIFS_EXPERIMENTAL is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
#
# Partition Types
@@ -1326,6 +1314,11 @@ CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=y
#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
# Profiling support
#
CONFIG_PROFILING=y
@@ -1335,21 +1328,32 @@ CONFIG_OPROFILE=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
+CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
# CONFIG_DEBUG_RODATA is not set
#
@@ -1358,12 +1362,13 @@ CONFIG_FORCED_INLINING=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
@@ -1372,9 +1377,18 @@ CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_ECB is not set
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CRYPTD is not set
CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_CAST5=m
@@ -1383,21 +1397,28 @@ CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
+# CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_CAMELLIA is not set
CONFIG_CRYPTO_TEST=m
-
-#
-# Hardware crypto devices
-#
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
+CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/parisc/hpux/gate.S b/arch/parisc/hpux/gate.S
index 0b9d5b1e4b3..38a1c1b8d4e 100644
--- a/arch/parisc/hpux/gate.S
+++ b/arch/parisc/hpux/gate.S
@@ -20,7 +20,7 @@
.import hpux_call_table
.import hpux_syscall_exit,code
- .align 4096
+ .align PAGE_SIZE
ENTRY(hpux_gateway_page)
nop
#ifdef CONFIG_64BIT
@@ -103,5 +103,5 @@ syscall_nosys:
ldo -ENOSYS(%r0),%r28
ENDPROC(hpux_gateway_page)
- .align 4096
+ .align PAGE_SIZE
ENTRY(end_hpux_gateway_page)
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index d3b7917a87c..eaa79bc14d9 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -290,9 +290,6 @@ int main(void)
DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE);
DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT);
DEFINE(ASM_PT_INITIAL, PT_INITIAL);
- DEFINE(ASM_PAGE_SIZE, PAGE_SIZE);
- DEFINE(ASM_PAGE_SIZE_DIV64, PAGE_SIZE/64);
- DEFINE(ASM_PAGE_SIZE_DIV128, PAGE_SIZE/128);
BLANK();
DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 42598abf457..111d47284ea 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -98,7 +98,6 @@
* The "get_stack" macros are responsible for determining the
* kernel stack value.
*
- * For Faults:
* If sr7 == 0
* Already using a kernel stack, so call the
* get_stack_use_r30 macro to push a pt_regs structure
@@ -110,26 +109,6 @@
* task pointer pointed to by cr30. Set the stack
* pointer to point to the end of the task structure.
*
- * For Interrupts:
- * If sr7 == 0
- * Already using a kernel stack, check to see if r30
- * is already pointing to the per processor interrupt
- * stack. If it is, call the get_stack_use_r30 macro
- * to push a pt_regs structure on the stack, and store
- * registers there. Otherwise, call get_stack_use_cr31
- * to get a pointer to the base of the interrupt stack
- * and push a pt_regs structure on that stack.
- * else
- * Need to set up a kernel stack, so call the
- * get_stack_use_cr30 macro to set up a pointer
- * to the pt_regs structure contained within the
- * task pointer pointed to by cr30. Set the stack
- * pointer to point to the end of the task structure.
- * N.B: We don't use the interrupt stack for the
- * first interrupt from userland, because signals/
- * resched's are processed when returning to userland,
- * and we can sleep in those cases.
- *
* Note that we use shadowed registers for temps until
* we can save %r26 and %r29. %r26 is used to preserve
* %r8 (a shadowed register) which temporarily contained
@@ -652,7 +631,7 @@
.text
- .align 4096
+ .align PAGE_SIZE
ENTRY(fault_vector_20)
/* First vector is invalid (0) */
@@ -904,7 +883,7 @@ ENDPROC(_switch_to)
*
*/
- .align 4096
+ .align PAGE_SIZE
ENTRY(syscall_exit_rfi)
mfctl %cr30,%r16
@@ -1086,23 +1065,13 @@ intr_do_preempt:
intr_extint:
CMPIB=,n 0,%r16,1f
+
get_stack_use_cr30
- b,n 3f
+ b,n 2f
1:
-#if 0 /* Interrupt Stack support not working yet! */
- mfctl %cr31,%r1
- copy %r30,%r17
- /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
- DEPI 0,31,15,%r17
- CMPB=,n %r1,%r17,2f
- get_stack_use_cr31
- b,n 3f
-#endif
-2:
get_stack_use_r30
-
-3:
+2:
save_specials %r29
virt_map
save_general %r29
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index 9676c486bb6..a7b8859488b 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -95,7 +95,7 @@ $bss_loop:
1:
stw %r3,0(%r4)
- ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
+ ldo (PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3
addib,> -1,%r1,1b
#if PT_NLEVELS == 3
ldo ASM_PMD_ENTRY_SIZE(%r4),%r4
@@ -128,10 +128,6 @@ $pgt_fill_loop:
/* And the stack pointer too */
ldo THREAD_SZ_ALGN(%r6),%sp
- /* And the interrupt stack */
- load32 interrupt_stack,%r6
- mtctl %r6,%cr31
-
#ifdef CONFIG_SMP
/* Set the smp rendevous address into page zero.
** It would be safer to do this in init_smp_config() but
diff --git a/arch/parisc/kernel/hpmc.S b/arch/parisc/kernel/hpmc.S
index 43b41df0b54..2cbf13b3ef1 100644
--- a/arch/parisc/kernel/hpmc.S
+++ b/arch/parisc/kernel/hpmc.S
@@ -55,13 +55,13 @@
* IODC requires 7K byte stack. That leaves 1K byte for os_hpmc.
*/
- .align 4096
+ .align PAGE_SIZE
hpmc_stack:
.block 16384
#define HPMC_IODC_BUF_SIZE 0x8000
- .align 4096
+ .align PAGE_SIZE
hpmc_iodc_buf:
.block HPMC_IODC_BUF_SIZE
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c
index 446f98d3fd7..26198a074d6 100644
--- a/arch/parisc/kernel/init_task.c
+++ b/arch/parisc/kernel/init_task.c
@@ -49,7 +49,6 @@ EXPORT_SYMBOL(init_mm);
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
-unsigned char interrupt_stack[ISTACK_SIZE] __attribute__ ((section("init_istack"), aligned(4096)));
union thread_union init_thread_union
__attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 90b24087852..5901092e019 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -289,7 +289,7 @@ ENTRY(copy_user_page_asm)
*/
ldd 0(%r25), %r19
- ldi ASM_PAGE_SIZE_DIV128, %r1
+ ldi (PAGE_SIZE / 128), %r1
ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */
ldw 128(%r25), %r0 /* prefetch 2 */
@@ -355,7 +355,7 @@ ENTRY(copy_user_page_asm)
* use ldd/std on a 32 bit kernel.
*/
ldw 0(%r25), %r19
- ldi ASM_PAGE_SIZE_DIV64, %r1
+ ldi (PAGE_SIZE / 64), %r1
1:
ldw 4(%r25), %r20
@@ -553,7 +553,7 @@ ENTRY(__clear_user_page_asm)
pdtlb 0(%r28)
#ifdef CONFIG_64BIT
- ldi ASM_PAGE_SIZE_DIV128, %r1
+ ldi (PAGE_SIZE / 128), %r1
/* PREFETCH (Write) has not (yet) been proven to help here */
/* #define PREFETCHW_OP ldd 256(%0), %r0 */
@@ -578,7 +578,7 @@ ENTRY(__clear_user_page_asm)
ldo 128(%r28), %r28
#else /* ! CONFIG_64BIT */
- ldi ASM_PAGE_SIZE_DIV64, %r1
+ ldi (PAGE_SIZE / 64), %r1
1:
stw %r0, 0(%r28)
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c
index 7aca704e96f..671ee5b9950 100644
--- a/arch/parisc/kernel/parisc_ksyms.c
+++ b/arch/parisc/kernel/parisc_ksyms.c
@@ -122,31 +122,9 @@ EXPORT_SYMBOL($$divI_12);
EXPORT_SYMBOL($$divI_14);
EXPORT_SYMBOL($$divI_15);
-extern void __ashrdi3(void);
-extern void __ashldi3(void);
-extern void __lshrdi3(void);
-extern void __muldi3(void);
-
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__muldi3);
-
asmlinkage void * __canonicalize_funcptr_for_compare(void *);
EXPORT_SYMBOL(__canonicalize_funcptr_for_compare);
-#ifdef CONFIG_64BIT
-extern void __divdi3(void);
-extern void __udivdi3(void);
-extern void __umoddi3(void);
-extern void __moddi3(void);
-
-EXPORT_SYMBOL(__divdi3);
-EXPORT_SYMBOL(__udivdi3);
-EXPORT_SYMBOL(__umoddi3);
-EXPORT_SYMBOL(__moddi3);
-#endif
-
#ifndef CONFIG_64BIT
extern void $$dyncall(void);
EXPORT_SYMBOL($$dyncall);
diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
index 23c1388df1f..41f8e321e34 100644
--- a/arch/parisc/kernel/pci-dma.c
+++ b/arch/parisc/kernel/pci-dma.c
@@ -569,11 +569,10 @@ static void *fail_alloc_consistent(struct device *dev, size_t size,
static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
- void *addr = NULL;
+ void *addr;
- /* rely on kmalloc to be cacheline aligned */
- addr = kmalloc(size, flag);
- if(addr)
+ addr = (void *)__get_free_pages(flag, get_order(size));
+ if (addr)
*dma_handle = (dma_addr_t)virt_to_phys(addr);
return addr;
@@ -582,7 +581,7 @@ static void *pa11_dma_alloc_noncoherent(struct device *dev, size_t size,
static void pa11_dma_free_noncoherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t iova)
{
- kfree(vaddr);
+ free_pages((unsigned long)vaddr, get_order(size));
return;
}
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 563df0072de..507d0ac99f6 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -194,37 +194,13 @@ void __init pcibios_init_bus(struct pci_bus *bus)
pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
}
-
-/* KLUGE: Link the child and parent resources - generic PCI didn't */
-static void
-pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
-{
- if (!r->parent) {
- printk(KERN_EMERG "PCI: resource not parented! [%p-%p]\n",
- (void*) r->start, (void*) r->end);
- r->parent = hba_res;
-
- /* reverse link is harder *sigh* */
- if (r->parent->child) {
- if (r->parent->sibling) {
- struct resource *next = r->parent->sibling;
- while (next->sibling)
- next = next->sibling;
- next->sibling = r;
- } else {
- r->parent->sibling = r;
- }
- } else
- r->parent->child = r;
- }
-}
-
/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
struct pci_bus_region *region, struct resource *res)
{
- struct pci_bus *bus = dev->bus;
- struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+#ifdef CONFIG_64BIT
+ struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
+#endif
if (res->flags & IORESOURCE_IO) {
/*
@@ -243,23 +219,15 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
}
DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
- bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
+ dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
region->start, region->end);
-
- /* KLUGE ALERT
- ** if this resource isn't linked to a "parent", then it seems
- ** to be a child of the HBA - lets link it in.
- */
- pcibios_link_hba_resources(&hba->io_space, bus->resource[0]);
- pcibios_link_hba_resources(&hba->lmmio_space, bus->resource[1]);
}
void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
struct pci_bus_region *region)
{
#ifdef CONFIG_64BIT
- struct pci_bus *bus = dev->bus;
- struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data);
+ struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
#endif
if (res->flags & IORESOURCE_MEM) {
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 549f5484342..370086fb833 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -82,7 +82,12 @@ static int __cpuinit processor_probe(struct parisc_device *dev)
unsigned long cpuid;
struct cpuinfo_parisc *p;
-#ifndef CONFIG_SMP
+#ifdef CONFIG_SMP
+ if (num_online_cpus() >= NR_CPUS) {
+ printk(KERN_INFO "num_online_cpus() >= NR_CPUS\n");
+ return 1;
+ }
+#else
if (boot_cpu_data.cpu_count > 0) {
printk(KERN_INFO "CONFIG_SMP=n ignoring additional CPUs\n");
return 1;
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index fb35ebc0c4d..2ce3806f02e 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -181,7 +181,7 @@ give_sigsegv:
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
+ si.si_pid = task_pid_vnr(current);
si.si_uid = current->uid;
si.si_addr = &frame->uc;
force_sig_info(SIGSEGV, &si, current);
diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index d7bc7bb42c9..85fc7754ec2 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -432,22 +432,10 @@ smp_cpu_init(int cpunum)
void __init smp_callin(void)
{
int slave_id = cpu_now_booting;
-#if 0
- void *istack;
-#endif
smp_cpu_init(slave_id);
preempt_disable();
-#if 0 /* NOT WORKING YET - see entry.S */
- istack = (void *)__get_free_pages(GFP_KERNEL,ISTACK_ORDER);
- if (istack == NULL) {
- printk(KERN_CRIT "Failed to allocate interrupt stack for cpu %d\n",slave_id);
- BUG();
- }
- mtctl(istack,31);
-#endif
-
flush_cache_all_local(); /* start with known state */
flush_tlb_all_local(NULL);
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 2989c6682bf..50bbf33ee00 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -473,3 +473,10 @@ long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf,
return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,
buf, len);
}
+
+asmlinkage long compat_sys_fallocate(int fd, int mode, u32 offhi, u32 offlo,
+ u32 lenhi, u32 lenlo)
+{
+ return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
+ ((loff_t)lenhi << 32) | lenlo);
+}
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index 56f6231cb86..69b6eebc466 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -10,6 +10,7 @@
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/errno.h>
+#include <asm/page.h>
#include <asm/psw.h>
#include <asm/thread_info.h>
#include <asm/assembly.h>
@@ -38,7 +39,7 @@
* pointers.
*/
- .align ASM_PAGE_SIZE
+ .align PAGE_SIZE
ENTRY(linux_gateway_page)
/* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */
@@ -597,7 +598,7 @@ cas_action:
/* Make sure nothing else is placed on this page */
- .align ASM_PAGE_SIZE
+ .align PAGE_SIZE
END(linux_gateway_page)
ENTRY(end_linux_gateway_page)
@@ -608,7 +609,7 @@ ENTRY(end_linux_gateway_page)
.section .rodata,"a"
- .align ASM_PAGE_SIZE
+ .align PAGE_SIZE
/* Light-weight-syscall table */
/* Start of lws table. */
ENTRY(lws_table)
@@ -617,13 +618,13 @@ ENTRY(lws_table)
END(lws_table)
/* End of lws table */
- .align ASM_PAGE_SIZE
+ .align PAGE_SIZE
ENTRY(sys_call_table)
#include "syscall_table.S"
END(sys_call_table)
#ifdef CONFIG_64BIT
- .align ASM_PAGE_SIZE
+ .align PAGE_SIZE
ENTRY(sys_call_table64)
#define SYSCALL_TABLE_64BIT
#include "syscall_table.S"
@@ -636,7 +637,7 @@ END(sys_call_table64)
will use this set of locks
*/
.section .data
- .align 4096
+ .align PAGE_SIZE
ENTRY(lws_lock_start)
/* lws locks */
.align 16
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 2540786a970..117438e9eb2 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -403,6 +403,7 @@
ENTRY_COMP(signalfd)
ENTRY_COMP(timerfd)
ENTRY_SAME(eventfd)
+ ENTRY_COMP(fallocate) /* 305 */
/* Nothing yet */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 8b3062a5c81..24be86bba94 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -189,16 +189,14 @@ static struct clocksource clocksource_cr16 = {
#ifdef CONFIG_SMP
int update_cr16_clocksource(void)
{
- int change = 0;
-
/* since the cr16 cycle counters are not synchronized across CPUs,
we'll check if we should switch to a safe clocksource: */
if (clocksource_cr16.rating != 0 && num_online_cpus() > 1) {
clocksource_change_rating(&clocksource_cr16, 0);
- change = 1;
+ return 1;
}
- return change;
+ return 0;
}
#else
int update_cr16_clocksource(void)
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index bbf029a184a..99fd56939af 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -219,7 +219,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
return; /* STFU */
printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n",
- current->comm, current->pid, str, err, regs->iaoq[0]);
+ current->comm, task_pid_nr(current), str, err, regs->iaoq[0]);
#ifdef PRINT_USER_FAULTS
/* XXX for debugging only */
show_regs(regs);
@@ -252,7 +252,7 @@ KERN_CRIT " || ||\n");
if (err)
printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n",
- current->comm, current->pid, str, err);
+ current->comm, task_pid_nr(current), str, err);
/* Wot's wrong wif bein' racy? */
if (current->thread.flags & PARISC_KERNEL_DEATH) {
@@ -317,7 +317,7 @@ static void handle_break(struct pt_regs *regs)
if (unlikely(iir != GDB_BREAK_INSN)) {
printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n",
iir & 31, (iir>>13) & ((1<<13)-1),
- current->pid, current->comm);
+ task_pid_nr(current), current->comm);
show_regs(regs);
}
#endif
@@ -747,7 +747,7 @@ void handle_interruption(int code, struct pt_regs *regs)
if (user_mode(regs)) {
#ifdef PRINT_USER_FAULTS
printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
- current->pid, current->comm);
+ task_pid_nr(current), current->comm);
show_regs(regs);
#endif
/* SIGBUS, for lack of a better one. */
@@ -772,7 +772,7 @@ void handle_interruption(int code, struct pt_regs *regs)
else
printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ",
code);
- printk("pid=%d command='%s'\n", current->pid, current->comm);
+ printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm);
show_regs(regs);
#endif
si.si_signo = SIGSEGV;
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index 347bb922e6d..aebf3c16887 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -469,7 +469,7 @@ void handle_unaligned(struct pt_regs *regs)
&& ++unaligned_count < 5) {
char buf[256];
sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n",
- current->comm, current->pid, regs->ior, regs->iaoq[0]);
+ current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]);
printk(KERN_WARNING "%s", buf);
#ifdef DEBUG_UNALIGNED
show_regs(regs);
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index cf780cb3b91..701b2d2d888 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -209,8 +209,8 @@ static int unwind_init(void)
static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
{
- void handle_interruption(int, struct pt_regs *);
- static unsigned long *hi = (unsigned long)&handle_interruption;
+ extern void handle_interruption(int, struct pt_regs *);
+ static unsigned long *hi = (unsigned long *)&handle_interruption;
if (pc == get_func_addr(hi)) {
struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
index ee7a16eb6fd..40d0ff9b81a 100644
--- a/arch/parisc/kernel/vmlinux.lds.S
+++ b/arch/parisc/kernel/vmlinux.lds.S
@@ -46,168 +46,211 @@ jiffies = jiffies_64;
#endif
SECTIONS
{
+ . = KERNEL_BINARY_TEXT_START;
- . = KERNEL_BINARY_TEXT_START;
-
- _text = .; /* Text and read-only data */
- .text ALIGN(16) : {
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- *(.text.do_softirq)
- *(.text.sys_exit)
- *(.text.do_sigaltstack)
- *(.text.do_fork)
- *(.text.*)
- *(.fixup)
- *(.lock.text) /* out-of-line lock text */
- *(.gnu.warning)
+ _text = .; /* Text and read-only data */
+ .text ALIGN(16) : {
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ *(.text.do_softirq)
+ *(.text.sys_exit)
+ *(.text.do_sigaltstack)
+ *(.text.do_fork)
+ *(.text.*)
+ *(.fixup)
+ *(.lock.text) /* out-of-line lock text */
+ *(.gnu.warning)
} = 0
+ /* End of text section */
+ _etext = .;
- _etext = .; /* End of text section */
+ RODATA
+ BUG_TABLE
- RODATA
-
- BUG_TABLE
-
- /* writeable */
- . = ALIGN(ASM_PAGE_SIZE); /* Make sure this is page aligned so
- that we can properly leave these
- as writable */
- data_start = .;
-
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
- __ex_table : { *(__ex_table) }
- __stop___ex_table = .;
+ /* writeable */
+ /* Make sure this is page aligned so
+ * that we can properly leave these
+ * as writable
+ */
+ . = ALIGN(PAGE_SIZE);
+ data_start = .;
+ . = ALIGN(16);
+ /* Exception table */
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
- NOTES
+ NOTES
- __start___unwind = .; /* unwind info */
- .PARISC.unwind : { *(.PARISC.unwind) }
- __stop___unwind = .;
+ /* unwind info */
+ .PARISC.unwind : {
+ __start___unwind = .;
+ *(.PARISC.unwind)
+ __stop___unwind = .;
+ }
- /* rarely changed data like cpu maps */
- . = ALIGN(16);
- .data.read_mostly : { *(.data.read_mostly) }
+ /* rarely changed data like cpu maps */
+ . = ALIGN(16);
+ .data.read_mostly : {
+ *(.data.read_mostly)
+ }
- . = ALIGN(L1_CACHE_BYTES);
- .data : { /* Data */
- DATA_DATA
- CONSTRUCTORS
+ . = ALIGN(L1_CACHE_BYTES);
+ /* Data */
+ .data : {
+ DATA_DATA
+ CONSTRUCTORS
}
- . = ALIGN(L1_CACHE_BYTES);
- .data.cacheline_aligned : { *(.data.cacheline_aligned) }
+ . = ALIGN(L1_CACHE_BYTES);
+ .data.cacheline_aligned : {
+ *(.data.cacheline_aligned)
+ }
- /* PA-RISC locks requires 16-byte alignment */
- . = ALIGN(16);
- .data.lock_aligned : { *(.data.lock_aligned) }
+ /* PA-RISC locks requires 16-byte alignment */
+ . = ALIGN(16);
+ .data.lock_aligned : {
+ *(.data.lock_aligned)
+ }
- . = ALIGN(ASM_PAGE_SIZE);
- /* nosave data is really only used for software suspend...it's here
- * just in case we ever implement it */
- __nosave_begin = .;
- .data_nosave : { *(.data.nosave) }
- . = ALIGN(ASM_PAGE_SIZE);
- __nosave_end = .;
+ /* nosave data is really only used for software suspend...it's here
+ * just in case we ever implement it
+ */
+ . = ALIGN(PAGE_SIZE);
+ __nosave_begin = .;
+ .data_nosave : {
+ *(.data.nosave)
+ }
+ . = ALIGN(PAGE_SIZE);
+ __nosave_end = .;
- _edata = .; /* End of data section */
+ /* End of data section */
+ _edata = .;
- __bss_start = .; /* BSS */
- /* page table entries need to be PAGE_SIZE aligned */
- . = ALIGN(ASM_PAGE_SIZE);
- .data.vmpages : {
- *(.data.vm0.pmd)
- *(.data.vm0.pgd)
- *(.data.vm0.pte)
+ /* BSS */
+ __bss_start = .;
+ /* page table entries need to be PAGE_SIZE aligned */
+ . = ALIGN(PAGE_SIZE);
+ .data.vmpages : {
+ *(.data.vm0.pmd)
+ *(.data.vm0.pgd)
+ *(.data.vm0.pte)
}
- .bss : { *(.bss) *(COMMON) }
- __bss_stop = .;
-
+ .bss : {
+ *(.bss)
+ *(COMMON)
+ }
+ __bss_stop = .;
- /* assembler code expects init_task to be 16k aligned */
- . = ALIGN(16384); /* init_task */
- .data.init_task : { *(.data.init_task) }
- /* The interrupt stack is currently partially coded, but not yet
- * implemented */
- . = ALIGN(16384);
- init_istack : { *(init_istack) }
+ /* assembler code expects init_task to be 16k aligned */
+ . = ALIGN(16384);
+ /* init_task */
+ .data.init_task : {
+ *(.data.init_task)
+ }
#ifdef CONFIG_64BIT
- . = ALIGN(16); /* Linkage tables */
- .opd : { *(.opd) } PROVIDE (__gp = .);
- .plt : { *(.plt) }
- .dlt : { *(.dlt) }
+ . = ALIGN(16);
+ /* Linkage tables */
+ .opd : {
+ *(.opd)
+ } PROVIDE (__gp = .);
+ .plt : {
+ *(.plt)
+ }
+ .dlt : {
+ *(.dlt)
+ }
#endif
- /* reserve space for interrupt stack by aligning __init* to 16k */
- . = ALIGN(16384);
- __init_begin = .;
- .init.text : {
- _sinittext = .;
- *(.init.text)
- _einittext = .;
- }
- .init.data : { *(.init.data) }
- . = ALIGN(16);
- __setup_start = .;
- .init.setup : { *(.init.setup) }
- __setup_end = .;
- __initcall_start = .;
- .initcall.init : {
- INITCALLS
- }
- __initcall_end = .;
- __con_initcall_start = .;
- .con_initcall.init : { *(.con_initcall.init) }
- __con_initcall_end = .;
- SECURITY_INIT
- /* alternate instruction replacement. This is a mechanism x86 uses
- * to detect the CPU type and replace generic instruction sequences
- * with CPU specific ones. We don't currently do this in PA, but
- * it seems like a good idea... */
- . = ALIGN(4);
- __alt_instructions = .;
- .altinstructions : { *(.altinstructions) }
- __alt_instructions_end = .;
- .altinstr_replacement : { *(.altinstr_replacement) }
- /* .exit.text is discard at runtime, not link time, to deal with references
- from .altinstructions and .eh_frame */
- .exit.text : { *(.exit.text) }
- .exit.data : { *(.exit.data) }
+ /* reserve space for interrupt stack by aligning __init* to 16k */
+ . = ALIGN(16384);
+ __init_begin = .;
+ .init.text : {
+ _sinittext = .;
+ *(.init.text)
+ _einittext = .;
+ }
+ .init.data : {
+ *(.init.data)
+ }
+ . = ALIGN(16);
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+ .initcall.init : {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+ SECURITY_INIT
+
+ /* alternate instruction replacement. This is a mechanism x86 uses
+ * to detect the CPU type and replace generic instruction sequences
+ * with CPU specific ones. We don't currently do this in PA, but
+ * it seems like a good idea...
+ */
+ . = ALIGN(4);
+ .altinstructions : {
+ __alt_instructions = .;
+ *(.altinstructions)
+ __alt_instructions_end = .;
+ }
+ .altinstr_replacement : {
+ *(.altinstr_replacement)
+ }
+
+ /* .exit.text is discard at runtime, not link time, to deal with references
+ * from .altinstructions and .eh_frame
+ */
+ .exit.text : {
+ *(.exit.text)
+ }
+ .exit.data : {
+ *(.exit.data)
+ }
#ifdef CONFIG_BLK_DEV_INITRD
- . = ALIGN(ASM_PAGE_SIZE);
- __initramfs_start = .;
- .init.ramfs : { *(.init.ramfs) }
- __initramfs_end = .;
+ . = ALIGN(PAGE_SIZE);
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
#endif
- PERCPU(ASM_PAGE_SIZE)
+ PERCPU(PAGE_SIZE)
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
+ /* freed after init ends here */
+ _end = . ;
- . = ALIGN(ASM_PAGE_SIZE);
- __init_end = .;
- /* freed after init ends here */
-
- _end = . ;
-
- /* Sections to be discarded */
- /DISCARD/ : {
- *(.exitcall.exit)
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exitcall.exit)
#ifdef CONFIG_64BIT
- /* temporary hack until binutils is fixed to not emit these
- for static binaries */
- *(.interp)
- *(.dynsym)
- *(.dynstr)
- *(.dynamic)
- *(.hash)
- *(.gnu.hash)
+ /* temporary hack until binutils is fixed to not emit these
+ * for static binaries
+ */
+ *(.interp)
+ *(.dynsym)
+ *(.dynstr)
+ *(.dynamic)
+ *(.hash)
+ *(.gnu.hash)
#endif
}
- STABS_DEBUG
- .note 0 : { *(.note) }
-
+ STABS_DEBUG
+ .note 0 : { *(.note) }
}
diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
index 5f2e6904d14..7ce406c7daf 100644
--- a/arch/parisc/lib/Makefile
+++ b/arch/parisc/lib/Makefile
@@ -4,4 +4,4 @@
lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o
-obj-y := iomap.o
+obj-y := libgcc/ milli/ iomap.o
diff --git a/arch/parisc/lib/libgcc/Makefile b/arch/parisc/lib/libgcc/Makefile
new file mode 100644
index 00000000000..b67a85ad9c8
--- /dev/null
+++ b/arch/parisc/lib/libgcc/Makefile
@@ -0,0 +1,4 @@
+obj-y := __ashldi3.o __ashrdi3.o __clzsi2.o __divdi3.o __divsi3.o \
+ __lshrdi3.o __moddi3.o __modsi3.o __udivdi3.o \
+ __udivmoddi4.o __udivmodsi4.o __udivsi3.o \
+ __umoddi3.o __umodsi3.o __muldi3.o __umulsidi3.o
diff --git a/arch/parisc/lib/libgcc/__ashldi3.c b/arch/parisc/lib/libgcc/__ashldi3.c
new file mode 100644
index 00000000000..a14a257abb2
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__ashldi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashldi3(u64 v, int cnt)
+{
+ int c = cnt & 31;
+ u32 vl = (u32) v;
+ u32 vh = (u32) (v >> 32);
+
+ if (cnt & 32) {
+ vh = (vl << c);
+ vl = 0;
+ } else {
+ vh = (vh << c) + (vl >> (32 - c));
+ vl = (vl << c);
+ }
+
+ return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashldi3);
diff --git a/arch/parisc/lib/libgcc/__ashrdi3.c b/arch/parisc/lib/libgcc/__ashrdi3.c
new file mode 100644
index 00000000000..8636a5aa4f7
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__ashrdi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __ashrdi3(u64 v, int cnt)
+{
+ int c = cnt & 31;
+ u32 vl = (u32) v;
+ u32 vh = (u32) (v >> 32);
+
+ if (cnt & 32) {
+ vl = ((s32) vh >> c);
+ vh = (s32) vh >> 31;
+ } else {
+ vl = (vl >> c) + (vh << (32 - c));
+ vh = ((s32) vh >> c);
+ }
+
+ return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__ashrdi3);
diff --git a/arch/parisc/lib/libgcc/__clzsi2.c b/arch/parisc/lib/libgcc/__clzsi2.c
new file mode 100644
index 00000000000..a7aa2f55a9c
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__clzsi2.c
@@ -0,0 +1,30 @@
+#include "libgcc.h"
+
+u32 __clzsi2(u32 v)
+{
+ int p = 31;
+
+ if (v & 0xffff0000) {
+ p -= 16;
+ v >>= 16;
+ }
+ if (v & 0xff00) {
+ p -= 8;
+ v >>= 8;
+ }
+ if (v & 0xf0) {
+ p -= 4;
+ v >>= 4;
+ }
+ if (v & 0xc) {
+ p -= 2;
+ v >>= 2;
+ }
+ if (v & 0x2) {
+ p -= 1;
+ v >>= 1;
+ }
+
+ return p;
+}
+EXPORT_SYMBOL(__clzsi2);
diff --git a/arch/parisc/lib/libgcc/__divdi3.c b/arch/parisc/lib/libgcc/__divdi3.c
new file mode 100644
index 00000000000..f23c6fe2838
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__divdi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __divdi3(s64 num, s64 den)
+{
+ int minus = 0;
+ s64 v;
+
+ if (num < 0) {
+ num = -num;
+ minus = 1;
+ }
+ if (den < 0) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ v = __udivmoddi4(num, den, NULL);
+ if (minus)
+ v = -v;
+
+ return v;
+}
+EXPORT_SYMBOL(__divdi3);
diff --git a/arch/parisc/lib/libgcc/__divsi3.c b/arch/parisc/lib/libgcc/__divsi3.c
new file mode 100644
index 00000000000..730fb530680
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__divsi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __divsi3(s32 num, s32 den)
+{
+ int minus = 0;
+ s32 v;
+
+ if (num < 0) {
+ num = -num;
+ minus = 1;
+ }
+ if (den < 0) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ v = __udivmodsi4(num, den, NULL);
+ if (minus)
+ v = -v;
+
+ return v;
+}
+EXPORT_SYMBOL(__divsi3);
diff --git a/arch/parisc/lib/libgcc/__lshrdi3.c b/arch/parisc/lib/libgcc/__lshrdi3.c
new file mode 100644
index 00000000000..4a820708ec5
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__lshrdi3.c
@@ -0,0 +1,19 @@
+#include "libgcc.h"
+
+u64 __lshrdi3(u64 v, int cnt)
+{
+ int c = cnt & 31;
+ u32 vl = (u32) v;
+ u32 vh = (u32) (v >> 32);
+
+ if (cnt & 32) {
+ vl = (vh >> c);
+ vh = 0;
+ } else {
+ vl = (vl >> c) + (vh << (32 - c));
+ vh = (vh >> c);
+ }
+
+ return ((u64) vh << 32) + vl;
+}
+EXPORT_SYMBOL(__lshrdi3);
diff --git a/arch/parisc/lib/libgcc/__moddi3.c b/arch/parisc/lib/libgcc/__moddi3.c
new file mode 100644
index 00000000000..ed64bbafc98
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__moddi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s64 __moddi3(s64 num, s64 den)
+{
+ int minus = 0;
+ s64 v;
+
+ if (num < 0) {
+ num = -num;
+ minus = 1;
+ }
+ if (den < 0) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ (void)__udivmoddi4(num, den, (u64 *) & v);
+ if (minus)
+ v = -v;
+
+ return v;
+}
+EXPORT_SYMBOL(__moddi3);
diff --git a/arch/parisc/lib/libgcc/__modsi3.c b/arch/parisc/lib/libgcc/__modsi3.c
new file mode 100644
index 00000000000..62f773efaee
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__modsi3.c
@@ -0,0 +1,23 @@
+#include "libgcc.h"
+
+s32 __modsi3(s32 num, s32 den)
+{
+ int minus = 0;
+ s32 v;
+
+ if (num < 0) {
+ num = -num;
+ minus = 1;
+ }
+ if (den < 0) {
+ den = -den;
+ minus ^= 1;
+ }
+
+ (void)__udivmodsi4(num, den, (u32 *) & v);
+ if (minus)
+ v = -v;
+
+ return v;
+}
+EXPORT_SYMBOL(__modsi3);
diff --git a/arch/parisc/lib/libgcc/__muldi3.c b/arch/parisc/lib/libgcc/__muldi3.c
new file mode 100644
index 00000000000..3308abdd558
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__muldi3.c
@@ -0,0 +1,22 @@
+#include "libgcc.h"
+
+union DWunion {
+ struct {
+ s32 high;
+ s32 low;
+ } s;
+ s64 ll;
+};
+
+s64 __muldi3(s64 u, s64 v)
+{
+ const union DWunion uu = { .ll = u };
+ const union DWunion vv = { .ll = v };
+ union DWunion w = { .ll = __umulsidi3(uu.s.low, vv.s.low) };
+
+ w.s.high += ((u32)uu.s.low * (u32)vv.s.high
+ + (u32)uu.s.high * (u32)vv.s.low);
+
+ return w.ll;
+}
+EXPORT_SYMBOL(__muldi3);
diff --git a/arch/parisc/lib/libgcc/__udivdi3.c b/arch/parisc/lib/libgcc/__udivdi3.c
new file mode 100644
index 00000000000..740023d690f
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivdi3.c
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u64 __udivdi3(u64 num, u64 den)
+{
+ return __udivmoddi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivdi3);
diff --git a/arch/parisc/lib/libgcc/__udivmoddi4.c b/arch/parisc/lib/libgcc/__udivmoddi4.c
new file mode 100644
index 00000000000..2df0caa5a7d
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivmoddi4.c
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p)
+{
+ u64 quot = 0, qbit = 1;
+
+ if (den == 0) {
+ BUG();
+ }
+
+ /* Left-justify denominator and count shift */
+ while ((s64) den >= 0) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while (qbit) {
+ if (den <= num) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if (rem_p)
+ *rem_p = num;
+
+ return quot;
+}
+EXPORT_SYMBOL(__udivmoddi4);
diff --git a/arch/parisc/lib/libgcc/__udivmodsi4.c b/arch/parisc/lib/libgcc/__udivmodsi4.c
new file mode 100644
index 00000000000..2a2fc28b202
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivmodsi4.c
@@ -0,0 +1,31 @@
+#include "libgcc.h"
+
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p)
+{
+ u32 quot = 0, qbit = 1;
+
+ if (den == 0) {
+ BUG();
+ }
+
+ /* Left-justify denominator and count shift */
+ while ((s32) den >= 0) {
+ den <<= 1;
+ qbit <<= 1;
+ }
+
+ while (qbit) {
+ if (den <= num) {
+ num -= den;
+ quot += qbit;
+ }
+ den >>= 1;
+ qbit >>= 1;
+ }
+
+ if (rem_p)
+ *rem_p = num;
+
+ return quot;
+}
+EXPORT_SYMBOL(__udivmodsi4);
diff --git a/arch/parisc/lib/libgcc/__udivsi3.c b/arch/parisc/lib/libgcc/__udivsi3.c
new file mode 100644
index 00000000000..756a44164e9
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__udivsi3.c
@@ -0,0 +1,7 @@
+#include "libgcc.h"
+
+u32 __udivsi3(u32 num, u32 den)
+{
+ return __udivmodsi4(num, den, NULL);
+}
+EXPORT_SYMBOL(__udivsi3);
diff --git a/arch/parisc/lib/libgcc/__umoddi3.c b/arch/parisc/lib/libgcc/__umoddi3.c
new file mode 100644
index 00000000000..ac744e948bc
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umoddi3.c
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u64 __umoddi3(u64 num, u64 den)
+{
+ u64 v;
+
+ (void)__udivmoddi4(num, den, &v);
+ return v;
+}
+EXPORT_SYMBOL(__umoddi3);
diff --git a/arch/parisc/lib/libgcc/__umodsi3.c b/arch/parisc/lib/libgcc/__umodsi3.c
new file mode 100644
index 00000000000..51f55aa89f9
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umodsi3.c
@@ -0,0 +1,10 @@
+#include "libgcc.h"
+
+u32 __umodsi3(u32 num, u32 den)
+{
+ u32 v;
+
+ (void)__udivmodsi4(num, den, &v);
+ return v;
+}
+EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/parisc/lib/libgcc/__umulsidi3.c b/arch/parisc/lib/libgcc/__umulsidi3.c
new file mode 100644
index 00000000000..396f669164d
--- /dev/null
+++ b/arch/parisc/lib/libgcc/__umulsidi3.c
@@ -0,0 +1,46 @@
+#include "libgcc.h"
+
+#define __ll_B ((u32) 1 << (32 / 2))
+#define __ll_lowpart(t) ((u32) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((u32) (t) >> 16)
+
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ u32 __x0, __x1, __x2, __x3; \
+ u16 __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart (u); \
+ __uh = __ll_highpart (u); \
+ __vl = __ll_lowpart (v); \
+ __vh = __ll_highpart (v); \
+ \
+ __x0 = (u32) __ul * __vl; \
+ __x1 = (u32) __ul * __vh; \
+ __x2 = (u32) __uh * __vl; \
+ __x3 = (u32) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
+ } while (0)
+
+union DWunion {
+ struct {
+ s32 high;
+ s32 low;
+ } s;
+ s64 ll;
+};
+
+u64 __umulsidi3(u32 u, u32 v)
+{
+ union DWunion __w;
+
+ umul_ppmm(__w.s.high, __w.s.low, u, v);
+
+ return __w.ll;
+}
diff --git a/arch/parisc/lib/libgcc/libgcc.h b/arch/parisc/lib/libgcc/libgcc.h
new file mode 100644
index 00000000000..5a6f7a510fb
--- /dev/null
+++ b/arch/parisc/lib/libgcc/libgcc.h
@@ -0,0 +1,32 @@
+#ifndef _PA_LIBGCC_H_
+#define _PA_LIBGCC_H_
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+/* Cribbed from klibc/libgcc/ */
+u64 __ashldi3(u64 v, int cnt);
+u64 __ashrdi3(u64 v, int cnt);
+
+u32 __clzsi2(u32 v);
+
+s64 __divdi3(s64 num, s64 den);
+s32 __divsi3(s32 num, s32 den);
+
+u64 __lshrdi3(u64 v, int cnt);
+
+s64 __moddi3(s64 num, s64 den);
+s32 __modsi3(s32 num, s32 den);
+
+u64 __udivdi3(u64 num, u64 den);
+u32 __udivsi3(u32 num, u32 den);
+
+u64 __udivmoddi4(u64 num, u64 den, u64 * rem_p);
+u32 __udivmodsi4(u32 num, u32 den, u32 * rem_p);
+
+u64 __umulsidi3(u32 u, u32 v);
+
+u64 __umoddi3(u64 num, u64 den);
+u32 __umodsi3(u32 num, u32 den);
+
+#endif /*_PA_LIBGCC_H_*/
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 2c43ebe99a9..d22042d3310 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -139,12 +139,12 @@ DECLARE_PER_CPU(struct exception_data, exception_data);
#define stw(_s,_t,_o,_a,_e) def_store_insn(stw,"r",_s,_t,_o,_a,_e)
#ifdef CONFIG_PREFETCH
-extern inline void prefetch_src(const void *addr)
+static inline void prefetch_src(const void *addr)
{
__asm__("ldw 0(" s_space ",%0), %%r0" : : "r" (addr));
}
-extern inline void prefetch_dst(const void *addr)
+static inline void prefetch_dst(const void *addr)
{
__asm__("ldd 0(" d_space ",%0), %%r0" : : "r" (addr));
}
diff --git a/arch/parisc/lib/milli/Makefile b/arch/parisc/lib/milli/Makefile
new file mode 100644
index 00000000000..9b24e9b1f3c
--- /dev/null
+++ b/arch/parisc/lib/milli/Makefile
@@ -0,0 +1 @@
+obj-y := dyncall.o divI.o divU.o remI.o remU.o div_const.o mulI.o
diff --git a/arch/parisc/lib/milli/divI.S b/arch/parisc/lib/milli/divI.S
new file mode 100644
index 00000000000..ac106b7b6f2
--- /dev/null
+++ b/arch/parisc/lib/milli/divI.S
@@ -0,0 +1,254 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_divI
+/* ROUTINES: $$divI, $$divoI
+
+ Single precision divide for signed binary integers.
+
+ The quotient is truncated towards zero.
+ The sign of the quotient is the XOR of the signs of the dividend and
+ divisor.
+ Divide by zero is trapped.
+ Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions:
+ . divisor is zero (traps with ADDIT,= 0,25,0)
+ . dividend==-2**31 and divisor==-1 and routine is $$divoI
+ . (traps with ADDO 26,25,0)
+ . Changes memory at the following places:
+ . NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Branchs to other millicode routines using BE
+ . $$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+ .
+ . For selected divisors, calls a divide by constant routine written by
+ . Karl Pettis. Eligible divisors are 1..15 excluding 11 and 13.
+ .
+ . The only overflow case is -2**31 divided by -1.
+ . Both routines return -2**31 but only $$divoI traps. */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1) /* r29 */
+RDEFINE(temp1,arg0)
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+ .import $$divI_2,millicode
+ .import $$divI_3,millicode
+ .import $$divI_4,millicode
+ .import $$divI_5,millicode
+ .import $$divI_6,millicode
+ .import $$divI_7,millicode
+ .import $$divI_8,millicode
+ .import $$divI_9,millicode
+ .import $$divI_10,millicode
+ .import $$divI_12,millicode
+ .import $$divI_14,millicode
+ .import $$divI_15,millicode
+ .export $$divI,millicode
+ .export $$divoI,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$divoI)
+ comib,=,n -1,arg1,LREF(negative1) /* when divisor == -1 */
+GSYM($$divI)
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,<> arg1,temp,r0 /* if not, don't use power of 2 divide */
+ addi,> 0,arg1,r0 /* if divisor > 0, use power of 2 divide */
+ b,n LREF(neg_denom)
+LSYM(pow2)
+ addi,>= 0,arg0,retreg /* if numerator is negative, add the */
+ add arg0,temp,retreg /* (denominaotr -1) to correct for shifts */
+ extru,= arg1,15,16,temp /* test denominator with 0xffff0000 */
+ extrs retreg,15,16,retreg /* retreg = retreg >> 16 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 16) */
+ ldi 0xcc,temp1 /* setup 0xcc in temp1 */
+ extru,= arg1,23,8,temp /* test denominator with 0xff00 */
+ extrs retreg,23,24,retreg /* retreg = retreg >> 8 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 8) */
+ ldi 0xaa,temp /* setup 0xaa in temp */
+ extru,= arg1,27,4,r0 /* test denominator with 0xf0 */
+ extrs retreg,27,28,retreg /* retreg = retreg >> 4 */
+ and,= arg1,temp1,r0 /* test denominator with 0xcc */
+ extrs retreg,29,30,retreg /* retreg = retreg >> 2 */
+ and,= arg1,temp,r0 /* test denominator with 0xaa */
+ extrs retreg,30,31,retreg /* retreg = retreg >> 1 */
+ MILLIRETN
+LSYM(neg_denom)
+ addi,< 0,arg1,r0 /* if arg1 >= 0, it's not power of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg1,temp /* make denominator positive */
+ comb,=,n arg1,temp,LREF(regular_seq) /* test against 0x80000000 and 0 */
+ ldo -1(temp),retreg /* is there at most one bit set ? */
+ and,= temp,retreg,r0 /* if so, the denominator is power of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg0,retreg /* negate numerator */
+ comb,=,n arg0,retreg,LREF(regular_seq) /* test against 0x80000000 */
+ copy retreg,arg0 /* set up arg0, arg1 and temp */
+ copy temp,arg1 /* before branching to pow2 */
+ b LREF(pow2)
+ ldo -1(arg1),temp
+LSYM(regular_seq)
+ comib,>>=,n 15,arg1,LREF(small_divisor)
+ add,>= 0,arg0,retreg /* move dividend, if retreg < 0, */
+LSYM(normal)
+ subi 0,retreg,retreg /* make it positive */
+ sub 0,arg1,temp /* clear carry, */
+ /* negate the divisor */
+ ds 0,temp,0 /* set V-bit to the comple- */
+ /* ment of the divisor sign */
+ add retreg,retreg,retreg /* shift msb bit into carry */
+ ds r0,arg1,temp /* 1st divide step, if no carry */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 32nd divide step, */
+ addc retreg,retreg,retreg /* shift last retreg bit into retreg */
+ xor,>= arg0,arg1,0 /* get correct sign of quotient */
+ sub 0,retreg,retreg /* based on operand signs */
+ MILLIRETN
+ nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register. We are working with */
+/* small divisors (and 32-bit integers) We must not be mislead */
+/* by "1" bits left in the upper 32 bits. */
+ depd %r0,31,32,%r25
+#endif
+ blr,n arg1,r0
+ nop
+/* table for divisor == 0,1, ... ,15 */
+ addit,= 0,arg1,r0 /* trap if divisor == 0 */
+ nop
+ MILLIRET /* divisor == 1 */
+ copy arg0,retreg
+ MILLI_BEN($$divI_2) /* divisor == 2 */
+ nop
+ MILLI_BEN($$divI_3) /* divisor == 3 */
+ nop
+ MILLI_BEN($$divI_4) /* divisor == 4 */
+ nop
+ MILLI_BEN($$divI_5) /* divisor == 5 */
+ nop
+ MILLI_BEN($$divI_6) /* divisor == 6 */
+ nop
+ MILLI_BEN($$divI_7) /* divisor == 7 */
+ nop
+ MILLI_BEN($$divI_8) /* divisor == 8 */
+ nop
+ MILLI_BEN($$divI_9) /* divisor == 9 */
+ nop
+ MILLI_BEN($$divI_10) /* divisor == 10 */
+ nop
+ b LREF(normal) /* divisor == 11 */
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_12) /* divisor == 12 */
+ nop
+ b LREF(normal) /* divisor == 13 */
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_14) /* divisor == 14 */
+ nop
+ MILLI_BEN($$divI_15) /* divisor == 15 */
+ nop
+
+LSYM(negative1)
+ sub 0,arg0,retreg /* result is negation of dividend */
+ MILLIRET
+ addo arg0,arg1,r0 /* trap iff dividend==0x80000000 && divisor==-1 */
+ .exit
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/divU.S b/arch/parisc/lib/milli/divU.S
new file mode 100644
index 00000000000..9287fe2546f
--- /dev/null
+++ b/arch/parisc/lib/milli/divU.S
@@ -0,0 +1,235 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_divU
+/* ROUTINE: $$divU
+ .
+ . Single precision divide for unsigned integers.
+ .
+ . Quotient is truncated towards zero.
+ . Traps on divide by zero.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions:
+ . divisor is zero
+ . Changes memory at the following places:
+ . NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Branchs to other millicode routines using BE:
+ . $$divU_# for 3,5,6,7,9,10,12,14,15
+ .
+ . For selected small divisors calls the special divide by constant
+ . routines written by Karl Pettis. These are: 3,5,6,7,9,10,12,14,15. */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1) /* r29 */
+RDEFINE(temp1,arg0)
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+ .export $$divU,millicode
+ .import $$divU_3,millicode
+ .import $$divU_5,millicode
+ .import $$divU_6,millicode
+ .import $$divU_7,millicode
+ .import $$divU_9,millicode
+ .import $$divU_10,millicode
+ .import $$divU_12,millicode
+ .import $$divU_14,millicode
+ .import $$divU_15,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+ by the two cases that branch back to "normal". */
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,= arg1,temp,r0 /* if so, denominator is power of 2 */
+ b LREF(regular_seq)
+ addit,= 0,arg1,0 /* trap for zero dvr */
+ copy arg0,retreg
+ extru,= arg1,15,16,temp /* test denominator with 0xffff0000 */
+ extru retreg,15,16,retreg /* retreg = retreg >> 16 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 16) */
+ ldi 0xcc,temp1 /* setup 0xcc in temp1 */
+ extru,= arg1,23,8,temp /* test denominator with 0xff00 */
+ extru retreg,23,24,retreg /* retreg = retreg >> 8 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 8) */
+ ldi 0xaa,temp /* setup 0xaa in temp */
+ extru,= arg1,27,4,r0 /* test denominator with 0xf0 */
+ extru retreg,27,28,retreg /* retreg = retreg >> 4 */
+ and,= arg1,temp1,r0 /* test denominator with 0xcc */
+ extru retreg,29,30,retreg /* retreg = retreg >> 2 */
+ and,= arg1,temp,r0 /* test denominator with 0xaa */
+ extru retreg,30,31,retreg /* retreg = retreg >> 1 */
+ MILLIRETN
+ nop
+LSYM(regular_seq)
+ comib,>= 15,arg1,LREF(special_divisor)
+ subi 0,arg1,temp /* clear carry, negate the divisor */
+ ds r0,temp,r0 /* set V-bit to 1 */
+LSYM(normal)
+ add arg0,arg0,retreg /* shift msb bit into carry */
+ ds r0,arg1,temp /* 1st divide step, if no carry */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 32nd divide step, */
+ MILLIRET
+ addc retreg,retreg,retreg /* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on. */
+LSYM(special_divisor)
+/* blr arg1,r0 */
+/* comib,>,n 0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+ generating such a blr, comib sequence. A problem in nullification. So I
+ rewrote this code. */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register. We are working with
+ small divisors (and 32-bit unsigned integers) We must not be mislead
+ by "1" bits left in the upper 32 bits. */
+ depd %r0,31,32,%r25
+#endif
+ comib,> 0,arg1,LREF(big_divisor)
+ nop
+ blr arg1,r0
+ nop
+
+LSYM(zero_divisor) /* this label is here to provide external visibility */
+ addit,= 0,arg1,0 /* trap for zero dvr */
+ nop
+ MILLIRET /* divisor == 1 */
+ copy arg0,retreg
+ MILLIRET /* divisor == 2 */
+ extru arg0,30,31,retreg
+ MILLI_BEN($$divU_3) /* divisor == 3 */
+ nop
+ MILLIRET /* divisor == 4 */
+ extru arg0,29,30,retreg
+ MILLI_BEN($$divU_5) /* divisor == 5 */
+ nop
+ MILLI_BEN($$divU_6) /* divisor == 6 */
+ nop
+ MILLI_BEN($$divU_7) /* divisor == 7 */
+ nop
+ MILLIRET /* divisor == 8 */
+ extru arg0,28,29,retreg
+ MILLI_BEN($$divU_9) /* divisor == 9 */
+ nop
+ MILLI_BEN($$divU_10) /* divisor == 10 */
+ nop
+ b LREF(normal) /* divisor == 11 */
+ ds r0,temp,r0 /* set V-bit to 1 */
+ MILLI_BEN($$divU_12) /* divisor == 12 */
+ nop
+ b LREF(normal) /* divisor == 13 */
+ ds r0,temp,r0 /* set V-bit to 1 */
+ MILLI_BEN($$divU_14) /* divisor == 14 */
+ nop
+ MILLI_BEN($$divU_15) /* divisor == 15 */
+ nop
+
+/* Handle the case where the high bit is on in the divisor.
+ Compute: if( dividend>=divisor) quotient=1; else quotient=0;
+ Note: dividend>==divisor iff dividend-divisor does not borrow
+ and not borrow iff carry. */
+LSYM(big_divisor)
+ sub arg0,arg1,r0
+ MILLIRET
+ addc r0,r0,retreg
+ .exit
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/div_const.S b/arch/parisc/lib/milli/div_const.S
new file mode 100644
index 00000000000..dd660076e94
--- /dev/null
+++ b/arch/parisc/lib/milli/div_const.S
@@ -0,0 +1,682 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_div_const
+/* ROUTINE: $$divI_2
+ . $$divI_3 $$divU_3
+ . $$divI_4
+ . $$divI_5 $$divU_5
+ . $$divI_6 $$divU_6
+ . $$divI_7 $$divU_7
+ . $$divI_8
+ . $$divI_9 $$divU_9
+ . $$divI_10 $$divU_10
+ .
+ . $$divI_12 $$divU_12
+ .
+ . $$divI_14 $$divU_14
+ . $$divI_15 $$divU_15
+ . $$divI_16
+ . $$divI_17 $$divU_17
+ .
+ . Divide by selected constants for single precision binary integers.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: NONE
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Calls other millicode routines using mrp: NONE
+ . Calls other millicode routines: NONE */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+ We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+ (with y fixed).
+
+ Let a = floor(z/y), for some choice of z. Note that z will be
+ chosen so that division by z is cheap.
+
+ Let r be the remainder(z/y). In other words, r = z - ay.
+
+ Now, our method is to choose a value for b such that
+
+ q'(x) = floor((ax+b)/z)
+
+ is equal to q(x) over as large a range of x as possible. If the
+ two are equal over a sufficiently large range, and if it is easy to
+ form the product (ax), and it is easy to divide by z, then we can
+ perform the division much faster than the general division algorithm.
+
+ So, we want the following to be true:
+
+ . For x in the following range:
+ .
+ . ky <= x < (k+1)y
+ .
+ . implies that
+ .
+ . k <= (ax+b)/z < (k+1)
+
+ We want to determine b such that this is true for all k in the
+ range {0..K} for some maximum K.
+
+ Since (ax+b) is an increasing function of x, we can take each
+ bound separately to determine the "best" value for b.
+
+ (ax+b)/z < (k+1) implies
+
+ (a((k+1)y-1)+b < (k+1)z implies
+
+ b < a + (k+1)(z-ay) implies
+
+ b < a + (k+1)r
+
+ This needs to be true for all k in the range {0..K}. In
+ particular, it is true for k = 0 and this leads to a maximum
+ acceptable value for b.
+
+ b < a+r or b <= a+r-1
+
+ Taking the other bound, we have
+
+ k <= (ax+b)/z implies
+
+ k <= (aky+b)/z implies
+
+ k(z-ay) <= b implies
+
+ kr <= b
+
+ Clearly, the largest range for k will be achieved by maximizing b,
+ when r is not zero. When r is zero, then the simplest choice for b
+ is 0. When r is not 0, set
+
+ . b = a+r-1
+
+ Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+ for all x in the range:
+
+ . 0 <= x < (K+1)y
+
+ We need to determine what K is. Of our two bounds,
+
+ . b < a+(k+1)r is satisfied for all k >= 0, by construction.
+
+ The other bound is
+
+ . kr <= b
+
+ This is always true if r = 0. If r is not 0 (the usual case), then
+ K = floor((a+r-1)/r), is the maximum value for k.
+
+ Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+ answer for q(x) = floor(x/y) when x is in the range
+
+ (0,(K+1)y-1) K = floor((a+r-1)/r)
+
+ To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+ the formula for q'(x) yields the correct value of q(x) for all x
+ representable by a single word in HPPA.
+
+ We are also constrained in that computing the product (ax), adding
+ b, and dividing by z must all be done quickly, otherwise we will be
+ better off going through the general algorithm using the DS
+ instruction, which uses approximately 70 cycles.
+
+ For each y, there is a choice of z which satisfies the constraints
+ for (K+1)y >= 2**32. We may not, however, be able to satisfy the
+ timing constraints for arbitrary y. It seems that z being equal to
+ a power of 2 or a power of 2 minus 1 is as good as we can do, since
+ it minimizes the time to do division by z. We want the choice of z
+ to also result in a value for (a) that minimizes the computation of
+ the product (ax). This is best achieved if (a) has a regular bit
+ pattern (so the multiplication can be done with shifts and adds).
+ The value of (a) also needs to be less than 2**32 so the product is
+ always guaranteed to fit in 2 words.
+
+ In actual practice, the following should be done:
+
+ 1) For negative x, you should take the absolute value and remember
+ . the fact so that the result can be negated. This obviously does
+ . not apply in the unsigned case.
+ 2) For even y, you should factor out the power of 2 that divides y
+ . and divide x by it. You can then proceed by dividing by the
+ . odd factor of y.
+
+ Here is a table of some odd values of y, and corresponding choices
+ for z which are "good".
+
+ y z r a (hex) max x (hex)
+
+ 3 2**32 1 55555555 100000001
+ 5 2**32 1 33333333 100000003
+ 7 2**24-1 0 249249 (infinite)
+ 9 2**24-1 0 1c71c7 (infinite)
+ 11 2**20-1 0 1745d (infinite)
+ 13 2**24-1 0 13b13b (infinite)
+ 15 2**32 1 11111111 10000000d
+ 17 2**32 1 f0f0f0f 10000000f
+
+ If r is 1, then b = a+r-1 = a. This simplifies the computation
+ of (ax+b), since you can compute (x+1)(a) instead. If r is 0,
+ then b = 0 is ok to use which simplifies (ax+b).
+
+ The bit patterns for 55555555, 33333333, and 11111111 are obviously
+ very regular. The bit patterns for the other values of a above are:
+
+ y (hex) (binary)
+
+ 7 249249 001001001001001001001001 << regular >>
+ 9 1c71c7 000111000111000111000111 << regular >>
+ 11 1745d 000000010111010001011101 << irregular >>
+ 13 13b13b 000100111011000100111011 << irregular >>
+
+ The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+ too irregular to warrant using this method.
+
+ When z is a power of 2 minus 1, then the division by z is slightly
+ more complicated, involving an iterative solution.
+
+ The code presented here solves division by 1 through 17, except for
+ 11 and 13. There are algorithms for both signed and unsigned
+ quantities given.
+
+ TIMINGS (cycles)
+
+ divisor positive negative unsigned
+
+ . 1 2 2 2
+ . 2 4 4 2
+ . 3 19 21 19
+ . 4 4 4 2
+ . 5 18 22 19
+ . 6 19 22 19
+ . 8 4 4 2
+ . 10 18 19 17
+ . 12 18 20 18
+ . 15 16 18 16
+ . 16 4 4 2
+ . 17 16 18 16
+
+ Now, the algorithm for 7, 9, and 14 is an iterative one. That is,
+ a loop body is executed until the tentative quotient is 0. The
+ number of times the loop body is executed varies depending on the
+ dividend, but is never more than two times. If the dividend is
+ less than the divisor, then the loop body is not executed at all.
+ Each iteration adds 4 cycles to the timings.
+
+ divisor positive negative unsigned
+
+ . 7 19+4n 20+4n 20+4n n = number of iterations
+ . 9 21+4n 22+4n 21+4n
+ . 14 21+4n 22+4n 20+4n
+
+ To give an idea of how the number of iterations varies, here is a
+ table of dividend versus number of iterations when dividing by 7.
+
+ smallest largest required
+ dividend dividend iterations
+
+ . 0 6 0
+ . 7 0x6ffffff 1
+ 0x1000006 0xffffffff 2
+
+ There is some overlap in the range of numbers requiring 1 and 2
+ iterations. */
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0) /* r26 */
+RDEFINE(t1,arg1) /* r25 */
+RDEFINE(x1,ret1) /* r29 */
+
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+
+ .proc
+ .callinfo millicode
+ .entry
+/* NONE of these routines require a stack frame
+ ALL of these routines are unwindable from millicode */
+
+GSYM($$divide_by_constant)
+ .export $$divide_by_constant,millicode
+/* Provides a "nice" label for the code covered by the unwind descriptor
+ for things like gprof. */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+ .export $$divI_2,millicode
+ comclr,>= arg0,0,0
+ addi 1,arg0,arg0
+ MILLIRET
+ extrs arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+ .export $$divI_4,millicode
+ comclr,>= arg0,0,0
+ addi 3,arg0,arg0
+ MILLIRET
+ extrs arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+ .export $$divI_8,millicode
+ comclr,>= arg0,0,0
+ addi 7,arg0,arg0
+ MILLIRET
+ extrs arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+ .export $$divI_16,millicode
+ comclr,>= arg0,0,0
+ addi 15,arg0,arg0
+ MILLIRET
+ extrs arg0,27,28,ret1
+
+/****************************************************************************
+*
+* DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+* includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+ .export $$divI_3,millicode
+ comb,<,N x2,0,LREF(neg3)
+
+ addi 1,x2,x2 /* this cannot overflow */
+ extru x2,1,2,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,0,x1
+
+LSYM(neg3)
+ subi 1,x2,x2 /* this cannot overflow */
+ extru x2,1,2,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_3)
+ .export $$divU_3,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,30,t1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+ .export $$divI_5,millicode
+ comb,<,N x2,0,LREF(neg5)
+
+ addi 3,x2,t1 /* this cannot overflow */
+ sh1add x2,t1,x2 /* multiply by 3 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+LSYM(neg5)
+ sub 0,x2,x2 /* negate x2 */
+ addi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,31,x1 /* get top bit (can be 1) */
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_5)
+ .export $$divU_5,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,31,t1 /* multiply by 3 to get started */
+ sh1add x2,x2,x2
+ b LREF(pos)
+ addc t1,x1,x1
+
+/* DIVISION BY 6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+ .export $$divI_6,millicode
+ comb,<,N x2,0,LREF(neg6)
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 5,x2,t1 /* compute 5*(x2+1) = 5*x2+5 */
+ sh2add x2,t1,x2 /* multiply by 5 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+LSYM(neg6)
+ subi 2,x2,x2 /* negate, divide by 2, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,30,31,x2
+ shd 0,x2,30,x1
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_6)
+ .export $$divU_6,millicode
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 1,x2,x2 /* cannot carry */
+ shd 0,x2,30,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+ .export $$divU_10,millicode
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 3,x2,t1 /* compute 3*(x2+1) = (3*x2)+3 */
+ sh1add x2,t1,x2 /* multiply by 3 to get started */
+ addc 0,0,x1
+LSYM(pos)
+ shd x1,x2,28,t1 /* multiply by 0x11 */
+ shd x2,0,28,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+LSYM(pos_for_17)
+ shd x1,x2,24,t1 /* multiply by 0x101 */
+ shd x2,0,24,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,16,t1 /* multiply by 0x10001 */
+ shd x2,0,16,t2
+ add x2,t2,x2
+ MILLIRET
+ addc x1,t1,x1
+
+GSYM($$divI_10)
+ .export $$divI_10,millicode
+ comb,< x2,0,LREF(neg10)
+ copy 0,x1
+ extru x2,30,31,x2 /* divide by 2 */
+ addib,TR 1,x2,LREF(pos) /* add 1 (cannot overflow) */
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+
+LSYM(neg10)
+ subi 2,x2,x2 /* negate, divide by 2, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,30,31,x2
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+LSYM(neg)
+ shd x1,x2,28,t1 /* multiply by 0x11 */
+ shd x2,0,28,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+LSYM(neg_for_17)
+ shd x1,x2,24,t1 /* multiply by 0x101 */
+ shd x2,0,24,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,16,t1 /* multiply by 0x10001 */
+ shd x2,0,16,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+ MILLIRET
+ sub 0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+ .export $$divI_12,millicode
+ comb,< x2,0,LREF(neg12)
+ copy 0,x1
+ extru x2,29,30,x2 /* divide by 4 */
+ addib,tr 1,x2,LREF(pos) /* compute 5*(x2+1) = 5*x2+5 */
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+
+LSYM(neg12)
+ subi 4,x2,x2 /* negate, divide by 4, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,29,30,x2
+ b LREF(neg)
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+
+GSYM($$divU_12)
+ .export $$divU_12,millicode
+ extru x2,29,30,x2 /* divide by 4 */
+ addi 5,x2,t1 /* cannot carry */
+ sh2add x2,t1,x2 /* multiply by 5 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+ .export $$divI_15,millicode
+ comb,< x2,0,LREF(neg15)
+ copy 0,x1
+ addib,tr 1,x2,LREF(pos)+4
+ shd x1,x2,28,t1
+
+LSYM(neg15)
+ b LREF(neg)
+ subi 1,x2,x2
+
+GSYM($$divU_15)
+ .export $$divU_15,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ b LREF(pos)
+ addc 0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a = f0f0f0f) */
+GSYM($$divI_17)
+ .export $$divI_17,millicode
+ comb,<,n x2,0,LREF(neg17)
+ addi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,28,t1 /* multiply by 0xf to get started */
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(pos_for_17)
+ subb t1,0,x1
+
+LSYM(neg17)
+ subi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,28,t1 /* multiply by 0xf to get started */
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(neg_for_17)
+ subb t1,0,x1
+
+GSYM($$divU_17)
+ .export $$divU_17,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,28,t1 /* multiply by 0xf to get started */
+LSYM(u17)
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(pos_for_17)
+ subb t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+ includes 7,9 and also 14
+
+
+ z = 2**24-1
+ r = z mod x = 0
+
+ so choose b = 0
+
+ Also, in order to divide by z = 2**24-1, we approximate by dividing
+ by (z+1) = 2**24 (which is easy), and then correcting.
+
+ (ax) = (z+1)q' + r
+ . = zq' + (q'+r)
+
+ So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+ Then the true remainder of (ax)/z is (q'+r). Repeat the process
+ with this new remainder, adding the tentative quotients together,
+ until a tentative quotient is 0 (and then we are done). There is
+ one last correction to be done. It is possible that (q'+r) = z.
+ If so, then (q'+r)/(z+1) = 0 and it looks like we are done. But,
+ in fact, we need to add 1 more to the quotient. Now, it turns
+ out that this happens if and only if the original value x is
+ an exact multiple of y. So, to avoid a three instruction test at
+ the end, instead use 1 instruction to add 1 to x at the beginning. */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+ .export $$divI_7,millicode
+ comb,<,n x2,0,LREF(neg7)
+LSYM(7)
+ addi 1,x2,x2 /* cannot overflow */
+ shd 0,x2,29,x1
+ sh3add x2,x2,x2
+ addc x1,0,x1
+LSYM(pos7)
+ shd x1,x2,26,t1
+ shd x2,0,26,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,20,t1
+ shd x2,0,20,t2
+ add x2,t2,x2
+ addc x1,t1,t1
+
+ /* computed <t1,x2>. Now divide it by (2**24 - 1) */
+
+ copy 0,x1
+ shd,= t1,x2,24,t1 /* tentative quotient */
+LSYM(1)
+ addb,tr t1,x1,LREF(2) /* add to previous quotient */
+ extru x2,31,24,x2 /* new remainder (unadjusted) */
+
+ MILLIRETN
+
+LSYM(2)
+ addb,tr t1,x2,LREF(1) /* adjust remainder */
+ extru,= x2,7,8,t1 /* new quotient */
+
+LSYM(neg7)
+ subi 1,x2,x2 /* negate x2 and add 1 */
+LSYM(8)
+ shd 0,x2,29,x1
+ sh3add x2,x2,x2
+ addc x1,0,x1
+
+LSYM(neg7_shift)
+ shd x1,x2,26,t1
+ shd x2,0,26,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,20,t1
+ shd x2,0,20,t2
+ add x2,t2,x2
+ addc x1,t1,t1
+
+ /* computed <t1,x2>. Now divide it by (2**24 - 1) */
+
+ copy 0,x1
+ shd,= t1,x2,24,t1 /* tentative quotient */
+LSYM(3)
+ addb,tr t1,x1,LREF(4) /* add to previous quotient */
+ extru x2,31,24,x2 /* new remainder (unadjusted) */
+
+ MILLIRET
+ sub 0,x1,x1 /* negate result */
+
+LSYM(4)
+ addb,tr t1,x2,LREF(3) /* adjust remainder */
+ extru,= x2,7,8,t1 /* new quotient */
+
+GSYM($$divU_7)
+ .export $$divU_7,millicode
+ addi 1,x2,x2 /* can carry */
+ addc 0,0,x1
+ shd x1,x2,29,t1
+ sh3add x2,x2,x2
+ b LREF(pos7)
+ addc t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+ .export $$divI_9,millicode
+ comb,<,n x2,0,LREF(neg9)
+ addi 1,x2,x2 /* cannot overflow */
+ shd 0,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(pos7)
+ subb t1,0,x1
+
+LSYM(neg9)
+ subi 1,x2,x2 /* negate and add 1 */
+ shd 0,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(neg7_shift)
+ subb t1,0,x1
+
+GSYM($$divU_9)
+ .export $$divU_9,millicode
+ addi 1,x2,x2 /* can carry */
+ addc 0,0,x1
+ shd x1,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(pos7)
+ subb t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+ .export $$divI_14,millicode
+ comb,<,n x2,0,LREF(neg14)
+GSYM($$divU_14)
+ .export $$divU_14,millicode
+ b LREF(7) /* go to 7 case */
+ extru x2,30,31,x2 /* divide by 2 */
+
+LSYM(neg14)
+ subi 2,x2,x2 /* negate (and add 2) */
+ b LREF(8)
+ extru x2,30,31,x2 /* divide by 2 */
+ .exit
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/dyncall.S b/arch/parisc/lib/milli/dyncall.S
new file mode 100644
index 00000000000..27f9ca558d0
--- /dev/null
+++ b/arch/parisc/lib/milli/dyncall.S
@@ -0,0 +1,32 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_dyncall
+ SUBSPA_MILLI
+ ATTR_DATA
+GSYM($$dyncall)
+ .export $$dyncall,millicode
+ .proc
+ .callinfo millicode
+ .entry
+ bb,>=,n %r22,30,LREF(1) ; branch if not plabel address
+ depi 0,31,2,%r22 ; clear the two least significant bits
+ ldw 4(%r22),%r19 ; load new LTP value
+ ldw 0(%r22),%r22 ; load address of target
+LSYM(1)
+ bv %r0(%r22) ; branch to the real target
+ stw %r2,-24(%r30) ; save return address into frame marker
+ .exit
+ .procend
+#endif
diff --git a/arch/parisc/lib/milli/milli.S b/arch/parisc/lib/milli/milli.S
new file mode 100644
index 00000000000..47c6cde712e
--- /dev/null
+++ b/arch/parisc/lib/milli/milli.S
@@ -0,0 +1,2071 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#ifdef CONFIG_64BIT
+ .level 2.0w
+#endif
+
+/* Hardware General Registers. */
+r0: .reg %r0
+r1: .reg %r1
+r2: .reg %r2
+r3: .reg %r3
+r4: .reg %r4
+r5: .reg %r5
+r6: .reg %r6
+r7: .reg %r7
+r8: .reg %r8
+r9: .reg %r9
+r10: .reg %r10
+r11: .reg %r11
+r12: .reg %r12
+r13: .reg %r13
+r14: .reg %r14
+r15: .reg %r15
+r16: .reg %r16
+r17: .reg %r17
+r18: .reg %r18
+r19: .reg %r19
+r20: .reg %r20
+r21: .reg %r21
+r22: .reg %r22
+r23: .reg %r23
+r24: .reg %r24
+r25: .reg %r25
+r26: .reg %r26
+r27: .reg %r27
+r28: .reg %r28
+r29: .reg %r29
+r30: .reg %r30
+r31: .reg %r31
+
+/* Hardware Space Registers. */
+sr0: .reg %sr0
+sr1: .reg %sr1
+sr2: .reg %sr2
+sr3: .reg %sr3
+sr4: .reg %sr4
+sr5: .reg %sr5
+sr6: .reg %sr6
+sr7: .reg %sr7
+
+/* Hardware Floating Point Registers. */
+fr0: .reg %fr0
+fr1: .reg %fr1
+fr2: .reg %fr2
+fr3: .reg %fr3
+fr4: .reg %fr4
+fr5: .reg %fr5
+fr6: .reg %fr6
+fr7: .reg %fr7
+fr8: .reg %fr8
+fr9: .reg %fr9
+fr10: .reg %fr10
+fr11: .reg %fr11
+fr12: .reg %fr12
+fr13: .reg %fr13
+fr14: .reg %fr14
+fr15: .reg %fr15
+
+/* Hardware Control Registers. */
+cr11: .reg %cr11
+sar: .reg %cr11 /* Shift Amount Register */
+
+/* Software Architecture General Registers. */
+rp: .reg r2 /* return pointer */
+#ifdef CONFIG_64BIT
+mrp: .reg r2 /* millicode return pointer */
+#else
+mrp: .reg r31 /* millicode return pointer */
+#endif
+ret0: .reg r28 /* return value */
+ret1: .reg r29 /* return value (high part of double) */
+sp: .reg r30 /* stack pointer */
+dp: .reg r27 /* data pointer */
+arg0: .reg r26 /* argument */
+arg1: .reg r25 /* argument or high part of double argument */
+arg2: .reg r24 /* argument */
+arg3: .reg r23 /* argument or high part of double argument */
+
+/* Software Architecture Space Registers. */
+/* sr0 ; return link from BLE */
+sret: .reg sr1 /* return value */
+sarg: .reg sr1 /* argument */
+/* sr4 ; PC SPACE tracker */
+/* sr5 ; process private data */
+
+/* Frame Offsets (millicode convention!) Used when calling other
+ millicode routines. Stack unwinding is dependent upon these
+ definitions. */
+r31_slot: .equ -20 /* "current RP" slot */
+sr0_slot: .equ -16 /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot: .equ -16 /* "current RP" slot */
+psp_slot: .equ -8 /* "previous SP" slot */
+#else
+mrp_slot: .equ -20 /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name: .EQU value
+#define RDEFINE(name,value)name: .REG value
+#ifdef milliext
+#define MILLI_BE(lbl) BE lbl(sr7,r0)
+#define MILLI_BEN(lbl) BE,n lbl(sr7,r0)
+#define MILLI_BLE(lbl) BLE lbl(sr7,r0)
+#define MILLI_BLEN(lbl) BLE,n lbl(sr7,r0)
+#define MILLIRETN BE,n 0(sr0,mrp)
+#define MILLIRET BE 0(sr0,mrp)
+#define MILLI_RETN BE,n 0(sr0,mrp)
+#define MILLI_RET BE 0(sr0,mrp)
+#else
+#define MILLI_BE(lbl) B lbl
+#define MILLI_BEN(lbl) B,n lbl
+#define MILLI_BLE(lbl) BL lbl,mrp
+#define MILLI_BLEN(lbl) BL,n lbl,mrp
+#define MILLIRETN BV,n 0(mrp)
+#define MILLIRET BV 0(mrp)
+#define MILLI_RETN BV,n 0(mrp)
+#define MILLI_RET BV 0(mrp)
+#endif
+
+#define CAT(a,b) a##b
+
+#define SUBSPA_MILLI .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA .section .data
+#define ATTR_DATA
+#define GLOBAL $global$
+#define GSYM(sym) !sym:
+#define LSYM(sym) !CAT(.L,sym:)
+#define LREF(sym) CAT(.L,sym)
+
+#ifdef L_dyncall
+ SUBSPA_MILLI
+ ATTR_DATA
+GSYM($$dyncall)
+ .export $$dyncall,millicode
+ .proc
+ .callinfo millicode
+ .entry
+ bb,>=,n %r22,30,LREF(1) ; branch if not plabel address
+ depi 0,31,2,%r22 ; clear the two least significant bits
+ ldw 4(%r22),%r19 ; load new LTP value
+ ldw 0(%r22),%r22 ; load address of target
+LSYM(1)
+ bv %r0(%r22) ; branch to the real target
+ stw %r2,-24(%r30) ; save return address into frame marker
+ .exit
+ .procend
+#endif
+
+#ifdef L_divI
+/* ROUTINES: $$divI, $$divoI
+
+ Single precision divide for signed binary integers.
+
+ The quotient is truncated towards zero.
+ The sign of the quotient is the XOR of the signs of the dividend and
+ divisor.
+ Divide by zero is trapped.
+ Divide of -2**31 by -1 is trapped for $$divoI but not for $$divI.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions:
+ . divisor is zero (traps with ADDIT,= 0,25,0)
+ . dividend==-2**31 and divisor==-1 and routine is $$divoI
+ . (traps with ADDO 26,25,0)
+ . Changes memory at the following places:
+ . NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Branchs to other millicode routines using BE
+ . $$div_# for # being 2,3,4,5,6,7,8,9,10,12,14,15
+ .
+ . For selected divisors, calls a divide by constant routine written by
+ . Karl Pettis. Eligible divisors are 1..15 excluding 11 and 13.
+ .
+ . The only overflow case is -2**31 divided by -1.
+ . Both routines return -2**31 but only $$divoI traps. */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1) /* r29 */
+RDEFINE(temp1,arg0)
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+ .import $$divI_2,millicode
+ .import $$divI_3,millicode
+ .import $$divI_4,millicode
+ .import $$divI_5,millicode
+ .import $$divI_6,millicode
+ .import $$divI_7,millicode
+ .import $$divI_8,millicode
+ .import $$divI_9,millicode
+ .import $$divI_10,millicode
+ .import $$divI_12,millicode
+ .import $$divI_14,millicode
+ .import $$divI_15,millicode
+ .export $$divI,millicode
+ .export $$divoI,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$divoI)
+ comib,=,n -1,arg1,LREF(negative1) /* when divisor == -1 */
+GSYM($$divI)
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,<> arg1,temp,r0 /* if not, don't use power of 2 divide */
+ addi,> 0,arg1,r0 /* if divisor > 0, use power of 2 divide */
+ b,n LREF(neg_denom)
+LSYM(pow2)
+ addi,>= 0,arg0,retreg /* if numerator is negative, add the */
+ add arg0,temp,retreg /* (denominaotr -1) to correct for shifts */
+ extru,= arg1,15,16,temp /* test denominator with 0xffff0000 */
+ extrs retreg,15,16,retreg /* retreg = retreg >> 16 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 16) */
+ ldi 0xcc,temp1 /* setup 0xcc in temp1 */
+ extru,= arg1,23,8,temp /* test denominator with 0xff00 */
+ extrs retreg,23,24,retreg /* retreg = retreg >> 8 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 8) */
+ ldi 0xaa,temp /* setup 0xaa in temp */
+ extru,= arg1,27,4,r0 /* test denominator with 0xf0 */
+ extrs retreg,27,28,retreg /* retreg = retreg >> 4 */
+ and,= arg1,temp1,r0 /* test denominator with 0xcc */
+ extrs retreg,29,30,retreg /* retreg = retreg >> 2 */
+ and,= arg1,temp,r0 /* test denominator with 0xaa */
+ extrs retreg,30,31,retreg /* retreg = retreg >> 1 */
+ MILLIRETN
+LSYM(neg_denom)
+ addi,< 0,arg1,r0 /* if arg1 >= 0, it's not power of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg1,temp /* make denominator positive */
+ comb,=,n arg1,temp,LREF(regular_seq) /* test against 0x80000000 and 0 */
+ ldo -1(temp),retreg /* is there at most one bit set ? */
+ and,= temp,retreg,r0 /* if so, the denominator is power of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg0,retreg /* negate numerator */
+ comb,=,n arg0,retreg,LREF(regular_seq) /* test against 0x80000000 */
+ copy retreg,arg0 /* set up arg0, arg1 and temp */
+ copy temp,arg1 /* before branching to pow2 */
+ b LREF(pow2)
+ ldo -1(arg1),temp
+LSYM(regular_seq)
+ comib,>>=,n 15,arg1,LREF(small_divisor)
+ add,>= 0,arg0,retreg /* move dividend, if retreg < 0, */
+LSYM(normal)
+ subi 0,retreg,retreg /* make it positive */
+ sub 0,arg1,temp /* clear carry, */
+ /* negate the divisor */
+ ds 0,temp,0 /* set V-bit to the comple- */
+ /* ment of the divisor sign */
+ add retreg,retreg,retreg /* shift msb bit into carry */
+ ds r0,arg1,temp /* 1st divide step, if no carry */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 32nd divide step, */
+ addc retreg,retreg,retreg /* shift last retreg bit into retreg */
+ xor,>= arg0,arg1,0 /* get correct sign of quotient */
+ sub 0,retreg,retreg /* based on operand signs */
+ MILLIRETN
+ nop
+
+LSYM(small_divisor)
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register. We are working with */
+/* small divisors (and 32-bit integers) We must not be mislead */
+/* by "1" bits left in the upper 32 bits. */
+ depd %r0,31,32,%r25
+#endif
+ blr,n arg1,r0
+ nop
+/* table for divisor == 0,1, ... ,15 */
+ addit,= 0,arg1,r0 /* trap if divisor == 0 */
+ nop
+ MILLIRET /* divisor == 1 */
+ copy arg0,retreg
+ MILLI_BEN($$divI_2) /* divisor == 2 */
+ nop
+ MILLI_BEN($$divI_3) /* divisor == 3 */
+ nop
+ MILLI_BEN($$divI_4) /* divisor == 4 */
+ nop
+ MILLI_BEN($$divI_5) /* divisor == 5 */
+ nop
+ MILLI_BEN($$divI_6) /* divisor == 6 */
+ nop
+ MILLI_BEN($$divI_7) /* divisor == 7 */
+ nop
+ MILLI_BEN($$divI_8) /* divisor == 8 */
+ nop
+ MILLI_BEN($$divI_9) /* divisor == 9 */
+ nop
+ MILLI_BEN($$divI_10) /* divisor == 10 */
+ nop
+ b LREF(normal) /* divisor == 11 */
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_12) /* divisor == 12 */
+ nop
+ b LREF(normal) /* divisor == 13 */
+ add,>= 0,arg0,retreg
+ MILLI_BEN($$divI_14) /* divisor == 14 */
+ nop
+ MILLI_BEN($$divI_15) /* divisor == 15 */
+ nop
+
+LSYM(negative1)
+ sub 0,arg0,retreg /* result is negation of dividend */
+ MILLIRET
+ addo arg0,arg1,r0 /* trap iff dividend==0x80000000 && divisor==-1 */
+ .exit
+ .procend
+ .end
+#endif
+
+#ifdef L_divU
+/* ROUTINE: $$divU
+ .
+ . Single precision divide for unsigned integers.
+ .
+ . Quotient is truncated towards zero.
+ . Traps on divide by zero.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions:
+ . divisor is zero
+ . Changes memory at the following places:
+ . NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Branchs to other millicode routines using BE:
+ . $$divU_# for 3,5,6,7,9,10,12,14,15
+ .
+ . For selected small divisors calls the special divide by constant
+ . routines written by Karl Pettis. These are: 3,5,6,7,9,10,12,14,15. */
+
+RDEFINE(temp,r1)
+RDEFINE(retreg,ret1) /* r29 */
+RDEFINE(temp1,arg0)
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+ .export $$divU,millicode
+ .import $$divU_3,millicode
+ .import $$divU_5,millicode
+ .import $$divU_6,millicode
+ .import $$divU_7,millicode
+ .import $$divU_9,millicode
+ .import $$divU_10,millicode
+ .import $$divU_12,millicode
+ .import $$divU_14,millicode
+ .import $$divU_15,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$divU)
+/* The subtract is not nullified since it does no harm and can be used
+ by the two cases that branch back to "normal". */
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,= arg1,temp,r0 /* if so, denominator is power of 2 */
+ b LREF(regular_seq)
+ addit,= 0,arg1,0 /* trap for zero dvr */
+ copy arg0,retreg
+ extru,= arg1,15,16,temp /* test denominator with 0xffff0000 */
+ extru retreg,15,16,retreg /* retreg = retreg >> 16 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 16) */
+ ldi 0xcc,temp1 /* setup 0xcc in temp1 */
+ extru,= arg1,23,8,temp /* test denominator with 0xff00 */
+ extru retreg,23,24,retreg /* retreg = retreg >> 8 */
+ or arg1,temp,arg1 /* arg1 = arg1 | (arg1 >> 8) */
+ ldi 0xaa,temp /* setup 0xaa in temp */
+ extru,= arg1,27,4,r0 /* test denominator with 0xf0 */
+ extru retreg,27,28,retreg /* retreg = retreg >> 4 */
+ and,= arg1,temp1,r0 /* test denominator with 0xcc */
+ extru retreg,29,30,retreg /* retreg = retreg >> 2 */
+ and,= arg1,temp,r0 /* test denominator with 0xaa */
+ extru retreg,30,31,retreg /* retreg = retreg >> 1 */
+ MILLIRETN
+ nop
+LSYM(regular_seq)
+ comib,>= 15,arg1,LREF(special_divisor)
+ subi 0,arg1,temp /* clear carry, negate the divisor */
+ ds r0,temp,r0 /* set V-bit to 1 */
+LSYM(normal)
+ add arg0,arg0,retreg /* shift msb bit into carry */
+ ds r0,arg1,temp /* 1st divide step, if no carry */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds temp,arg1,temp /* 32nd divide step, */
+ MILLIRET
+ addc retreg,retreg,retreg /* shift last retreg bit into retreg */
+
+/* Handle the cases where divisor is a small constant or has high bit on. */
+LSYM(special_divisor)
+/* blr arg1,r0 */
+/* comib,>,n 0,arg1,LREF(big_divisor) ; nullify previous instruction */
+
+/* Pratap 8/13/90. The 815 Stirling chip set has a bug that prevents us from
+ generating such a blr, comib sequence. A problem in nullification. So I
+ rewrote this code. */
+
+#if defined(CONFIG_64BIT)
+/* Clear the upper 32 bits of the arg1 register. We are working with
+ small divisors (and 32-bit unsigned integers) We must not be mislead
+ by "1" bits left in the upper 32 bits. */
+ depd %r0,31,32,%r25
+#endif
+ comib,> 0,arg1,LREF(big_divisor)
+ nop
+ blr arg1,r0
+ nop
+
+LSYM(zero_divisor) /* this label is here to provide external visibility */
+ addit,= 0,arg1,0 /* trap for zero dvr */
+ nop
+ MILLIRET /* divisor == 1 */
+ copy arg0,retreg
+ MILLIRET /* divisor == 2 */
+ extru arg0,30,31,retreg
+ MILLI_BEN($$divU_3) /* divisor == 3 */
+ nop
+ MILLIRET /* divisor == 4 */
+ extru arg0,29,30,retreg
+ MILLI_BEN($$divU_5) /* divisor == 5 */
+ nop
+ MILLI_BEN($$divU_6) /* divisor == 6 */
+ nop
+ MILLI_BEN($$divU_7) /* divisor == 7 */
+ nop
+ MILLIRET /* divisor == 8 */
+ extru arg0,28,29,retreg
+ MILLI_BEN($$divU_9) /* divisor == 9 */
+ nop
+ MILLI_BEN($$divU_10) /* divisor == 10 */
+ nop
+ b LREF(normal) /* divisor == 11 */
+ ds r0,temp,r0 /* set V-bit to 1 */
+ MILLI_BEN($$divU_12) /* divisor == 12 */
+ nop
+ b LREF(normal) /* divisor == 13 */
+ ds r0,temp,r0 /* set V-bit to 1 */
+ MILLI_BEN($$divU_14) /* divisor == 14 */
+ nop
+ MILLI_BEN($$divU_15) /* divisor == 15 */
+ nop
+
+/* Handle the case where the high bit is on in the divisor.
+ Compute: if( dividend>=divisor) quotient=1; else quotient=0;
+ Note: dividend>==divisor iff dividend-divisor does not borrow
+ and not borrow iff carry. */
+LSYM(big_divisor)
+ sub arg0,arg1,r0
+ MILLIRET
+ addc r0,r0,retreg
+ .exit
+ .procend
+ .end
+#endif
+
+#ifdef L_remI
+/* ROUTINE: $$remI
+
+ DESCRIPTION:
+ . $$remI returns the remainder of the division of two signed 32-bit
+ . integers. The sign of the remainder is the same as the sign of
+ . the dividend.
+
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = destroyed
+ . arg1 = destroyed
+ . ret1 = remainder
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: DIVIDE BY ZERO
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable
+ . Does not create a stack frame
+ . Is usable for internal or external microcode
+
+ DISCUSSION:
+ . Calls other millicode routines via mrp: NONE
+ . Calls other millicode routines: NONE */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$remI)
+GSYM($$remoI)
+ .export $$remI,MILLICODE
+ .export $$remoI,MILLICODE
+ ldo -1(arg1),tmp /* is there at most one bit set ? */
+ and,<> arg1,tmp,r0 /* if not, don't use power of 2 */
+ addi,> 0,arg1,r0 /* if denominator > 0, use power */
+ /* of 2 */
+ b,n LREF(neg_denom)
+LSYM(pow2)
+ comb,>,n 0,arg0,LREF(neg_num) /* is numerator < 0 ? */
+ and arg0,tmp,retreg /* get the result */
+ MILLIRETN
+LSYM(neg_num)
+ subi 0,arg0,arg0 /* negate numerator */
+ and arg0,tmp,retreg /* get the result */
+ subi 0,retreg,retreg /* negate result */
+ MILLIRETN
+LSYM(neg_denom)
+ addi,< 0,arg1,r0 /* if arg1 >= 0, it's not power */
+ /* of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg1,tmp /* make denominator positive */
+ comb,=,n arg1,tmp,LREF(regular_seq) /* test against 0x80000000 and 0 */
+ ldo -1(tmp),retreg /* is there at most one bit set ? */
+ and,= tmp,retreg,r0 /* if not, go to regular_seq */
+ b,n LREF(regular_seq)
+ comb,>,n 0,arg0,LREF(neg_num_2) /* if arg0 < 0, negate it */
+ and arg0,retreg,retreg
+ MILLIRETN
+LSYM(neg_num_2)
+ subi 0,arg0,tmp /* test against 0x80000000 */
+ and tmp,retreg,retreg
+ subi 0,retreg,retreg
+ MILLIRETN
+LSYM(regular_seq)
+ addit,= 0,arg1,0 /* trap if div by zero */
+ add,>= 0,arg0,retreg /* move dividend, if retreg < 0, */
+ sub 0,retreg,retreg /* make it positive */
+ sub 0,arg1, tmp /* clear carry, */
+ /* negate the divisor */
+ ds 0, tmp,0 /* set V-bit to the comple- */
+ /* ment of the divisor sign */
+ or 0,0, tmp /* clear tmp */
+ add retreg,retreg,retreg /* shift msb bit into carry */
+ ds tmp,arg1, tmp /* 1st divide step, if no carry */
+ /* out, msb of quotient = 0 */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+LSYM(t1)
+ ds tmp,arg1, tmp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 32nd divide step, */
+ addc retreg,retreg,retreg /* shift last bit into retreg */
+ movb,>=,n tmp,retreg,LREF(finish) /* branch if pos. tmp */
+ add,< arg1,0,0 /* if arg1 > 0, add arg1 */
+ add,tr tmp,arg1,retreg /* for correcting remainder tmp */
+ sub tmp,arg1,retreg /* else add absolute value arg1 */
+LSYM(finish)
+ add,>= arg0,0,0 /* set sign of remainder */
+ sub 0,retreg,retreg /* to sign of dividend */
+ MILLIRET
+ nop
+ .exit
+ .procend
+#ifdef milliext
+ .origin 0x00000200
+#endif
+ .end
+#endif
+
+#ifdef L_remU
+/* ROUTINE: $$remU
+ . Single precision divide for remainder with unsigned binary integers.
+ .
+ . The remainder must be dividend-(dividend/divisor)*divisor.
+ . Divide by zero is trapped.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = remainder
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: DIVIDE BY ZERO
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Calls other millicode routines using mrp: NONE
+ . Calls other millicode routines: NONE */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1) /* r29 */
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .export $$remU,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$remU)
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,= arg1,temp,r0 /* if not, don't use power of 2 */
+ b LREF(regular_seq)
+ addit,= 0,arg1,r0 /* trap on div by zero */
+ and arg0,temp,rmndr /* get the result for power of 2 */
+ MILLIRETN
+LSYM(regular_seq)
+ comib,>=,n 0,arg1,LREF(special_case)
+ subi 0,arg1,rmndr /* clear carry, negate the divisor */
+ ds r0,rmndr,r0 /* set V-bit to 1 */
+ add arg0,arg0,temp /* shift msb bit into carry */
+ ds r0,arg1,rmndr /* 1st divide step, if no carry */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 2nd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 3rd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 4th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 5th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 6th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 7th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 8th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 9th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 10th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 11th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 12th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 13th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 14th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 15th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 16th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 17th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 18th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 19th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 20th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 21st divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 22nd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 23rd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 24th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 25th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 26th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 27th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 28th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 29th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 30th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 31st divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 32nd divide step, */
+ comiclr,<= 0,rmndr,r0
+ add rmndr,arg1,rmndr /* correction */
+ MILLIRETN
+ nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work! */
+LSYM(special_case)
+ sub,>>= arg0,arg1,rmndr
+ copy arg0,rmndr
+ MILLIRETN
+ nop
+ .exit
+ .procend
+ .end
+#endif
+
+#ifdef L_div_const
+/* ROUTINE: $$divI_2
+ . $$divI_3 $$divU_3
+ . $$divI_4
+ . $$divI_5 $$divU_5
+ . $$divI_6 $$divU_6
+ . $$divI_7 $$divU_7
+ . $$divI_8
+ . $$divI_9 $$divU_9
+ . $$divI_10 $$divU_10
+ .
+ . $$divI_12 $$divU_12
+ .
+ . $$divI_14 $$divU_14
+ . $$divI_15 $$divU_15
+ . $$divI_16
+ . $$divI_17 $$divU_17
+ .
+ . Divide by selected constants for single precision binary integers.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = quotient
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: NONE
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Calls other millicode routines using mrp: NONE
+ . Calls other millicode routines: NONE */
+
+
+/* TRUNCATED DIVISION BY SMALL INTEGERS
+
+ We are interested in q(x) = floor(x/y), where x >= 0 and y > 0
+ (with y fixed).
+
+ Let a = floor(z/y), for some choice of z. Note that z will be
+ chosen so that division by z is cheap.
+
+ Let r be the remainder(z/y). In other words, r = z - ay.
+
+ Now, our method is to choose a value for b such that
+
+ q'(x) = floor((ax+b)/z)
+
+ is equal to q(x) over as large a range of x as possible. If the
+ two are equal over a sufficiently large range, and if it is easy to
+ form the product (ax), and it is easy to divide by z, then we can
+ perform the division much faster than the general division algorithm.
+
+ So, we want the following to be true:
+
+ . For x in the following range:
+ .
+ . ky <= x < (k+1)y
+ .
+ . implies that
+ .
+ . k <= (ax+b)/z < (k+1)
+
+ We want to determine b such that this is true for all k in the
+ range {0..K} for some maximum K.
+
+ Since (ax+b) is an increasing function of x, we can take each
+ bound separately to determine the "best" value for b.
+
+ (ax+b)/z < (k+1) implies
+
+ (a((k+1)y-1)+b < (k+1)z implies
+
+ b < a + (k+1)(z-ay) implies
+
+ b < a + (k+1)r
+
+ This needs to be true for all k in the range {0..K}. In
+ particular, it is true for k = 0 and this leads to a maximum
+ acceptable value for b.
+
+ b < a+r or b <= a+r-1
+
+ Taking the other bound, we have
+
+ k <= (ax+b)/z implies
+
+ k <= (aky+b)/z implies
+
+ k(z-ay) <= b implies
+
+ kr <= b
+
+ Clearly, the largest range for k will be achieved by maximizing b,
+ when r is not zero. When r is zero, then the simplest choice for b
+ is 0. When r is not 0, set
+
+ . b = a+r-1
+
+ Now, by construction, q'(x) = floor((ax+b)/z) = q(x) = floor(x/y)
+ for all x in the range:
+
+ . 0 <= x < (K+1)y
+
+ We need to determine what K is. Of our two bounds,
+
+ . b < a+(k+1)r is satisfied for all k >= 0, by construction.
+
+ The other bound is
+
+ . kr <= b
+
+ This is always true if r = 0. If r is not 0 (the usual case), then
+ K = floor((a+r-1)/r), is the maximum value for k.
+
+ Therefore, the formula q'(x) = floor((ax+b)/z) yields the correct
+ answer for q(x) = floor(x/y) when x is in the range
+
+ (0,(K+1)y-1) K = floor((a+r-1)/r)
+
+ To be most useful, we want (K+1)y-1 = (max x) >= 2**32-1 so that
+ the formula for q'(x) yields the correct value of q(x) for all x
+ representable by a single word in HPPA.
+
+ We are also constrained in that computing the product (ax), adding
+ b, and dividing by z must all be done quickly, otherwise we will be
+ better off going through the general algorithm using the DS
+ instruction, which uses approximately 70 cycles.
+
+ For each y, there is a choice of z which satisfies the constraints
+ for (K+1)y >= 2**32. We may not, however, be able to satisfy the
+ timing constraints for arbitrary y. It seems that z being equal to
+ a power of 2 or a power of 2 minus 1 is as good as we can do, since
+ it minimizes the time to do division by z. We want the choice of z
+ to also result in a value for (a) that minimizes the computation of
+ the product (ax). This is best achieved if (a) has a regular bit
+ pattern (so the multiplication can be done with shifts and adds).
+ The value of (a) also needs to be less than 2**32 so the product is
+ always guaranteed to fit in 2 words.
+
+ In actual practice, the following should be done:
+
+ 1) For negative x, you should take the absolute value and remember
+ . the fact so that the result can be negated. This obviously does
+ . not apply in the unsigned case.
+ 2) For even y, you should factor out the power of 2 that divides y
+ . and divide x by it. You can then proceed by dividing by the
+ . odd factor of y.
+
+ Here is a table of some odd values of y, and corresponding choices
+ for z which are "good".
+
+ y z r a (hex) max x (hex)
+
+ 3 2**32 1 55555555 100000001
+ 5 2**32 1 33333333 100000003
+ 7 2**24-1 0 249249 (infinite)
+ 9 2**24-1 0 1c71c7 (infinite)
+ 11 2**20-1 0 1745d (infinite)
+ 13 2**24-1 0 13b13b (infinite)
+ 15 2**32 1 11111111 10000000d
+ 17 2**32 1 f0f0f0f 10000000f
+
+ If r is 1, then b = a+r-1 = a. This simplifies the computation
+ of (ax+b), since you can compute (x+1)(a) instead. If r is 0,
+ then b = 0 is ok to use which simplifies (ax+b).
+
+ The bit patterns for 55555555, 33333333, and 11111111 are obviously
+ very regular. The bit patterns for the other values of a above are:
+
+ y (hex) (binary)
+
+ 7 249249 001001001001001001001001 << regular >>
+ 9 1c71c7 000111000111000111000111 << regular >>
+ 11 1745d 000000010111010001011101 << irregular >>
+ 13 13b13b 000100111011000100111011 << irregular >>
+
+ The bit patterns for (a) corresponding to (y) of 11 and 13 may be
+ too irregular to warrant using this method.
+
+ When z is a power of 2 minus 1, then the division by z is slightly
+ more complicated, involving an iterative solution.
+
+ The code presented here solves division by 1 through 17, except for
+ 11 and 13. There are algorithms for both signed and unsigned
+ quantities given.
+
+ TIMINGS (cycles)
+
+ divisor positive negative unsigned
+
+ . 1 2 2 2
+ . 2 4 4 2
+ . 3 19 21 19
+ . 4 4 4 2
+ . 5 18 22 19
+ . 6 19 22 19
+ . 8 4 4 2
+ . 10 18 19 17
+ . 12 18 20 18
+ . 15 16 18 16
+ . 16 4 4 2
+ . 17 16 18 16
+
+ Now, the algorithm for 7, 9, and 14 is an iterative one. That is,
+ a loop body is executed until the tentative quotient is 0. The
+ number of times the loop body is executed varies depending on the
+ dividend, but is never more than two times. If the dividend is
+ less than the divisor, then the loop body is not executed at all.
+ Each iteration adds 4 cycles to the timings.
+
+ divisor positive negative unsigned
+
+ . 7 19+4n 20+4n 20+4n n = number of iterations
+ . 9 21+4n 22+4n 21+4n
+ . 14 21+4n 22+4n 20+4n
+
+ To give an idea of how the number of iterations varies, here is a
+ table of dividend versus number of iterations when dividing by 7.
+
+ smallest largest required
+ dividend dividend iterations
+
+ . 0 6 0
+ . 7 0x6ffffff 1
+ 0x1000006 0xffffffff 2
+
+ There is some overlap in the range of numbers requiring 1 and 2
+ iterations. */
+
+RDEFINE(t2,r1)
+RDEFINE(x2,arg0) /* r26 */
+RDEFINE(t1,arg1) /* r25 */
+RDEFINE(x1,ret1) /* r29 */
+
+ SUBSPA_MILLI_DIV
+ ATTR_MILLI
+
+ .proc
+ .callinfo millicode
+ .entry
+/* NONE of these routines require a stack frame
+ ALL of these routines are unwindable from millicode */
+
+GSYM($$divide_by_constant)
+ .export $$divide_by_constant,millicode
+/* Provides a "nice" label for the code covered by the unwind descriptor
+ for things like gprof. */
+
+/* DIVISION BY 2 (shift by 1) */
+GSYM($$divI_2)
+ .export $$divI_2,millicode
+ comclr,>= arg0,0,0
+ addi 1,arg0,arg0
+ MILLIRET
+ extrs arg0,30,31,ret1
+
+
+/* DIVISION BY 4 (shift by 2) */
+GSYM($$divI_4)
+ .export $$divI_4,millicode
+ comclr,>= arg0,0,0
+ addi 3,arg0,arg0
+ MILLIRET
+ extrs arg0,29,30,ret1
+
+
+/* DIVISION BY 8 (shift by 3) */
+GSYM($$divI_8)
+ .export $$divI_8,millicode
+ comclr,>= arg0,0,0
+ addi 7,arg0,arg0
+ MILLIRET
+ extrs arg0,28,29,ret1
+
+/* DIVISION BY 16 (shift by 4) */
+GSYM($$divI_16)
+ .export $$divI_16,millicode
+ comclr,>= arg0,0,0
+ addi 15,arg0,arg0
+ MILLIRET
+ extrs arg0,27,28,ret1
+
+/****************************************************************************
+*
+* DIVISION BY DIVISORS OF FFFFFFFF, and powers of 2 times these
+*
+* includes 3,5,15,17 and also 6,10,12
+*
+****************************************************************************/
+
+/* DIVISION BY 3 (use z = 2**32; a = 55555555) */
+
+GSYM($$divI_3)
+ .export $$divI_3,millicode
+ comb,<,N x2,0,LREF(neg3)
+
+ addi 1,x2,x2 /* this cannot overflow */
+ extru x2,1,2,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,0,x1
+
+LSYM(neg3)
+ subi 1,x2,x2 /* this cannot overflow */
+ extru x2,1,2,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_3)
+ .export $$divU_3,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,30,t1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,t1,x1
+
+/* DIVISION BY 5 (use z = 2**32; a = 33333333) */
+
+GSYM($$divI_5)
+ .export $$divI_5,millicode
+ comb,<,N x2,0,LREF(neg5)
+
+ addi 3,x2,t1 /* this cannot overflow */
+ sh1add x2,t1,x2 /* multiply by 3 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+LSYM(neg5)
+ sub 0,x2,x2 /* negate x2 */
+ addi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,31,x1 /* get top bit (can be 1) */
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_5)
+ .export $$divU_5,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,31,t1 /* multiply by 3 to get started */
+ sh1add x2,x2,x2
+ b LREF(pos)
+ addc t1,x1,x1
+
+/* DIVISION BY 6 (shift to divide by 2 then divide by 3) */
+GSYM($$divI_6)
+ .export $$divI_6,millicode
+ comb,<,N x2,0,LREF(neg6)
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 5,x2,t1 /* compute 5*(x2+1) = 5*x2+5 */
+ sh2add x2,t1,x2 /* multiply by 5 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+LSYM(neg6)
+ subi 2,x2,x2 /* negate, divide by 2, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,30,31,x2
+ shd 0,x2,30,x1
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+ b LREF(neg)
+ addc x1,0,x1
+
+GSYM($$divU_6)
+ .export $$divU_6,millicode
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 1,x2,x2 /* cannot carry */
+ shd 0,x2,30,x1 /* multiply by 5 to get started */
+ sh2add x2,x2,x2
+ b LREF(pos)
+ addc x1,0,x1
+
+/* DIVISION BY 10 (shift to divide by 2 then divide by 5) */
+GSYM($$divU_10)
+ .export $$divU_10,millicode
+ extru x2,30,31,x2 /* divide by 2 */
+ addi 3,x2,t1 /* compute 3*(x2+1) = (3*x2)+3 */
+ sh1add x2,t1,x2 /* multiply by 3 to get started */
+ addc 0,0,x1
+LSYM(pos)
+ shd x1,x2,28,t1 /* multiply by 0x11 */
+ shd x2,0,28,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+LSYM(pos_for_17)
+ shd x1,x2,24,t1 /* multiply by 0x101 */
+ shd x2,0,24,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,16,t1 /* multiply by 0x10001 */
+ shd x2,0,16,t2
+ add x2,t2,x2
+ MILLIRET
+ addc x1,t1,x1
+
+GSYM($$divI_10)
+ .export $$divI_10,millicode
+ comb,< x2,0,LREF(neg10)
+ copy 0,x1
+ extru x2,30,31,x2 /* divide by 2 */
+ addib,TR 1,x2,LREF(pos) /* add 1 (cannot overflow) */
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+
+LSYM(neg10)
+ subi 2,x2,x2 /* negate, divide by 2, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,30,31,x2
+ sh1add x2,x2,x2 /* multiply by 3 to get started */
+LSYM(neg)
+ shd x1,x2,28,t1 /* multiply by 0x11 */
+ shd x2,0,28,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+LSYM(neg_for_17)
+ shd x1,x2,24,t1 /* multiply by 0x101 */
+ shd x2,0,24,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,16,t1 /* multiply by 0x10001 */
+ shd x2,0,16,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+ MILLIRET
+ sub 0,x1,x1
+
+/* DIVISION BY 12 (shift to divide by 4 then divide by 3) */
+GSYM($$divI_12)
+ .export $$divI_12,millicode
+ comb,< x2,0,LREF(neg12)
+ copy 0,x1
+ extru x2,29,30,x2 /* divide by 4 */
+ addib,tr 1,x2,LREF(pos) /* compute 5*(x2+1) = 5*x2+5 */
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+
+LSYM(neg12)
+ subi 4,x2,x2 /* negate, divide by 4, and add 1 */
+ /* negation and adding 1 are done */
+ /* at the same time by the SUBI */
+ extru x2,29,30,x2
+ b LREF(neg)
+ sh2add x2,x2,x2 /* multiply by 5 to get started */
+
+GSYM($$divU_12)
+ .export $$divU_12,millicode
+ extru x2,29,30,x2 /* divide by 4 */
+ addi 5,x2,t1 /* cannot carry */
+ sh2add x2,t1,x2 /* multiply by 5 to get started */
+ b LREF(pos)
+ addc 0,0,x1
+
+/* DIVISION BY 15 (use z = 2**32; a = 11111111) */
+GSYM($$divI_15)
+ .export $$divI_15,millicode
+ comb,< x2,0,LREF(neg15)
+ copy 0,x1
+ addib,tr 1,x2,LREF(pos)+4
+ shd x1,x2,28,t1
+
+LSYM(neg15)
+ b LREF(neg)
+ subi 1,x2,x2
+
+GSYM($$divU_15)
+ .export $$divU_15,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ b LREF(pos)
+ addc 0,0,x1
+
+/* DIVISION BY 17 (use z = 2**32; a = f0f0f0f) */
+GSYM($$divI_17)
+ .export $$divI_17,millicode
+ comb,<,n x2,0,LREF(neg17)
+ addi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,28,t1 /* multiply by 0xf to get started */
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(pos_for_17)
+ subb t1,0,x1
+
+LSYM(neg17)
+ subi 1,x2,x2 /* this cannot overflow */
+ shd 0,x2,28,t1 /* multiply by 0xf to get started */
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(neg_for_17)
+ subb t1,0,x1
+
+GSYM($$divU_17)
+ .export $$divU_17,millicode
+ addi 1,x2,x2 /* this CAN overflow */
+ addc 0,0,x1
+ shd x1,x2,28,t1 /* multiply by 0xf to get started */
+LSYM(u17)
+ shd x2,0,28,t2
+ sub t2,x2,x2
+ b LREF(pos_for_17)
+ subb t1,x1,x1
+
+
+/* DIVISION BY DIVISORS OF FFFFFF, and powers of 2 times these
+ includes 7,9 and also 14
+
+
+ z = 2**24-1
+ r = z mod x = 0
+
+ so choose b = 0
+
+ Also, in order to divide by z = 2**24-1, we approximate by dividing
+ by (z+1) = 2**24 (which is easy), and then correcting.
+
+ (ax) = (z+1)q' + r
+ . = zq' + (q'+r)
+
+ So to compute (ax)/z, compute q' = (ax)/(z+1) and r = (ax) mod (z+1)
+ Then the true remainder of (ax)/z is (q'+r). Repeat the process
+ with this new remainder, adding the tentative quotients together,
+ until a tentative quotient is 0 (and then we are done). There is
+ one last correction to be done. It is possible that (q'+r) = z.
+ If so, then (q'+r)/(z+1) = 0 and it looks like we are done. But,
+ in fact, we need to add 1 more to the quotient. Now, it turns
+ out that this happens if and only if the original value x is
+ an exact multiple of y. So, to avoid a three instruction test at
+ the end, instead use 1 instruction to add 1 to x at the beginning. */
+
+/* DIVISION BY 7 (use z = 2**24-1; a = 249249) */
+GSYM($$divI_7)
+ .export $$divI_7,millicode
+ comb,<,n x2,0,LREF(neg7)
+LSYM(7)
+ addi 1,x2,x2 /* cannot overflow */
+ shd 0,x2,29,x1
+ sh3add x2,x2,x2
+ addc x1,0,x1
+LSYM(pos7)
+ shd x1,x2,26,t1
+ shd x2,0,26,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,20,t1
+ shd x2,0,20,t2
+ add x2,t2,x2
+ addc x1,t1,t1
+
+ /* computed <t1,x2>. Now divide it by (2**24 - 1) */
+
+ copy 0,x1
+ shd,= t1,x2,24,t1 /* tentative quotient */
+LSYM(1)
+ addb,tr t1,x1,LREF(2) /* add to previous quotient */
+ extru x2,31,24,x2 /* new remainder (unadjusted) */
+
+ MILLIRETN
+
+LSYM(2)
+ addb,tr t1,x2,LREF(1) /* adjust remainder */
+ extru,= x2,7,8,t1 /* new quotient */
+
+LSYM(neg7)
+ subi 1,x2,x2 /* negate x2 and add 1 */
+LSYM(8)
+ shd 0,x2,29,x1
+ sh3add x2,x2,x2
+ addc x1,0,x1
+
+LSYM(neg7_shift)
+ shd x1,x2,26,t1
+ shd x2,0,26,t2
+ add x2,t2,x2
+ addc x1,t1,x1
+
+ shd x1,x2,20,t1
+ shd x2,0,20,t2
+ add x2,t2,x2
+ addc x1,t1,t1
+
+ /* computed <t1,x2>. Now divide it by (2**24 - 1) */
+
+ copy 0,x1
+ shd,= t1,x2,24,t1 /* tentative quotient */
+LSYM(3)
+ addb,tr t1,x1,LREF(4) /* add to previous quotient */
+ extru x2,31,24,x2 /* new remainder (unadjusted) */
+
+ MILLIRET
+ sub 0,x1,x1 /* negate result */
+
+LSYM(4)
+ addb,tr t1,x2,LREF(3) /* adjust remainder */
+ extru,= x2,7,8,t1 /* new quotient */
+
+GSYM($$divU_7)
+ .export $$divU_7,millicode
+ addi 1,x2,x2 /* can carry */
+ addc 0,0,x1
+ shd x1,x2,29,t1
+ sh3add x2,x2,x2
+ b LREF(pos7)
+ addc t1,x1,x1
+
+/* DIVISION BY 9 (use z = 2**24-1; a = 1c71c7) */
+GSYM($$divI_9)
+ .export $$divI_9,millicode
+ comb,<,n x2,0,LREF(neg9)
+ addi 1,x2,x2 /* cannot overflow */
+ shd 0,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(pos7)
+ subb t1,0,x1
+
+LSYM(neg9)
+ subi 1,x2,x2 /* negate and add 1 */
+ shd 0,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(neg7_shift)
+ subb t1,0,x1
+
+GSYM($$divU_9)
+ .export $$divU_9,millicode
+ addi 1,x2,x2 /* can carry */
+ addc 0,0,x1
+ shd x1,x2,29,t1
+ shd x2,0,29,t2
+ sub t2,x2,x2
+ b LREF(pos7)
+ subb t1,x1,x1
+
+/* DIVISION BY 14 (shift to divide by 2 then divide by 7) */
+GSYM($$divI_14)
+ .export $$divI_14,millicode
+ comb,<,n x2,0,LREF(neg14)
+GSYM($$divU_14)
+ .export $$divU_14,millicode
+ b LREF(7) /* go to 7 case */
+ extru x2,30,31,x2 /* divide by 2 */
+
+LSYM(neg14)
+ subi 2,x2,x2 /* negate (and add 2) */
+ b LREF(8)
+ extru x2,30,31,x2 /* divide by 2 */
+ .exit
+ .procend
+ .end
+#endif
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE: $$mulI
+
+
+DESCRIPTION:
+
+ $$mulI multiplies two single word integers, giving a single
+ word result.
+
+
+INPUT REGISTERS:
+
+ arg0 = Operand 1
+ arg1 = Operand 2
+ r31 == return pc
+ sr0 == return space when called externally
+
+
+OUTPUT REGISTERS:
+
+ arg0 = undefined
+ arg1 = undefined
+ ret1 = result
+
+OTHER REGISTERS AFFECTED:
+
+ r1 = undefined
+
+SIDE EFFECTS:
+
+ Causes a trap under the following conditions: NONE
+ Changes memory at the following places: NONE
+
+PERMISSIBLE CONTEXT:
+
+ Unwindable
+ Does not create a stack frame
+ Is usable for internal or external microcode
+
+DISCUSSION:
+
+ Calls other millicode routines via mrp: NONE
+ Calls other millicode routines: NONE
+
+***************************************************************************/
+
+
+#define a0 %arg0
+#define a1 %arg1
+#define t0 %r1
+#define r %ret1
+
+#define a0__128a0 zdep a0,24,25,a0
+#define a0__256a0 zdep a0,23,24,a0
+#define a1_ne_0_b_l0 comb,<> a1,0,LREF(l0)
+#define a1_ne_0_b_l1 comb,<> a1,0,LREF(l1)
+#define a1_ne_0_b_l2 comb,<> a1,0,LREF(l2)
+#define b_n_ret_t0 b,n LREF(ret_t0)
+#define b_e_shift b LREF(e_shift)
+#define b_e_t0ma0 b LREF(e_t0ma0)
+#define b_e_t0 b LREF(e_t0)
+#define b_e_t0a0 b LREF(e_t0a0)
+#define b_e_t02a0 b LREF(e_t02a0)
+#define b_e_t04a0 b LREF(e_t04a0)
+#define b_e_2t0 b LREF(e_2t0)
+#define b_e_2t0a0 b LREF(e_2t0a0)
+#define b_e_2t04a0 b LREF(e2t04a0)
+#define b_e_3t0 b LREF(e_3t0)
+#define b_e_4t0 b LREF(e_4t0)
+#define b_e_4t0a0 b LREF(e_4t0a0)
+#define b_e_4t08a0 b LREF(e4t08a0)
+#define b_e_5t0 b LREF(e_5t0)
+#define b_e_8t0 b LREF(e_8t0)
+#define b_e_8t0a0 b LREF(e_8t0a0)
+#define r__r_a0 add r,a0,r
+#define r__r_2a0 sh1add a0,r,r
+#define r__r_4a0 sh2add a0,r,r
+#define r__r_8a0 sh3add a0,r,r
+#define r__r_t0 add r,t0,r
+#define r__r_2t0 sh1add t0,r,r
+#define r__r_4t0 sh2add t0,r,r
+#define r__r_8t0 sh3add t0,r,r
+#define t0__3a0 sh1add a0,a0,t0
+#define t0__4a0 sh2add a0,0,t0
+#define t0__5a0 sh2add a0,a0,t0
+#define t0__8a0 sh3add a0,0,t0
+#define t0__9a0 sh3add a0,a0,t0
+#define t0__16a0 zdep a0,27,28,t0
+#define t0__32a0 zdep a0,26,27,t0
+#define t0__64a0 zdep a0,25,26,t0
+#define t0__128a0 zdep a0,24,25,t0
+#define t0__t0ma0 sub t0,a0,t0
+#define t0__t0_a0 add t0,a0,t0
+#define t0__t0_2a0 sh1add a0,t0,t0
+#define t0__t0_4a0 sh2add a0,t0,t0
+#define t0__t0_8a0 sh3add a0,t0,t0
+#define t0__2t0_a0 sh1add t0,a0,t0
+#define t0__3t0 sh1add t0,t0,t0
+#define t0__4t0 sh2add t0,0,t0
+#define t0__4t0_a0 sh2add t0,a0,t0
+#define t0__5t0 sh2add t0,t0,t0
+#define t0__8t0 sh3add t0,0,t0
+#define t0__8t0_a0 sh3add t0,a0,t0
+#define t0__9t0 sh3add t0,t0,t0
+#define t0__16t0 zdep t0,27,28,t0
+#define t0__32t0 zdep t0,26,27,t0
+#define t0__256a0 zdep a0,23,24,t0
+
+
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .align 16
+ .proc
+ .callinfo millicode
+ .export $$mulI,millicode
+GSYM($$mulI)
+ combt,<<= a1,a0,LREF(l4) /* swap args if unsigned a1>a0 */
+ copy 0,r /* zero out the result */
+ xor a0,a1,a0 /* swap a0 & a1 using the */
+ xor a0,a1,a1 /* old xor trick */
+ xor a0,a1,a0
+LSYM(l4)
+ combt,<= 0,a0,LREF(l3) /* if a0>=0 then proceed like unsigned */
+ zdep a1,30,8,t0 /* t0 = (a1&0xff)<<1 ********* */
+ sub,> 0,a1,t0 /* otherwise negate both and */
+ combt,<=,n a0,t0,LREF(l2) /* swap back if |a0|<|a1| */
+ sub 0,a0,a1
+ movb,tr,n t0,a0,LREF(l2) /* 10th inst. */
+
+LSYM(l0) r__r_t0 /* add in this partial product */
+LSYM(l1) a0__256a0 /* a0 <<= 8 ****************** */
+LSYM(l2) zdep a1,30,8,t0 /* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3) blr t0,0 /* case on these 8 bits ****** */
+ extru a1,23,24,a1 /* a1 >>= 8 ****************** */
+
+/*16 insts before this. */
+/* a0 <<= 8 ************************** */
+LSYM(x0) a1_ne_0_b_l2 ! a0__256a0 ! MILLIRETN ! nop
+LSYM(x1) a1_ne_0_b_l1 ! r__r_a0 ! MILLIRETN ! nop
+LSYM(x2) a1_ne_0_b_l1 ! r__r_2a0 ! MILLIRETN ! nop
+LSYM(x3) a1_ne_0_b_l0 ! t0__3a0 ! MILLIRET ! r__r_t0
+LSYM(x4) a1_ne_0_b_l1 ! r__r_4a0 ! MILLIRETN ! nop
+LSYM(x5) a1_ne_0_b_l0 ! t0__5a0 ! MILLIRET ! r__r_t0
+LSYM(x6) t0__3a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x7) t0__3a0 ! a1_ne_0_b_l0 ! r__r_4a0 ! b_n_ret_t0
+LSYM(x8) a1_ne_0_b_l1 ! r__r_8a0 ! MILLIRETN ! nop
+LSYM(x9) a1_ne_0_b_l0 ! t0__9a0 ! MILLIRET ! r__r_t0
+LSYM(x10) t0__5a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x11) t0__3a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+LSYM(x12) t0__3a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x13) t0__5a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+LSYM(x14) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x15) t0__5a0 ! a1_ne_0_b_l0 ! t0__3t0 ! b_n_ret_t0
+LSYM(x16) t0__16a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x17) t0__9a0 ! a1_ne_0_b_l0 ! t0__t0_8a0 ! b_n_ret_t0
+LSYM(x18) t0__9a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x19) t0__9a0 ! a1_ne_0_b_l0 ! t0__2t0_a0 ! b_n_ret_t0
+LSYM(x20) t0__5a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x21) t0__5a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x22) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x23) t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x24) t0__3a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x25) t0__5a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+LSYM(x26) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x27) t0__3a0 ! a1_ne_0_b_l0 ! t0__9t0 ! b_n_ret_t0
+LSYM(x28) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x29) t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x30) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+LSYM(x31) t0__32a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x32) t0__32a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x33) t0__8a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x34) t0__16a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x35) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__t0_8a0
+LSYM(x36) t0__9a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x37) t0__9a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x38) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x39) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x40) t0__5a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x41) t0__5a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+LSYM(x42) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x43) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x44) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x45) t0__9a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+LSYM(x46) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_a0
+LSYM(x47) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x48) t0__3a0 ! a1_ne_0_b_l0 ! t0__16t0 ! b_n_ret_t0
+LSYM(x49) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_4a0
+LSYM(x50) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+LSYM(x51) t0__9a0 ! t0__t0_8a0 ! b_e_t0 ! t0__3t0
+LSYM(x52) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x53) t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x54) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+LSYM(x55) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x56) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x57) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x58) t0__3a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x59) t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x60) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x61) t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x62) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x63) t0__64a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x64) t0__64a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x65) t0__8a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+LSYM(x66) t0__32a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x67) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x68) t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x69) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x70) t0__64a0 ! t0__t0_4a0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x71) t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x72) t0__9a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x73) t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_t0
+LSYM(x74) t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x75) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x76) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x77) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x78) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x79) t0__16a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x80) t0__16a0 ! t0__5t0 ! b_e_shift ! r__r_t0
+LSYM(x81) t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_t0
+LSYM(x82) t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x83) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x84) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x85) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x86) t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x87) t0__9a0 ! t0__9t0 ! b_e_t02a0 ! t0__t0_4a0
+LSYM(x88) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x89) t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x90) t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+LSYM(x91) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x92) t0__5a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x93) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__3t0
+LSYM(x94) t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__t0_2a0
+LSYM(x95) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x96) t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x97) t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x98) t0__32a0 ! t0__3t0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x99) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x100) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+LSYM(x101) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x102) t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+LSYM(x103) t0__5a0 ! t0__5t0 ! b_e_t02a0 ! t0__4t0_a0
+LSYM(x104) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x105) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x106) t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x107) t0__9a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__8t0_a0
+LSYM(x108) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x109) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x110) t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x111) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x112) t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__16t0
+LSYM(x113) t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x114) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x115) t0__9a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x116) t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x117) t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x118) t0__3a0 ! t0__4t0_a0 ! b_e_t0a0 ! t0__9t0
+LSYM(x119) t0__3a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__9t0
+LSYM(x120) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x121) t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x122) t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x123) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x124) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+LSYM(x125) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+LSYM(x126) t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x127) t0__128a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x128) t0__128a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x129) t0__128a0 ! a1_ne_0_b_l0 ! t0__t0_a0 ! b_n_ret_t0
+LSYM(x130) t0__64a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x131) t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x132) t0__8a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x133) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x134) t0__8a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x135) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__3t0
+LSYM(x136) t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x137) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x138) t0__8a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x139) t0__8a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__4t0_a0
+LSYM(x140) t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__5t0
+LSYM(x141) t0__8a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x142) t0__9a0 ! t0__8t0 ! b_e_2t0 ! t0__t0ma0
+LSYM(x143) t0__16a0 ! t0__9t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x144) t0__9a0 ! t0__8t0 ! b_e_shift ! r__r_2t0
+LSYM(x145) t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x146) t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x147) t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x148) t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x149) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x150) t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x151) t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x152) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x153) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x154) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x155) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__5t0
+LSYM(x156) t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x157) t0__32a0 ! t0__t0ma0 ! b_e_t02a0 ! t0__5t0
+LSYM(x158) t0__16a0 ! t0__5t0 ! b_e_2t0 ! t0__t0ma0
+LSYM(x159) t0__32a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x160) t0__5a0 ! t0__4t0 ! b_e_shift ! r__r_8t0
+LSYM(x161) t0__8a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x162) t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_2t0
+LSYM(x163) t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x164) t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x165) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x166) t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x167) t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x168) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x169) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x170) t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__5t0
+LSYM(x171) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x172) t0__5a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x173) t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__9t0
+LSYM(x174) t0__32a0 ! t0__t0_2a0 ! b_e_t04a0 ! t0__5t0
+LSYM(x175) t0__8a0 ! t0__2t0_a0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x176) t0__5a0 ! t0__4t0_a0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x177) t0__5a0 ! t0__4t0_a0 ! b_e_8t0a0 ! t0__t0_a0
+LSYM(x178) t0__5a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__8t0_a0
+LSYM(x179) t0__5a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__8t0_a0
+LSYM(x180) t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+LSYM(x181) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x182) t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x183) t0__9a0 ! t0__5t0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x184) t0__5a0 ! t0__9t0 ! b_e_4t0 ! t0__t0_a0
+LSYM(x185) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x186) t0__32a0 ! t0__t0ma0 ! b_e_2t0 ! t0__3t0
+LSYM(x187) t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__5t0
+LSYM(x188) t0__9a0 ! t0__5t0 ! b_e_4t0 ! t0__t0_2a0
+LSYM(x189) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x190) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__5t0
+LSYM(x191) t0__64a0 ! t0__3t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x192) t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x193) t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x194) t0__8a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x195) t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x196) t0__8a0 ! t0__3t0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x197) t0__8a0 ! t0__3t0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x198) t0__64a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+LSYM(x199) t0__8a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x200) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_8t0
+LSYM(x201) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x202) t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x203) t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__4t0_a0
+LSYM(x204) t0__8a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+LSYM(x205) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x206) t0__64a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x207) t0__8a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+LSYM(x208) t0__5a0 ! t0__5t0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x209) t0__5a0 ! t0__5t0 ! b_e_8t0a0 ! t0__t0_a0
+LSYM(x210) t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__5t0
+LSYM(x211) t0__5a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__5t0
+LSYM(x212) t0__3a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x213) t0__3a0 ! t0__4t0_a0 ! b_e_4t0a0 ! t0__4t0_a0
+LSYM(x214) t0__9a0 ! t0__t0_4a0 ! b_e_2t04a0 ! t0__8t0_a0
+LSYM(x215) t0__5a0 ! t0__4t0_a0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x216) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x217) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x218) t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x219) t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x220) t0__3a0 ! t0__9t0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x221) t0__3a0 ! t0__9t0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x222) t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x223) t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x224) t0__9a0 ! t0__3t0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x225) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+LSYM(x226) t0__3a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__32t0
+LSYM(x227) t0__9a0 ! t0__5t0 ! b_e_t02a0 ! t0__5t0
+LSYM(x228) t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+LSYM(x229) t0__9a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__3t0
+LSYM(x230) t0__9a0 ! t0__5t0 ! b_e_5t0 ! t0__t0_a0
+LSYM(x231) t0__9a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+LSYM(x232) t0__3a0 ! t0__2t0_a0 ! b_e_8t0 ! t0__4t0_a0
+LSYM(x233) t0__3a0 ! t0__2t0_a0 ! b_e_8t0a0 ! t0__4t0_a0
+LSYM(x234) t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__9t0
+LSYM(x235) t0__3a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__9t0
+LSYM(x236) t0__9a0 ! t0__2t0_a0 ! b_e_4t08a0 ! t0__3t0
+LSYM(x237) t0__16a0 ! t0__5t0 ! b_e_3t0 ! t0__t0ma0
+LSYM(x238) t0__3a0 ! t0__4t0_a0 ! b_e_2t04a0 ! t0__9t0
+LSYM(x239) t0__16a0 ! t0__5t0 ! b_e_t0ma0 ! t0__3t0
+LSYM(x240) t0__9a0 ! t0__t0_a0 ! b_e_8t0 ! t0__3t0
+LSYM(x241) t0__9a0 ! t0__t0_a0 ! b_e_8t0a0 ! t0__3t0
+LSYM(x242) t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__8t0_a0
+LSYM(x243) t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__3t0
+LSYM(x244) t0__5a0 ! t0__3t0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x245) t0__8a0 ! t0__3t0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x246) t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x247) t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x248) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_8t0
+LSYM(x249) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x250) t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__5t0
+LSYM(x251) t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__5t0
+LSYM(x252) t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+LSYM(x253) t0__64a0 ! t0__t0ma0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x254) t0__128a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x255) t0__256a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+/*1040 insts before this. */
+LSYM(ret_t0) MILLIRET
+LSYM(e_t0) r__r_t0
+LSYM(e_shift) a1_ne_0_b_l2
+ a0__256a0 /* a0 <<= 8 *********** */
+ MILLIRETN
+LSYM(e_t0ma0) a1_ne_0_b_l0
+ t0__t0ma0
+ MILLIRET
+ r__r_t0
+LSYM(e_t0a0) a1_ne_0_b_l0
+ t0__t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e_t02a0) a1_ne_0_b_l0
+ t0__t0_2a0
+ MILLIRET
+ r__r_t0
+LSYM(e_t04a0) a1_ne_0_b_l0
+ t0__t0_4a0
+ MILLIRET
+ r__r_t0
+LSYM(e_2t0) a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+LSYM(e_2t0a0) a1_ne_0_b_l0
+ t0__2t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e2t04a0) t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+LSYM(e_3t0) a1_ne_0_b_l0
+ t0__3t0
+ MILLIRET
+ r__r_t0
+LSYM(e_4t0) a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+LSYM(e_4t0a0) a1_ne_0_b_l0
+ t0__4t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e4t08a0) t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+LSYM(e_5t0) a1_ne_0_b_l0
+ t0__5t0
+ MILLIRET
+ r__r_t0
+LSYM(e_8t0) a1_ne_0_b_l1
+ r__r_8t0
+ MILLIRETN
+LSYM(e_8t0a0) a1_ne_0_b_l0
+ t0__8t0_a0
+ MILLIRET
+ r__r_t0
+
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/milli.h b/arch/parisc/lib/milli/milli.h
new file mode 100644
index 00000000000..19ac79f336d
--- /dev/null
+++ b/arch/parisc/lib/milli/milli.h
@@ -0,0 +1,165 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#ifndef _PA_MILLI_H_
+#define _PA_MILLI_H_
+
+#define L_dyncall
+#define L_divI
+#define L_divU
+#define L_remI
+#define L_remU
+#define L_div_const
+#define L_mulI
+
+#ifdef CONFIG_64BIT
+ .level 2.0w
+#endif
+
+/* Hardware General Registers. */
+r0: .reg %r0
+r1: .reg %r1
+r2: .reg %r2
+r3: .reg %r3
+r4: .reg %r4
+r5: .reg %r5
+r6: .reg %r6
+r7: .reg %r7
+r8: .reg %r8
+r9: .reg %r9
+r10: .reg %r10
+r11: .reg %r11
+r12: .reg %r12
+r13: .reg %r13
+r14: .reg %r14
+r15: .reg %r15
+r16: .reg %r16
+r17: .reg %r17
+r18: .reg %r18
+r19: .reg %r19
+r20: .reg %r20
+r21: .reg %r21
+r22: .reg %r22
+r23: .reg %r23
+r24: .reg %r24
+r25: .reg %r25
+r26: .reg %r26
+r27: .reg %r27
+r28: .reg %r28
+r29: .reg %r29
+r30: .reg %r30
+r31: .reg %r31
+
+/* Hardware Space Registers. */
+sr0: .reg %sr0
+sr1: .reg %sr1
+sr2: .reg %sr2
+sr3: .reg %sr3
+sr4: .reg %sr4
+sr5: .reg %sr5
+sr6: .reg %sr6
+sr7: .reg %sr7
+
+/* Hardware Floating Point Registers. */
+fr0: .reg %fr0
+fr1: .reg %fr1
+fr2: .reg %fr2
+fr3: .reg %fr3
+fr4: .reg %fr4
+fr5: .reg %fr5
+fr6: .reg %fr6
+fr7: .reg %fr7
+fr8: .reg %fr8
+fr9: .reg %fr9
+fr10: .reg %fr10
+fr11: .reg %fr11
+fr12: .reg %fr12
+fr13: .reg %fr13
+fr14: .reg %fr14
+fr15: .reg %fr15
+
+/* Hardware Control Registers. */
+cr11: .reg %cr11
+sar: .reg %cr11 /* Shift Amount Register */
+
+/* Software Architecture General Registers. */
+rp: .reg r2 /* return pointer */
+#ifdef CONFIG_64BIT
+mrp: .reg r2 /* millicode return pointer */
+#else
+mrp: .reg r31 /* millicode return pointer */
+#endif
+ret0: .reg r28 /* return value */
+ret1: .reg r29 /* return value (high part of double) */
+sp: .reg r30 /* stack pointer */
+dp: .reg r27 /* data pointer */
+arg0: .reg r26 /* argument */
+arg1: .reg r25 /* argument or high part of double argument */
+arg2: .reg r24 /* argument */
+arg3: .reg r23 /* argument or high part of double argument */
+
+/* Software Architecture Space Registers. */
+/* sr0 ; return link from BLE */
+sret: .reg sr1 /* return value */
+sarg: .reg sr1 /* argument */
+/* sr4 ; PC SPACE tracker */
+/* sr5 ; process private data */
+
+/* Frame Offsets (millicode convention!) Used when calling other
+ millicode routines. Stack unwinding is dependent upon these
+ definitions. */
+r31_slot: .equ -20 /* "current RP" slot */
+sr0_slot: .equ -16 /* "static link" slot */
+#if defined(CONFIG_64BIT)
+mrp_slot: .equ -16 /* "current RP" slot */
+psp_slot: .equ -8 /* "previous SP" slot */
+#else
+mrp_slot: .equ -20 /* "current RP" slot (replacing "r31_slot") */
+#endif
+
+
+#define DEFINE(name,value)name: .EQU value
+#define RDEFINE(name,value)name: .REG value
+#ifdef milliext
+#define MILLI_BE(lbl) BE lbl(sr7,r0)
+#define MILLI_BEN(lbl) BE,n lbl(sr7,r0)
+#define MILLI_BLE(lbl) BLE lbl(sr7,r0)
+#define MILLI_BLEN(lbl) BLE,n lbl(sr7,r0)
+#define MILLIRETN BE,n 0(sr0,mrp)
+#define MILLIRET BE 0(sr0,mrp)
+#define MILLI_RETN BE,n 0(sr0,mrp)
+#define MILLI_RET BE 0(sr0,mrp)
+#else
+#define MILLI_BE(lbl) B lbl
+#define MILLI_BEN(lbl) B,n lbl
+#define MILLI_BLE(lbl) BL lbl,mrp
+#define MILLI_BLEN(lbl) BL,n lbl,mrp
+#define MILLIRETN BV,n 0(mrp)
+#define MILLIRET BV 0(mrp)
+#define MILLI_RETN BV,n 0(mrp)
+#define MILLI_RET BV 0(mrp)
+#endif
+
+#define CAT(a,b) a##b
+
+#define SUBSPA_MILLI .section .text
+#define SUBSPA_MILLI_DIV .section .text.div,"ax",@progbits! .align 16
+#define SUBSPA_MILLI_MUL .section .text.mul,"ax",@progbits! .align 16
+#define ATTR_MILLI
+#define SUBSPA_DATA .section .data
+#define ATTR_DATA
+#define GLOBAL $global$
+#define GSYM(sym) !sym:
+#define LSYM(sym) !CAT(.L,sym:)
+#define LREF(sym) CAT(.L,sym)
+
+#endif /*_PA_MILLI_H_*/
diff --git a/arch/parisc/lib/milli/mulI.S b/arch/parisc/lib/milli/mulI.S
new file mode 100644
index 00000000000..4c7e0c36d15
--- /dev/null
+++ b/arch/parisc/lib/milli/mulI.S
@@ -0,0 +1,474 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_mulI
+/* VERSION "@(#)$$mulI $ Revision: 12.4 $ $ Date: 94/03/17 17:18:51 $" */
+/******************************************************************************
+This routine is used on PA2.0 processors when gcc -mno-fpregs is used
+
+ROUTINE: $$mulI
+
+
+DESCRIPTION:
+
+ $$mulI multiplies two single word integers, giving a single
+ word result.
+
+
+INPUT REGISTERS:
+
+ arg0 = Operand 1
+ arg1 = Operand 2
+ r31 == return pc
+ sr0 == return space when called externally
+
+
+OUTPUT REGISTERS:
+
+ arg0 = undefined
+ arg1 = undefined
+ ret1 = result
+
+OTHER REGISTERS AFFECTED:
+
+ r1 = undefined
+
+SIDE EFFECTS:
+
+ Causes a trap under the following conditions: NONE
+ Changes memory at the following places: NONE
+
+PERMISSIBLE CONTEXT:
+
+ Unwindable
+ Does not create a stack frame
+ Is usable for internal or external microcode
+
+DISCUSSION:
+
+ Calls other millicode routines via mrp: NONE
+ Calls other millicode routines: NONE
+
+***************************************************************************/
+
+
+#define a0 %arg0
+#define a1 %arg1
+#define t0 %r1
+#define r %ret1
+
+#define a0__128a0 zdep a0,24,25,a0
+#define a0__256a0 zdep a0,23,24,a0
+#define a1_ne_0_b_l0 comb,<> a1,0,LREF(l0)
+#define a1_ne_0_b_l1 comb,<> a1,0,LREF(l1)
+#define a1_ne_0_b_l2 comb,<> a1,0,LREF(l2)
+#define b_n_ret_t0 b,n LREF(ret_t0)
+#define b_e_shift b LREF(e_shift)
+#define b_e_t0ma0 b LREF(e_t0ma0)
+#define b_e_t0 b LREF(e_t0)
+#define b_e_t0a0 b LREF(e_t0a0)
+#define b_e_t02a0 b LREF(e_t02a0)
+#define b_e_t04a0 b LREF(e_t04a0)
+#define b_e_2t0 b LREF(e_2t0)
+#define b_e_2t0a0 b LREF(e_2t0a0)
+#define b_e_2t04a0 b LREF(e2t04a0)
+#define b_e_3t0 b LREF(e_3t0)
+#define b_e_4t0 b LREF(e_4t0)
+#define b_e_4t0a0 b LREF(e_4t0a0)
+#define b_e_4t08a0 b LREF(e4t08a0)
+#define b_e_5t0 b LREF(e_5t0)
+#define b_e_8t0 b LREF(e_8t0)
+#define b_e_8t0a0 b LREF(e_8t0a0)
+#define r__r_a0 add r,a0,r
+#define r__r_2a0 sh1add a0,r,r
+#define r__r_4a0 sh2add a0,r,r
+#define r__r_8a0 sh3add a0,r,r
+#define r__r_t0 add r,t0,r
+#define r__r_2t0 sh1add t0,r,r
+#define r__r_4t0 sh2add t0,r,r
+#define r__r_8t0 sh3add t0,r,r
+#define t0__3a0 sh1add a0,a0,t0
+#define t0__4a0 sh2add a0,0,t0
+#define t0__5a0 sh2add a0,a0,t0
+#define t0__8a0 sh3add a0,0,t0
+#define t0__9a0 sh3add a0,a0,t0
+#define t0__16a0 zdep a0,27,28,t0
+#define t0__32a0 zdep a0,26,27,t0
+#define t0__64a0 zdep a0,25,26,t0
+#define t0__128a0 zdep a0,24,25,t0
+#define t0__t0ma0 sub t0,a0,t0
+#define t0__t0_a0 add t0,a0,t0
+#define t0__t0_2a0 sh1add a0,t0,t0
+#define t0__t0_4a0 sh2add a0,t0,t0
+#define t0__t0_8a0 sh3add a0,t0,t0
+#define t0__2t0_a0 sh1add t0,a0,t0
+#define t0__3t0 sh1add t0,t0,t0
+#define t0__4t0 sh2add t0,0,t0
+#define t0__4t0_a0 sh2add t0,a0,t0
+#define t0__5t0 sh2add t0,t0,t0
+#define t0__8t0 sh3add t0,0,t0
+#define t0__8t0_a0 sh3add t0,a0,t0
+#define t0__9t0 sh3add t0,t0,t0
+#define t0__16t0 zdep t0,27,28,t0
+#define t0__32t0 zdep t0,26,27,t0
+#define t0__256a0 zdep a0,23,24,t0
+
+
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .align 16
+ .proc
+ .callinfo millicode
+ .export $$mulI,millicode
+GSYM($$mulI)
+ combt,<<= a1,a0,LREF(l4) /* swap args if unsigned a1>a0 */
+ copy 0,r /* zero out the result */
+ xor a0,a1,a0 /* swap a0 & a1 using the */
+ xor a0,a1,a1 /* old xor trick */
+ xor a0,a1,a0
+LSYM(l4)
+ combt,<= 0,a0,LREF(l3) /* if a0>=0 then proceed like unsigned */
+ zdep a1,30,8,t0 /* t0 = (a1&0xff)<<1 ********* */
+ sub,> 0,a1,t0 /* otherwise negate both and */
+ combt,<=,n a0,t0,LREF(l2) /* swap back if |a0|<|a1| */
+ sub 0,a0,a1
+ movb,tr,n t0,a0,LREF(l2) /* 10th inst. */
+
+LSYM(l0) r__r_t0 /* add in this partial product */
+LSYM(l1) a0__256a0 /* a0 <<= 8 ****************** */
+LSYM(l2) zdep a1,30,8,t0 /* t0 = (a1&0xff)<<1 ********* */
+LSYM(l3) blr t0,0 /* case on these 8 bits ****** */
+ extru a1,23,24,a1 /* a1 >>= 8 ****************** */
+
+/*16 insts before this. */
+/* a0 <<= 8 ************************** */
+LSYM(x0) a1_ne_0_b_l2 ! a0__256a0 ! MILLIRETN ! nop
+LSYM(x1) a1_ne_0_b_l1 ! r__r_a0 ! MILLIRETN ! nop
+LSYM(x2) a1_ne_0_b_l1 ! r__r_2a0 ! MILLIRETN ! nop
+LSYM(x3) a1_ne_0_b_l0 ! t0__3a0 ! MILLIRET ! r__r_t0
+LSYM(x4) a1_ne_0_b_l1 ! r__r_4a0 ! MILLIRETN ! nop
+LSYM(x5) a1_ne_0_b_l0 ! t0__5a0 ! MILLIRET ! r__r_t0
+LSYM(x6) t0__3a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x7) t0__3a0 ! a1_ne_0_b_l0 ! r__r_4a0 ! b_n_ret_t0
+LSYM(x8) a1_ne_0_b_l1 ! r__r_8a0 ! MILLIRETN ! nop
+LSYM(x9) a1_ne_0_b_l0 ! t0__9a0 ! MILLIRET ! r__r_t0
+LSYM(x10) t0__5a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x11) t0__3a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+LSYM(x12) t0__3a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x13) t0__5a0 ! a1_ne_0_b_l0 ! r__r_8a0 ! b_n_ret_t0
+LSYM(x14) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x15) t0__5a0 ! a1_ne_0_b_l0 ! t0__3t0 ! b_n_ret_t0
+LSYM(x16) t0__16a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x17) t0__9a0 ! a1_ne_0_b_l0 ! t0__t0_8a0 ! b_n_ret_t0
+LSYM(x18) t0__9a0 ! a1_ne_0_b_l1 ! r__r_2t0 ! MILLIRETN
+LSYM(x19) t0__9a0 ! a1_ne_0_b_l0 ! t0__2t0_a0 ! b_n_ret_t0
+LSYM(x20) t0__5a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x21) t0__5a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x22) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x23) t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x24) t0__3a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x25) t0__5a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+LSYM(x26) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x27) t0__3a0 ! a1_ne_0_b_l0 ! t0__9t0 ! b_n_ret_t0
+LSYM(x28) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x29) t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x30) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+LSYM(x31) t0__32a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x32) t0__32a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x33) t0__8a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x34) t0__16a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x35) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__t0_8a0
+LSYM(x36) t0__9a0 ! a1_ne_0_b_l1 ! r__r_4t0 ! MILLIRETN
+LSYM(x37) t0__9a0 ! a1_ne_0_b_l0 ! t0__4t0_a0 ! b_n_ret_t0
+LSYM(x38) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x39) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x40) t0__5a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x41) t0__5a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+LSYM(x42) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x43) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x44) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x45) t0__9a0 ! a1_ne_0_b_l0 ! t0__5t0 ! b_n_ret_t0
+LSYM(x46) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_a0
+LSYM(x47) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x48) t0__3a0 ! a1_ne_0_b_l0 ! t0__16t0 ! b_n_ret_t0
+LSYM(x49) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__t0_4a0
+LSYM(x50) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+LSYM(x51) t0__9a0 ! t0__t0_8a0 ! b_e_t0 ! t0__3t0
+LSYM(x52) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x53) t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x54) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_2t0
+LSYM(x55) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x56) t0__3a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x57) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x58) t0__3a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x59) t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x60) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x61) t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x62) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x63) t0__64a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x64) t0__64a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x65) t0__8a0 ! a1_ne_0_b_l0 ! t0__8t0_a0 ! b_n_ret_t0
+LSYM(x66) t0__32a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x67) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x68) t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x69) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x70) t0__64a0 ! t0__t0_4a0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x71) t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x72) t0__9a0 ! a1_ne_0_b_l1 ! r__r_8t0 ! MILLIRETN
+LSYM(x73) t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_t0
+LSYM(x74) t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x75) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x76) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x77) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x78) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x79) t0__16a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x80) t0__16a0 ! t0__5t0 ! b_e_shift ! r__r_t0
+LSYM(x81) t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_t0
+LSYM(x82) t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x83) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x84) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x85) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x86) t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x87) t0__9a0 ! t0__9t0 ! b_e_t02a0 ! t0__t0_4a0
+LSYM(x88) t0__5a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x89) t0__5a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x90) t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_2t0
+LSYM(x91) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x92) t0__5a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x93) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__3t0
+LSYM(x94) t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__t0_2a0
+LSYM(x95) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x96) t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x97) t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x98) t0__32a0 ! t0__3t0 ! b_e_t0 ! t0__t0_2a0
+LSYM(x99) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x100) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+LSYM(x101) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x102) t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+LSYM(x103) t0__5a0 ! t0__5t0 ! b_e_t02a0 ! t0__4t0_a0
+LSYM(x104) t0__3a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x105) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x106) t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x107) t0__9a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__8t0_a0
+LSYM(x108) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_4t0
+LSYM(x109) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x110) t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x111) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x112) t0__3a0 ! t0__2t0_a0 ! b_e_t0 ! t0__16t0
+LSYM(x113) t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x114) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x115) t0__9a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x116) t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x117) t0__3a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x118) t0__3a0 ! t0__4t0_a0 ! b_e_t0a0 ! t0__9t0
+LSYM(x119) t0__3a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__9t0
+LSYM(x120) t0__5a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x121) t0__5a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x122) t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x123) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x124) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+LSYM(x125) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+LSYM(x126) t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x127) t0__128a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+LSYM(x128) t0__128a0 ! a1_ne_0_b_l1 ! r__r_t0 ! MILLIRETN
+LSYM(x129) t0__128a0 ! a1_ne_0_b_l0 ! t0__t0_a0 ! b_n_ret_t0
+LSYM(x130) t0__64a0 ! t0__t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x131) t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x132) t0__8a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x133) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x134) t0__8a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x135) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__3t0
+LSYM(x136) t0__8a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x137) t0__8a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x138) t0__8a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x139) t0__8a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__4t0_a0
+LSYM(x140) t0__3a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__5t0
+LSYM(x141) t0__8a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x142) t0__9a0 ! t0__8t0 ! b_e_2t0 ! t0__t0ma0
+LSYM(x143) t0__16a0 ! t0__9t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x144) t0__9a0 ! t0__8t0 ! b_e_shift ! r__r_2t0
+LSYM(x145) t0__9a0 ! t0__8t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x146) t0__9a0 ! t0__8t0_a0 ! b_e_shift ! r__r_2t0
+LSYM(x147) t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x148) t0__9a0 ! t0__4t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x149) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x150) t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x151) t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x152) t0__9a0 ! t0__2t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x153) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x154) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x155) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__5t0
+LSYM(x156) t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x157) t0__32a0 ! t0__t0ma0 ! b_e_t02a0 ! t0__5t0
+LSYM(x158) t0__16a0 ! t0__5t0 ! b_e_2t0 ! t0__t0ma0
+LSYM(x159) t0__32a0 ! t0__5t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x160) t0__5a0 ! t0__4t0 ! b_e_shift ! r__r_8t0
+LSYM(x161) t0__8a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x162) t0__9a0 ! t0__9t0 ! b_e_shift ! r__r_2t0
+LSYM(x163) t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__2t0_a0
+LSYM(x164) t0__5a0 ! t0__8t0_a0 ! b_e_shift ! r__r_4t0
+LSYM(x165) t0__8a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x166) t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x167) t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x168) t0__5a0 ! t0__4t0_a0 ! b_e_shift ! r__r_8t0
+LSYM(x169) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x170) t0__32a0 ! t0__t0_2a0 ! b_e_t0 ! t0__5t0
+LSYM(x171) t0__9a0 ! t0__2t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x172) t0__5a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x173) t0__9a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__9t0
+LSYM(x174) t0__32a0 ! t0__t0_2a0 ! b_e_t04a0 ! t0__5t0
+LSYM(x175) t0__8a0 ! t0__2t0_a0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x176) t0__5a0 ! t0__4t0_a0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x177) t0__5a0 ! t0__4t0_a0 ! b_e_8t0a0 ! t0__t0_a0
+LSYM(x178) t0__5a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__8t0_a0
+LSYM(x179) t0__5a0 ! t0__2t0_a0 ! b_e_2t0a0 ! t0__8t0_a0
+LSYM(x180) t0__9a0 ! t0__5t0 ! b_e_shift ! r__r_4t0
+LSYM(x181) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x182) t0__9a0 ! t0__5t0 ! b_e_2t0 ! t0__2t0_a0
+LSYM(x183) t0__9a0 ! t0__5t0 ! b_e_2t0a0 ! t0__2t0_a0
+LSYM(x184) t0__5a0 ! t0__9t0 ! b_e_4t0 ! t0__t0_a0
+LSYM(x185) t0__9a0 ! t0__4t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x186) t0__32a0 ! t0__t0ma0 ! b_e_2t0 ! t0__3t0
+LSYM(x187) t0__9a0 ! t0__4t0_a0 ! b_e_t02a0 ! t0__5t0
+LSYM(x188) t0__9a0 ! t0__5t0 ! b_e_4t0 ! t0__t0_2a0
+LSYM(x189) t0__5a0 ! t0__4t0_a0 ! b_e_t0 ! t0__9t0
+LSYM(x190) t0__9a0 ! t0__2t0_a0 ! b_e_2t0 ! t0__5t0
+LSYM(x191) t0__64a0 ! t0__3t0 ! b_e_t0 ! t0__t0ma0
+LSYM(x192) t0__8a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x193) t0__8a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x194) t0__8a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x195) t0__8a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x196) t0__8a0 ! t0__3t0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x197) t0__8a0 ! t0__3t0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x198) t0__64a0 ! t0__t0_2a0 ! b_e_t0 ! t0__3t0
+LSYM(x199) t0__8a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x200) t0__5a0 ! t0__5t0 ! b_e_shift ! r__r_8t0
+LSYM(x201) t0__5a0 ! t0__5t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x202) t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x203) t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__4t0_a0
+LSYM(x204) t0__8a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+LSYM(x205) t0__5a0 ! t0__8t0_a0 ! b_e_t0 ! t0__5t0
+LSYM(x206) t0__64a0 ! t0__t0_4a0 ! b_e_t02a0 ! t0__3t0
+LSYM(x207) t0__8a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+LSYM(x208) t0__5a0 ! t0__5t0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x209) t0__5a0 ! t0__5t0 ! b_e_8t0a0 ! t0__t0_a0
+LSYM(x210) t0__5a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__5t0
+LSYM(x211) t0__5a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__5t0
+LSYM(x212) t0__3a0 ! t0__4t0_a0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x213) t0__3a0 ! t0__4t0_a0 ! b_e_4t0a0 ! t0__4t0_a0
+LSYM(x214) t0__9a0 ! t0__t0_4a0 ! b_e_2t04a0 ! t0__8t0_a0
+LSYM(x215) t0__5a0 ! t0__4t0_a0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x216) t0__9a0 ! t0__3t0 ! b_e_shift ! r__r_8t0
+LSYM(x217) t0__9a0 ! t0__3t0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x218) t0__9a0 ! t0__3t0 ! b_e_2t0 ! t0__4t0_a0
+LSYM(x219) t0__9a0 ! t0__8t0_a0 ! b_e_t0 ! t0__3t0
+LSYM(x220) t0__3a0 ! t0__9t0 ! b_e_4t0 ! t0__2t0_a0
+LSYM(x221) t0__3a0 ! t0__9t0 ! b_e_4t0a0 ! t0__2t0_a0
+LSYM(x222) t0__9a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x223) t0__9a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x224) t0__9a0 ! t0__3t0 ! b_e_8t0 ! t0__t0_a0
+LSYM(x225) t0__9a0 ! t0__5t0 ! b_e_t0 ! t0__5t0
+LSYM(x226) t0__3a0 ! t0__2t0_a0 ! b_e_t02a0 ! t0__32t0
+LSYM(x227) t0__9a0 ! t0__5t0 ! b_e_t02a0 ! t0__5t0
+LSYM(x228) t0__9a0 ! t0__2t0_a0 ! b_e_4t0 ! t0__3t0
+LSYM(x229) t0__9a0 ! t0__2t0_a0 ! b_e_4t0a0 ! t0__3t0
+LSYM(x230) t0__9a0 ! t0__5t0 ! b_e_5t0 ! t0__t0_a0
+LSYM(x231) t0__9a0 ! t0__2t0_a0 ! b_e_3t0 ! t0__4t0_a0
+LSYM(x232) t0__3a0 ! t0__2t0_a0 ! b_e_8t0 ! t0__4t0_a0
+LSYM(x233) t0__3a0 ! t0__2t0_a0 ! b_e_8t0a0 ! t0__4t0_a0
+LSYM(x234) t0__3a0 ! t0__4t0_a0 ! b_e_2t0 ! t0__9t0
+LSYM(x235) t0__3a0 ! t0__4t0_a0 ! b_e_2t0a0 ! t0__9t0
+LSYM(x236) t0__9a0 ! t0__2t0_a0 ! b_e_4t08a0 ! t0__3t0
+LSYM(x237) t0__16a0 ! t0__5t0 ! b_e_3t0 ! t0__t0ma0
+LSYM(x238) t0__3a0 ! t0__4t0_a0 ! b_e_2t04a0 ! t0__9t0
+LSYM(x239) t0__16a0 ! t0__5t0 ! b_e_t0ma0 ! t0__3t0
+LSYM(x240) t0__9a0 ! t0__t0_a0 ! b_e_8t0 ! t0__3t0
+LSYM(x241) t0__9a0 ! t0__t0_a0 ! b_e_8t0a0 ! t0__3t0
+LSYM(x242) t0__5a0 ! t0__3t0 ! b_e_2t0 ! t0__8t0_a0
+LSYM(x243) t0__9a0 ! t0__9t0 ! b_e_t0 ! t0__3t0
+LSYM(x244) t0__5a0 ! t0__3t0 ! b_e_4t0 ! t0__4t0_a0
+LSYM(x245) t0__8a0 ! t0__3t0 ! b_e_5t0 ! t0__2t0_a0
+LSYM(x246) t0__5a0 ! t0__8t0_a0 ! b_e_2t0 ! t0__3t0
+LSYM(x247) t0__5a0 ! t0__8t0_a0 ! b_e_2t0a0 ! t0__3t0
+LSYM(x248) t0__32a0 ! t0__t0ma0 ! b_e_shift ! r__r_8t0
+LSYM(x249) t0__32a0 ! t0__t0ma0 ! b_e_t0 ! t0__8t0_a0
+LSYM(x250) t0__5a0 ! t0__5t0 ! b_e_2t0 ! t0__5t0
+LSYM(x251) t0__5a0 ! t0__5t0 ! b_e_2t0a0 ! t0__5t0
+LSYM(x252) t0__64a0 ! t0__t0ma0 ! b_e_shift ! r__r_4t0
+LSYM(x253) t0__64a0 ! t0__t0ma0 ! b_e_t0 ! t0__4t0_a0
+LSYM(x254) t0__128a0 ! t0__t0ma0 ! b_e_shift ! r__r_2t0
+LSYM(x255) t0__256a0 ! a1_ne_0_b_l0 ! t0__t0ma0 ! b_n_ret_t0
+/*1040 insts before this. */
+LSYM(ret_t0) MILLIRET
+LSYM(e_t0) r__r_t0
+LSYM(e_shift) a1_ne_0_b_l2
+ a0__256a0 /* a0 <<= 8 *********** */
+ MILLIRETN
+LSYM(e_t0ma0) a1_ne_0_b_l0
+ t0__t0ma0
+ MILLIRET
+ r__r_t0
+LSYM(e_t0a0) a1_ne_0_b_l0
+ t0__t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e_t02a0) a1_ne_0_b_l0
+ t0__t0_2a0
+ MILLIRET
+ r__r_t0
+LSYM(e_t04a0) a1_ne_0_b_l0
+ t0__t0_4a0
+ MILLIRET
+ r__r_t0
+LSYM(e_2t0) a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+LSYM(e_2t0a0) a1_ne_0_b_l0
+ t0__2t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e2t04a0) t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_2t0
+ MILLIRETN
+LSYM(e_3t0) a1_ne_0_b_l0
+ t0__3t0
+ MILLIRET
+ r__r_t0
+LSYM(e_4t0) a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+LSYM(e_4t0a0) a1_ne_0_b_l0
+ t0__4t0_a0
+ MILLIRET
+ r__r_t0
+LSYM(e4t08a0) t0__t0_2a0
+ a1_ne_0_b_l1
+ r__r_4t0
+ MILLIRETN
+LSYM(e_5t0) a1_ne_0_b_l0
+ t0__5t0
+ MILLIRET
+ r__r_t0
+LSYM(e_8t0) a1_ne_0_b_l1
+ r__r_8t0
+ MILLIRETN
+LSYM(e_8t0a0) a1_ne_0_b_l0
+ t0__8t0_a0
+ MILLIRET
+ r__r_t0
+
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/remI.S b/arch/parisc/lib/milli/remI.S
new file mode 100644
index 00000000000..63bc094471e
--- /dev/null
+++ b/arch/parisc/lib/milli/remI.S
@@ -0,0 +1,185 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_remI
+/* ROUTINE: $$remI
+
+ DESCRIPTION:
+ . $$remI returns the remainder of the division of two signed 32-bit
+ . integers. The sign of the remainder is the same as the sign of
+ . the dividend.
+
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = destroyed
+ . arg1 = destroyed
+ . ret1 = remainder
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: DIVIDE BY ZERO
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable
+ . Does not create a stack frame
+ . Is usable for internal or external microcode
+
+ DISCUSSION:
+ . Calls other millicode routines via mrp: NONE
+ . Calls other millicode routines: NONE */
+
+RDEFINE(tmp,r1)
+RDEFINE(retreg,ret1)
+
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$remI)
+GSYM($$remoI)
+ .export $$remI,MILLICODE
+ .export $$remoI,MILLICODE
+ ldo -1(arg1),tmp /* is there at most one bit set ? */
+ and,<> arg1,tmp,r0 /* if not, don't use power of 2 */
+ addi,> 0,arg1,r0 /* if denominator > 0, use power */
+ /* of 2 */
+ b,n LREF(neg_denom)
+LSYM(pow2)
+ comb,>,n 0,arg0,LREF(neg_num) /* is numerator < 0 ? */
+ and arg0,tmp,retreg /* get the result */
+ MILLIRETN
+LSYM(neg_num)
+ subi 0,arg0,arg0 /* negate numerator */
+ and arg0,tmp,retreg /* get the result */
+ subi 0,retreg,retreg /* negate result */
+ MILLIRETN
+LSYM(neg_denom)
+ addi,< 0,arg1,r0 /* if arg1 >= 0, it's not power */
+ /* of 2 */
+ b,n LREF(regular_seq)
+ sub r0,arg1,tmp /* make denominator positive */
+ comb,=,n arg1,tmp,LREF(regular_seq) /* test against 0x80000000 and 0 */
+ ldo -1(tmp),retreg /* is there at most one bit set ? */
+ and,= tmp,retreg,r0 /* if not, go to regular_seq */
+ b,n LREF(regular_seq)
+ comb,>,n 0,arg0,LREF(neg_num_2) /* if arg0 < 0, negate it */
+ and arg0,retreg,retreg
+ MILLIRETN
+LSYM(neg_num_2)
+ subi 0,arg0,tmp /* test against 0x80000000 */
+ and tmp,retreg,retreg
+ subi 0,retreg,retreg
+ MILLIRETN
+LSYM(regular_seq)
+ addit,= 0,arg1,0 /* trap if div by zero */
+ add,>= 0,arg0,retreg /* move dividend, if retreg < 0, */
+ sub 0,retreg,retreg /* make it positive */
+ sub 0,arg1, tmp /* clear carry, */
+ /* negate the divisor */
+ ds 0, tmp,0 /* set V-bit to the comple- */
+ /* ment of the divisor sign */
+ or 0,0, tmp /* clear tmp */
+ add retreg,retreg,retreg /* shift msb bit into carry */
+ ds tmp,arg1, tmp /* 1st divide step, if no carry */
+ /* out, msb of quotient = 0 */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+LSYM(t1)
+ ds tmp,arg1, tmp /* 2nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 3rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 4th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 5th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 6th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 7th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 8th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 9th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 10th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 11th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 12th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 13th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 14th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 15th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 16th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 17th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 18th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 19th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 20th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 21st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 22nd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 23rd divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 24th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 25th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 26th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 27th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 28th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 29th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 30th divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 31st divide step */
+ addc retreg,retreg,retreg /* shift retreg with/into carry */
+ ds tmp,arg1, tmp /* 32nd divide step, */
+ addc retreg,retreg,retreg /* shift last bit into retreg */
+ movb,>=,n tmp,retreg,LREF(finish) /* branch if pos. tmp */
+ add,< arg1,0,0 /* if arg1 > 0, add arg1 */
+ add,tr tmp,arg1,retreg /* for correcting remainder tmp */
+ sub tmp,arg1,retreg /* else add absolute value arg1 */
+LSYM(finish)
+ add,>= arg0,0,0 /* set sign of remainder */
+ sub 0,retreg,retreg /* to sign of dividend */
+ MILLIRET
+ nop
+ .exit
+ .procend
+#ifdef milliext
+ .origin 0x00000200
+#endif
+ .end
+#endif
diff --git a/arch/parisc/lib/milli/remU.S b/arch/parisc/lib/milli/remU.S
new file mode 100644
index 00000000000..c0a2d6e247c
--- /dev/null
+++ b/arch/parisc/lib/milli/remU.S
@@ -0,0 +1,148 @@
+/* 32 and 64-bit millicode, original author Hewlett-Packard
+ adapted for gcc by Paul Bame <bame@debian.org>
+ and Alan Modra <alan@linuxcare.com.au>.
+
+ Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+ This file is part of GCC and is released under the terms of
+ of the GNU General Public License as published by the Free Software
+ Foundation; either version 2, or (at your option) any later version.
+ See the file COPYING in the top-level GCC source directory for a copy
+ of the license. */
+
+#include "milli.h"
+
+#ifdef L_remU
+/* ROUTINE: $$remU
+ . Single precision divide for remainder with unsigned binary integers.
+ .
+ . The remainder must be dividend-(dividend/divisor)*divisor.
+ . Divide by zero is trapped.
+
+ INPUT REGISTERS:
+ . arg0 == dividend
+ . arg1 == divisor
+ . mrp == return pc
+ . sr0 == return space when called externally
+
+ OUTPUT REGISTERS:
+ . arg0 = undefined
+ . arg1 = undefined
+ . ret1 = remainder
+
+ OTHER REGISTERS AFFECTED:
+ . r1 = undefined
+
+ SIDE EFFECTS:
+ . Causes a trap under the following conditions: DIVIDE BY ZERO
+ . Changes memory at the following places: NONE
+
+ PERMISSIBLE CONTEXT:
+ . Unwindable.
+ . Does not create a stack frame.
+ . Suitable for internal or external millicode.
+ . Assumes the special millicode register conventions.
+
+ DISCUSSION:
+ . Calls other millicode routines using mrp: NONE
+ . Calls other millicode routines: NONE */
+
+
+RDEFINE(temp,r1)
+RDEFINE(rmndr,ret1) /* r29 */
+ SUBSPA_MILLI
+ ATTR_MILLI
+ .export $$remU,millicode
+ .proc
+ .callinfo millicode
+ .entry
+GSYM($$remU)
+ ldo -1(arg1),temp /* is there at most one bit set ? */
+ and,= arg1,temp,r0 /* if not, don't use power of 2 */
+ b LREF(regular_seq)
+ addit,= 0,arg1,r0 /* trap on div by zero */
+ and arg0,temp,rmndr /* get the result for power of 2 */
+ MILLIRETN
+LSYM(regular_seq)
+ comib,>=,n 0,arg1,LREF(special_case)
+ subi 0,arg1,rmndr /* clear carry, negate the divisor */
+ ds r0,rmndr,r0 /* set V-bit to 1 */
+ add arg0,arg0,temp /* shift msb bit into carry */
+ ds r0,arg1,rmndr /* 1st divide step, if no carry */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 2nd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 3rd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 4th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 5th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 6th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 7th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 8th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 9th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 10th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 11th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 12th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 13th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 14th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 15th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 16th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 17th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 18th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 19th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 20th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 21st divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 22nd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 23rd divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 24th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 25th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 26th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 27th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 28th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 29th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 30th divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 31st divide step */
+ addc temp,temp,temp /* shift temp with/into carry */
+ ds rmndr,arg1,rmndr /* 32nd divide step, */
+ comiclr,<= 0,rmndr,r0
+ add rmndr,arg1,rmndr /* correction */
+ MILLIRETN
+ nop
+
+/* Putting >= on the last DS and deleting COMICLR does not work! */
+LSYM(special_case)
+ sub,>>= arg0,arg1,rmndr
+ copy arg0,rmndr
+ MILLIRETN
+ nop
+ .exit
+ .procend
+ .end
+#endif
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 1c091b415cd..b2e3e9a8cec 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -211,7 +211,7 @@ bad_area:
#ifdef PRINT_USER_FAULTS
printk(KERN_DEBUG "\n");
printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n",
- tsk->pid, tsk->comm, code, address);
+ task_pid_nr(tsk), tsk->comm, code, address);
if (vma) {
printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n",
vma->vm_start, vma->vm_end);
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index e724b362c49..aa875fa4348 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -607,7 +607,7 @@ void show_mem(void)
printk("Zone list for zone %d on node %d: ", j, i);
for (k = 0; zl->zones[k] != NULL; k++)
- printk("[%ld/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
+ printk("[%d/%s] ", zone_to_nid(zl->zones[k]), zl->zones[k]->name);
printk("\n");
}
}
diff --git a/arch/parisc/oprofile/Kconfig b/arch/parisc/oprofile/Kconfig
deleted file mode 100644
index 5ade19801b9..00000000000
--- a/arch/parisc/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 3763f681ce4..18f397ca05e 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -669,20 +669,7 @@ source "arch/powerpc/sysdev/qe_lib/Kconfig"
source "lib/Kconfig"
-menu "Instrumentation Support"
-
-source "arch/powerpc/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes"
- depends on !BOOKE && !4xx && KALLSYMS && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
source "arch/powerpc/Kconfig.debug"
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index bc45f5fbb06..6731763f028 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -70,18 +70,16 @@
};
gpt@600 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <0>;
reg = <600 10>;
interrupts = <1 9 0>;
interrupt-parent = <&mpc5200_pic>;
- has-wdt;
+ fsl,has-wdt;
};
gpt@610 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <1>;
reg = <610 10>;
interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
};
gpt@620 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <2>;
reg = <620 10>;
interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
};
gpt@630 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <3>;
reg = <630 10>;
interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
};
gpt@640 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <4>;
reg = <640 10>;
interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
};
gpt@650 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <5>;
reg = <650 10>;
interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
};
gpt@660 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <6>;
reg = <660 10>;
interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
};
gpt@670 { // General Purpose Timer
- compatible = "mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200-gpt";
cell-index = <7>;
reg = <670 10>;
interrupts = <1 10 0>;
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index 6582c9a39b2..b540388c608 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -70,18 +70,16 @@
};
gpt@600 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <0>;
reg = <600 10>;
interrupts = <1 9 0>;
interrupt-parent = <&mpc5200_pic>;
- has-wdt;
+ fsl,has-wdt;
};
gpt@610 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <1>;
reg = <610 10>;
interrupts = <1 a 0>;
@@ -89,8 +87,7 @@
};
gpt@620 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <2>;
reg = <620 10>;
interrupts = <1 b 0>;
@@ -98,8 +95,7 @@
};
gpt@630 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <3>;
reg = <630 10>;
interrupts = <1 c 0>;
@@ -107,8 +103,7 @@
};
gpt@640 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <4>;
reg = <640 10>;
interrupts = <1 d 0>;
@@ -116,8 +111,7 @@
};
gpt@650 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <5>;
reg = <650 10>;
interrupts = <1 e 0>;
@@ -125,8 +119,7 @@
};
gpt@660 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <6>;
reg = <660 10>;
interrupts = <1 f 0>;
@@ -134,8 +127,7 @@
};
gpt@670 { // General Purpose Timer
- compatible = "mpc5200b-gpt","mpc5200-gpt";
- device_type = "gpt";
+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt";
cell-index = <7>;
reg = <670 10>;
interrupts = <1 10 0>;
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 8b47c846421..dcd7c02727c 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -68,6 +68,7 @@ CONFIG_SYSVIPC_SYSCTL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=15
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index bb8d4e46f0c..05582af50c5 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -71,6 +71,7 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index c09eb8cfbe7..62a38406b62 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -71,6 +71,7 @@ CONFIG_AUDITSYSCALL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
diff --git a/arch/powerpc/kernel/cpu_setup_6xx.S b/arch/powerpc/kernel/cpu_setup_6xx.S
index 8b4a4ee85ec..f1ee0b3f78f 100644
--- a/arch/powerpc/kernel/cpu_setup_6xx.S
+++ b/arch/powerpc/kernel/cpu_setup_6xx.S
@@ -113,7 +113,7 @@ setup_604_hid0:
* around #3 and with the same fix we use. We may want to
* check if the CPU is using 60x bus mode in which case
* the workaround for errata #4 is useless. Also, we may
- * want to explicitely clear HID0_NOPDST as this is not
+ * want to explicitly clear HID0_NOPDST as this is not
* needed once we have applied workaround #5 (though it's
* not set by Apple's firmware at least).
*/
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 9001104b56b..14206e3f081 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -161,8 +161,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
int i;
for_each_sg(sgl, sg, nents, i) {
- sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
- dma_direct_offset;
+ sg->dma_address = sg_phys(sg) | dma_direct_offset;
sg->dma_length = sg->length;
}
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 289d7e93591..72fd87156b2 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -102,8 +102,7 @@ static int ibmebus_map_sg(struct device *dev,
int i;
for_each_sg(sgl, sg, nents, i) {
- sg->dma_address = (dma_addr_t)page_address(sg->page)
- + sg->offset;
+ sg->dma_address = (dma_addr_t) sg_virt(sg);
sg->dma_length = sg->length;
}
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 306a6f75b6c..2d0c9ef555e 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -307,7 +307,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
continue;
}
/* Allocate iommu entries for that segment */
- vaddr = (unsigned long)page_address(s->page) + s->offset;
+ vaddr = (unsigned long) sg_virt(s);
npages = iommu_num_pages(vaddr, slen);
entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 2250f9e6c5c..b0e5deb4274 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -491,7 +491,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
/* Legacy flags are left to default at this point,
* one can then use irq_create_mapping() to
- * explicitely change them
+ * explicitly change them
*/
ops->map(host, i, i);
}
diff --git a/arch/powerpc/kernel/l2cr_6xx.S b/arch/powerpc/kernel/l2cr_6xx.S
index 858f28ac8a0..2a2f3c3f6d8 100644
--- a/arch/powerpc/kernel/l2cr_6xx.S
+++ b/arch/powerpc/kernel/l2cr_6xx.S
@@ -1,6 +1,6 @@
/*
L2CR functions
- Copyright 1997-1998 by PowerLogix R & D, Inc.
+ Copyright © 1997-1998 by PowerLogix R & D, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index e60a0c544d6..c0c8e8c3ced 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -61,45 +61,39 @@ NORET_TYPE void machine_kexec(struct kimage *image)
for(;;);
}
-static int __init early_parse_crashk(char *p)
-{
- unsigned long size;
-
- if (!p)
- return 1;
-
- size = memparse(p, &p);
-
- if (*p == '@')
- crashk_res.start = memparse(p + 1, &p);
- else
- crashk_res.start = KDUMP_KERNELBASE;
-
- crashk_res.end = crashk_res.start + size - 1;
-
- return 0;
-}
-early_param("crashkernel", early_parse_crashk);
-
void __init reserve_crashkernel(void)
{
- unsigned long size;
+ unsigned long long crash_size, crash_base;
+ int ret;
+
+ /* this is necessary because of lmb_phys_mem_size() */
+ lmb_analyze();
+
+ /* use common parsing */
+ ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(),
+ &crash_size, &crash_base);
+ if (ret == 0 && crash_size > 0) {
+ if (crash_base == 0)
+ crash_base = KDUMP_KERNELBASE;
+ crashk_res.start = crash_base;
+ } else {
+ /* handle the device tree */
+ crash_size = crashk_res.end - crashk_res.start + 1;
+ }
- if (crashk_res.start == 0)
+ if (crash_size == 0)
return;
/* We might have got these values via the command line or the
* device tree, either way sanitise them now. */
- size = crashk_res.end - crashk_res.start + 1;
-
if (crashk_res.start != KDUMP_KERNELBASE)
printk("Crash kernel location must be 0x%x\n",
KDUMP_KERNELBASE);
crashk_res.start = KDUMP_KERNELBASE;
- size = PAGE_ALIGN(size);
- crashk_res.end = crashk_res.start + size - 1;
+ crash_size = PAGE_ALIGN(crash_size);
+ crashk_res.end = crashk_res.start + crash_size - 1;
/* Crash kernel trumps memory limit */
if (memory_limit && memory_limit <= crashk_res.end) {
@@ -108,7 +102,13 @@ void __init reserve_crashkernel(void)
memory_limit);
}
- lmb_reserve(crashk_res.start, size);
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crashk_res.start >> 20),
+ (unsigned long)(lmb_phys_mem_size() >> 20));
+
+ lmb_reserve(crashk_res.start, crash_size);
}
int overlaps_crashkernel(unsigned long start, unsigned long size)
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index ea6ad7a2a7e..b9d88374f14 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -459,7 +459,7 @@ void show_regs(struct pt_regs * regs)
printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr);
#endif
printk("TASK = %p[%d] '%s' THREAD: %p",
- current, current->pid, current->comm, task_thread_info(current));
+ current, task_pid_nr(current), current->comm, task_thread_info(current));
#ifdef CONFIG_SMP
printk(" CPU: %d", smp_processor_id());
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index bf9e39c6e29..59c464e26f3 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -201,7 +201,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_init(current)) {
+ if (is_global_init(current)) {
__sighandler_t handler;
spin_lock_irq(&current->sighand->siglock);
@@ -881,7 +881,7 @@ void nonrecoverable_exception(struct pt_regs *regs)
void trace_syscall(struct pt_regs *regs)
{
printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n",
- current, current->pid, regs->nip, regs->link, regs->gpr[0],
+ current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0],
regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted());
}
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index ab3546c5ac3..a18fda361cc 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -375,7 +375,7 @@ bad_area_nosemaphore:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/powerpc/oprofile/Kconfig b/arch/powerpc/oprofile/Kconfig
deleted file mode 100644
index 7089e79689b..00000000000
--- a/arch/powerpc/oprofile/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-config OPROFILE_CELL
- bool "OProfile for Cell Broadband Engine"
- depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m)
- default y
- help
- Profiling of Cell BE SPUs requires special support enabled
- by this option.
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 65b7ae42623..25d2bfa3d9d 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -145,6 +145,9 @@ static void __init lite5200_setup_arch(void)
/* Some mpc5200 & mpc5200b related configuration */
mpc5200_setup_xlb_arbiter();
+ /* Map wdt for mpc52xx_restart() */
+ mpc52xx_map_wdt();
+
#ifdef CONFIG_PM
mpc52xx_suspend.board_suspend_prepare = lite5200_suspend_prepare;
mpc52xx_suspend.board_resume_finish = lite5200_resume_finish;
@@ -183,5 +186,6 @@ define_machine(lite5200) {
.init = mpc52xx_declare_of_platform_devices,
.init_IRQ = mpc52xx_init_irq,
.get_irq = mpc52xx_get_irq,
+ .restart = mpc52xx_restart,
.calibrate_decr = generic_calibrate_decr,
};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 3bc201e07e6..9850685c542 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -18,15 +18,20 @@
#include <asm/prom.h>
#include <asm/mpc52xx.h>
+/*
+ * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
+ * Permanent mapping is required because mpc52xx_restart() can be called
+ * from interrupt context while node mapping (which calls ioremap())
+ * cannot be used at such point.
+ */
+static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
-void __iomem *
-mpc52xx_find_and_map(const char *compatible)
+static void __iomem *
+mpc52xx_map_node(struct device_node *ofn)
{
- struct device_node *ofn;
const u32 *regaddr_p;
u64 regaddr64, size64;
- ofn = of_find_compatible_node(NULL, NULL, compatible);
if (!ofn)
return NULL;
@@ -42,8 +47,23 @@ mpc52xx_find_and_map(const char *compatible)
return ioremap((u32)regaddr64, (u32)size64);
}
+
+void __iomem *
+mpc52xx_find_and_map(const char *compatible)
+{
+ return mpc52xx_map_node(
+ of_find_compatible_node(NULL, NULL, compatible));
+}
+
EXPORT_SYMBOL(mpc52xx_find_and_map);
+void __iomem *
+mpc52xx_find_and_map_path(const char *path)
+{
+ return mpc52xx_map_node(of_find_node_by_path(path));
+}
+
+EXPORT_SYMBOL(mpc52xx_find_and_map_path);
/**
* mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
@@ -113,3 +133,46 @@ mpc52xx_declare_of_platform_devices(void)
"Error while probing of_platform bus\n");
}
+void __init
+mpc52xx_map_wdt(void)
+{
+ const void *has_wdt;
+ struct device_node *np;
+
+ /* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
+ * possibly from a interrupt context. wdt is only implement
+ * on a gpt0, so check has-wdt property before mapping.
+ */
+ for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
+ has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
+ if (has_wdt) {
+ mpc52xx_wdt = mpc52xx_map_node(np);
+ return;
+ }
+ }
+ for_each_compatible_node(np, NULL, "mpc5200-gpt") {
+ has_wdt = of_get_property(np, "has-wdt", NULL);
+ if (has_wdt) {
+ mpc52xx_wdt = mpc52xx_map_node(np);
+ return;
+ }
+ }
+}
+
+void
+mpc52xx_restart(char *cmd)
+{
+ local_irq_disable();
+
+ /* Turn on the watchdog and wait for it to expire.
+ * It effectively does a reset. */
+ if (mpc52xx_wdt) {
+ out_be32(&mpc52xx_wdt->mode, 0x00000000);
+ out_be32(&mpc52xx_wdt->count, 0x000000ff);
+ out_be32(&mpc52xx_wdt->mode, 0x00009004);
+ } else
+ printk("mpc52xx_restart: Can't access wdt. "
+ "Restart impossible, system halted.\n");
+
+ while (1);
+}
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 229d355ed86..ea22cad2cd0 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -120,7 +120,7 @@ config PPC_PMI
depends on PPC_IBM_CELL_BLADE
help
PMI (Platform Management Interrupt) is a way to
- communicate with the BMC (Baseboard Mangement Controller).
+ communicate with the BMC (Baseboard Management Controller).
It is used in some IBM Cell blades.
default m
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index d72b16d6816..d9e56a50379 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -748,7 +748,7 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
if (count)
goto out;
- /* write aѕ much as possible */
+ /* write as much as possible */
for (count = 4, udata++; (count + 4) <= len; count += 4, udata++) {
int ret;
ret = __get_user(wbox_data, udata);
diff --git a/arch/powerpc/platforms/celleb/scc_uhc.c b/arch/powerpc/platforms/celleb/scc_uhc.c
index a7c548bde2e..b59c38a06e3 100644
--- a/arch/powerpc/platforms/celleb/scc_uhc.c
+++ b/arch/powerpc/platforms/celleb/scc_uhc.c
@@ -36,7 +36,7 @@ static inline int uhc_clkctrl_ready(u32 val)
}
/*
- * UHC(usb host controler) enable function.
+ * UHC(usb host controller) enable function.
* affect to both of OHCI and EHCI core module.
*/
static void enable_scc_uhc(struct pci_dev *dev)
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index 354c0586162..144177d77cf 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -41,13 +41,13 @@
#include <linux/root_dev.h>
#include <linux/serial.h>
#include <linux/smp.h>
+#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/pgtable.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/kexec.h>
#include <asm/pci-bridge.h>
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 07e64b48e7f..6405f4a3676 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -628,9 +628,8 @@ static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
int i;
for_each_sg(sgl, sg, nents, i) {
- int result = ps3_dma_map(dev->d_region,
- page_to_phys(sg->page) + sg->offset, sg->length,
- &sg->dma_address, 0);
+ int result = ps3_dma_map(dev->d_region, sg_phys(sg),
+ sg->length, &sg->dma_address, 0);
if (result) {
pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 3a393c7f390..a1ab25c7082 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -332,7 +332,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err)
err->disposition == RTAS_DISP_NOT_RECOVERED &&
err->target == RTAS_TARGET_MEMORY &&
err->type == RTAS_TYPE_ECC_UNCORR &&
- !(current->pid == 0 || is_init(current))) {
+ !(current->pid == 0 || is_global_init(current))) {
/* Kill off a user process with an ECC error */
printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n",
current->pid);
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.c b/arch/powerpc/sysdev/bestcomm/bestcomm.c
index 48492a83e5a..740ad73ce5c 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.c
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.c
@@ -269,6 +269,7 @@ bcom_engine_init(void)
int task;
phys_addr_t tdt_pa, ctx_pa, var_pa, fdt_pa;
unsigned int tdt_size, ctx_size, var_size, fdt_size;
+ u16 regval;
/* Allocate & clear SRAM zones for FDT, TDTs, contexts and vars/incs */
tdt_size = BCOM_MAX_TASKS * sizeof(struct bcom_tdt);
@@ -319,9 +320,11 @@ bcom_engine_init(void)
/* Init 'always' initiator */
out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ALWAYS], BCOM_IPR_ALWAYS);
- /* Disable COMM Bus Prefetch, apparently it's not reliable yet */
- /* FIXME: This should be done on 5200 and not 5200B ... */
- out_be16(&bcom_eng->regs->PtdCntrl, in_be16(&bcom_eng->regs->PtdCntrl) | 1);
+ /* Disable COMM Bus Prefetch on the original 5200; it's broken */
+ if ((mfspr(SPRN_SVR) & MPC5200_SVR_MASK) == MPC5200_SVR) {
+ regval = in_be16(&bcom_eng->regs->PtdCntrl);
+ out_be16(&bcom_eng->regs->PtdCntrl, regval | 1);
+ }
/* Init lock */
spin_lock_init(&bcom_eng->lock);
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index 607925c8a99..6473fa7cb4b 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1317,7 +1317,7 @@ endmenu
source "lib/Kconfig"
-source "arch/powerpc/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/ppc/Kconfig.debug"
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 487dc66dcc7..500497e3c72 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -13,6 +13,8 @@
# modified by Cort (cort@cs.nmt.edu)
#
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS += -fno-builtin -D__BOOTER__ -Iarch/$(ARCH)/boot/include
HOSTCFLAGS += -Iarch/$(ARCH)/boot/include
BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 3f3b292eb77..c78568905c3 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -121,7 +121,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
* generate the same exception over and over again and we get
* nowhere. Better to kill it and let the kernel panic.
*/
- if (is_init(current)) {
+ if (is_global_init(current)) {
__sighandler_t handler;
spin_lock_irq(&current->sighand->siglock);
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 94913ddcf76..254c23b755e 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -290,7 +290,7 @@ bad_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c
index 248684f50dd..dcd6070b85e 100644
--- a/arch/ppc/platforms/chestnut.c
+++ b/arch/ppc/platforms/chestnut.c
@@ -49,7 +49,6 @@ extern void gen550_progress(char *, unsigned short);
extern void gen550_init(int, struct uart_port *);
extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh);
-#define BIT(x) (1<<x)
#define CHESTNUT_PRESERVE_MASK (BIT(MV64x60_CPU2DEV_0_WIN) | \
BIT(MV64x60_CPU2DEV_1_WIN) | \
BIT(MV64x60_CPU2DEV_2_WIN) | \
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index b71132166f6..4ec716d8c1a 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -529,21 +529,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-menu "Instrumentation Support"
-
-source "arch/s390/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes (EXPERIMENTAL)"
- depends on EXPERIMENTAL && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-
-endmenu
+source "kernel/Kconfig.instrumentation"
source "arch/s390/Kconfig.debug"
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 2aae23dba4b..ece7b99da89 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Tue Jul 17 12:50:23 2007
+# Linux kernel version: 2.6.23
+# Mon Oct 22 12:10:44 2007
#
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
@@ -19,15 +19,11 @@ CONFIG_S390=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
-# Code maturity level options
+# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
@@ -42,7 +38,14 @@ CONFIG_AUDIT=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_NS=y
+CONFIG_CGROUP_CPUACCT=y
# CONFIG_CPUSETS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
# CONFIG_RELAY is not set
CONFIG_BLK_DEV_INITRD=y
@@ -63,7 +66,6 @@ CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
@@ -83,6 +85,7 @@ CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
CONFIG_BLK_DEV_BSG=y
+CONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
@@ -108,7 +111,6 @@ CONFIG_64BIT=y
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_HOTPLUG_CPU=y
-CONFIG_DEFAULT_MIGRATION_COST=1000000
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_AUDIT_ARCH=y
@@ -143,9 +145,11 @@ CONFIG_FLATMEM_MANUAL=y
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_HOLES_IN_ZONE=y
@@ -219,12 +223,14 @@ CONFIG_INET_TUNNEL=y
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IP_VS is not set
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_IPV6_ROUTER_PREF is not set
@@ -243,7 +249,48 @@ CONFIG_IPV6_SIT=y
# CONFIG_IPV6_TUNNEL is not set
# CONFIG_IPV6_MULTIPLE_TABLES is not set
# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+CONFIG_NETFILTER_NETLINK=m
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK_ENABLED=m
+CONFIG_NF_CONNTRACK=m
+# CONFIG_NF_CT_ACCT is not set
+# CONFIG_NF_CONNTRACK_MARK is not set
+# CONFIG_NF_CONNTRACK_EVENTS is not set
+# CONFIG_NF_CT_PROTO_SCTP is not set
+# CONFIG_NF_CT_PROTO_UDPLITE is not set
+# CONFIG_NF_CONNTRACK_AMANDA is not set
+# CONFIG_NF_CONNTRACK_FTP is not set
+# CONFIG_NF_CONNTRACK_H323 is not set
+# CONFIG_NF_CONNTRACK_IRC is not set
+# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
+# CONFIG_NF_CONNTRACK_PPTP is not set
+# CONFIG_NF_CONNTRACK_SANE is not set
+# CONFIG_NF_CONNTRACK_SIP is not set
+# CONFIG_NF_CONNTRACK_TFTP is not set
+# CONFIG_NF_CT_NETLINK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_CONNTRACK_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration (EXPERIMENTAL)
+#
+# CONFIG_NF_CONNTRACK_IPV6 is not set
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
# CONFIG_IP_DCCP is not set
CONFIG_IP_SCTP=m
# CONFIG_SCTP_DBG_MSG is not set
@@ -263,12 +310,7 @@ CONFIG_SCTP_HMAC_MD5=y
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_FIFO=y
#
# Queueing/Scheduling
@@ -306,10 +348,12 @@ CONFIG_NET_CLS_ACT=y
CONFIG_NET_ACT_POLICE=y
# CONFIG_NET_ACT_GACT is not set
# CONFIG_NET_ACT_MIRRED is not set
+CONFIG_NET_ACT_NAT=m
# CONFIG_NET_ACT_PEDIT is not set
# CONFIG_NET_ACT_SIMP is not set
CONFIG_NET_CLS_POLICE=y
# CONFIG_NET_CLS_IND is not set
+CONFIG_NET_SCH_FIFO=y
#
# Network testing
@@ -329,6 +373,7 @@ CONFIG_CCW=y
#
# Generic Driver Options
#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
@@ -400,17 +445,11 @@ CONFIG_SCSI_FC_ATTRS=y
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_SCSI_DEBUG is not set
CONFIG_ZFCP=y
-
-#
-# Multi-device support (RAID and LVM)
-#
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=m
@@ -429,7 +468,9 @@ CONFIG_DM_ZERO=y
CONFIG_DM_MULTIPATH=y
# CONFIG_DM_MULTIPATH_EMC is not set
# CONFIG_DM_MULTIPATH_RDAC is not set
+# CONFIG_DM_MULTIPATH_HP is not set
# CONFIG_DM_DELAY is not set
+# CONFIG_DM_UEVENT is not set
CONFIG_NETDEVICES=y
# CONFIG_NETDEVICES_MULTIQUEUE is not set
# CONFIG_IFB is not set
@@ -438,8 +479,13 @@ CONFIG_BONDING=m
# CONFIG_MACVLAN is not set
CONFIG_EQUALIZER=m
CONFIG_TUN=m
+CONFIG_VETH=m
CONFIG_NET_ETHERNET=y
# CONFIG_MII is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
CONFIG_NETDEV_1000=y
CONFIG_NETDEV_10000=y
# CONFIG_TR is not set
@@ -473,7 +519,6 @@ CONFIG_CCWGROUP=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_WATCHDOG is not set
CONFIG_HW_RANDOM=m
# CONFIG_R3964 is not set
CONFIG_RAW_DRIVER=m
@@ -490,7 +535,6 @@ CONFIG_TN3270_CONSOLE=y
CONFIG_TN3215=y
CONFIG_TN3215_CONSOLE=y
CONFIG_CCW_CONSOLE=y
-CONFIG_SCLP=y
CONFIG_SCLP_TTY=y
CONFIG_SCLP_CONSOLE=y
CONFIG_SCLP_VT220_TTY=y
@@ -514,6 +558,11 @@ CONFIG_S390_TAPE_34XX=m
CONFIG_MONWRITER=m
CONFIG_S390_VMUR=m
# CONFIG_POWER_SUPPLY is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
#
# File systems
@@ -569,7 +618,6 @@ CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
CONFIG_CONFIGFS_FS=m
#
@@ -588,10 +636,7 @@ CONFIG_CONFIGFS_FS=m
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
@@ -638,27 +683,13 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
# CONFIG_NLS is not set
-
-#
-# Distributed Lock Manager
-#
CONFIG_DLM=m
# CONFIG_DLM_DEBUG is not set
-
-#
-# Instrumentation Support
-#
-
-#
-# Profiling support
-#
+CONFIG_INSTRUMENTATION=y
# CONFIG_PROFILING is not set
CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -682,6 +713,7 @@ CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
@@ -694,14 +726,17 @@ CONFIG_FORCED_INLINING=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
+CONFIG_SAMPLES=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_HASH=m
CONFIG_CRYPTO_MANAGER=y
@@ -720,6 +755,7 @@ CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_XTS is not set
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_DES is not set
CONFIG_CRYPTO_FCRYPT=m
@@ -733,11 +769,13 @@ CONFIG_CRYPTO_FCRYPT=m
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_SEED=m
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_CRC32C is not set
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
+CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_SHA1_S390 is not set
# CONFIG_CRYPTO_SHA256_S390 is not set
@@ -755,5 +793,6 @@ CONFIG_BITREVERSE=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=m
+CONFIG_CRC7=m
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 66b51901c87..ce0856d3250 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -648,6 +648,8 @@ static int dump_set_type(enum dump_type type)
case DUMP_TYPE_CCW:
if (MACHINE_IS_VM)
dump_method = DUMP_METHOD_CCW_VM;
+ else if (diag308_set_works)
+ dump_method = DUMP_METHOD_CCW_DIAG;
else
dump_method = DUMP_METHOD_CCW_CIO;
break;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index abb447a3e47..96492cf2d49 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -44,6 +44,7 @@
#include <asm/processor.h>
#include <asm/irq.h>
#include <asm/timer.h>
+#include <asm/cpu.h>
asmlinkage void ret_from_fork(void) asm ("ret_from_fork");
@@ -91,6 +92,14 @@ EXPORT_SYMBOL(unregister_idle_notifier);
void do_monitor_call(struct pt_regs *regs, long interruption_code)
{
+ struct s390_idle_data *idle;
+
+ idle = &__get_cpu_var(s390_idle);
+ spin_lock(&idle->lock);
+ idle->idle_time += get_clock() - idle->idle_enter;
+ idle->in_idle = 0;
+ spin_unlock(&idle->lock);
+
/* disable monitor call class 0 */
__ctl_clear_bit(8, 15);
@@ -105,6 +114,7 @@ extern void s390_handle_mcck(void);
static void default_idle(void)
{
int cpu, rc;
+ struct s390_idle_data *idle;
/* CPU is going idle. */
cpu = smp_processor_id();
@@ -142,6 +152,12 @@ static void default_idle(void)
return;
}
+ idle = &__get_cpu_var(s390_idle);
+ spin_lock(&idle->lock);
+ idle->idle_count++;
+ idle->in_idle = 1;
+ idle->idle_enter = get_clock();
+ spin_unlock(&idle->lock);
trace_hardirqs_on();
/* Wait for external, I/O or machine check interrupt. */
__load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
@@ -166,7 +182,7 @@ void show_regs(struct pt_regs *regs)
printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted());
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
- current->comm, current->pid, (void *) tsk,
+ current->comm, task_pid_nr(current), (void *) tsk,
(void *) tsk->thread.ksp);
show_registers(regs);
@@ -254,14 +270,12 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
save_fp_regs(&current->thread.fp_regs);
memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
sizeof(s390_fp_regs));
- p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS)
p->thread.acrs[0] = regs->gprs[6];
#else /* CONFIG_64BIT */
/* Save the fpu registers to new thread structure. */
save_fp_regs(&p->thread.fp_regs);
- p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _REGION_TABLE;
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS) {
if (test_thread_flag(TIF_31BIT)) {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 35edbef1d22..1d97fe1c0e5 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -42,6 +42,7 @@
#include <asm/tlbflush.h>
#include <asm/timer.h>
#include <asm/lowcore.h>
+#include <asm/cpu.h>
/*
* An array with a pointer the lowcore of every CPU.
@@ -325,7 +326,7 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig)
*/
void smp_ptlb_callback(void *info)
{
- local_flush_tlb();
+ __tlb_flush_local();
}
void smp_ptlb_all(void)
@@ -494,6 +495,8 @@ int __cpuinit start_secondary(void *cpuvoid)
return 0;
}
+DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
+
static void __init smp_create_idle(unsigned int cpu)
{
struct task_struct *p;
@@ -506,6 +509,7 @@ static void __init smp_create_idle(unsigned int cpu)
if (IS_ERR(p))
panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
current_set[cpu] = p;
+ spin_lock_init(&(&per_cpu(s390_idle, cpu))->lock);
}
static int cpu_stopped(int cpu)
@@ -724,6 +728,7 @@ void __init smp_prepare_boot_cpu(void)
cpu_set(0, cpu_online_map);
S390_lowcore.percpu_offset = __per_cpu_offset[0];
current_set[0] = current;
+ spin_lock_init(&(&__get_cpu_var(s390_idle))->lock);
}
void __init smp_cpus_done(unsigned int max_cpus)
@@ -756,22 +761,71 @@ static ssize_t show_capability(struct sys_device *dev, char *buf)
}
static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
+static ssize_t show_idle_count(struct sys_device *dev, char *buf)
+{
+ struct s390_idle_data *idle;
+ unsigned long long idle_count;
+
+ idle = &per_cpu(s390_idle, dev->id);
+ spin_lock_irq(&idle->lock);
+ idle_count = idle->idle_count;
+ spin_unlock_irq(&idle->lock);
+ return sprintf(buf, "%llu\n", idle_count);
+}
+static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
+
+static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+{
+ struct s390_idle_data *idle;
+ unsigned long long new_time;
+
+ idle = &per_cpu(s390_idle, dev->id);
+ spin_lock_irq(&idle->lock);
+ if (idle->in_idle) {
+ new_time = get_clock();
+ idle->idle_time += new_time - idle->idle_enter;
+ idle->idle_enter = new_time;
+ }
+ new_time = idle->idle_time;
+ spin_unlock_irq(&idle->lock);
+ return sprintf(buf, "%llu us\n", new_time >> 12);
+}
+static SYSDEV_ATTR(idle_time, 0444, show_idle_time, NULL);
+
+static struct attribute *cpu_attrs[] = {
+ &attr_capability.attr,
+ &attr_idle_count.attr,
+ &attr_idle_time.attr,
+ NULL,
+};
+
+static struct attribute_group cpu_attr_group = {
+ .attrs = cpu_attrs,
+};
+
static int __cpuinit smp_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned int)(long)hcpu;
struct cpu *c = &per_cpu(cpu_devices, cpu);
struct sys_device *s = &c->sysdev;
+ struct s390_idle_data *idle;
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- if (sysdev_create_file(s, &attr_capability))
+ idle = &per_cpu(s390_idle, cpu);
+ spin_lock_irq(&idle->lock);
+ idle->idle_enter = 0;
+ idle->idle_time = 0;
+ idle->idle_count = 0;
+ spin_unlock_irq(&idle->lock);
+ if (sysfs_create_group(&s->kobj, &cpu_attr_group))
return NOTIFY_BAD;
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- sysdev_remove_file(s, &attr_capability);
+ sysfs_remove_group(&s->kobj, &cpu_attr_group);
break;
}
return NOTIFY_OK;
@@ -784,6 +838,7 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
static int __init topology_init(void)
{
int cpu;
+ int rc;
register_cpu_notifier(&smp_cpu_nb);
@@ -796,7 +851,9 @@ static int __init topology_init(void)
if (!cpu_online(cpu))
continue;
s = &c->sysdev;
- sysdev_create_file(s, &attr_capability);
+ rc = sysfs_create_group(&s->kobj, &cpu_attr_group);
+ if (rc)
+ return rc;
}
return 0;
}
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
index 60604b2819b..7e8efaade2e 100644
--- a/arch/s390/lib/uaccess_pt.c
+++ b/arch/s390/lib/uaccess_pt.c
@@ -15,6 +15,27 @@
#include <asm/futex.h>
#include "uaccess.h"
+static inline pte_t *follow_table(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+ return NULL;
+
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+ return NULL;
+
+ pmd = pmd_offset(pud, addr);
+ if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
+ return NULL;
+
+ return pte_offset_map(pmd, addr);
+}
+
static int __handle_fault(struct mm_struct *mm, unsigned long address,
int write_access)
{
@@ -64,7 +85,7 @@ out:
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
@@ -85,8 +106,6 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
{
struct mm_struct *mm = current->mm;
unsigned long offset, pfn, done, size;
- pgd_t *pgd;
- pmd_t *pmd;
pte_t *pte;
void *from, *to;
@@ -94,15 +113,7 @@ static size_t __user_copy_pt(unsigned long uaddr, void *kptr,
retry:
spin_lock(&mm->page_table_lock);
do {
- pgd = pgd_offset(mm, uaddr);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- goto fault;
-
- pmd = pmd_offset(pgd, uaddr);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
- goto fault;
-
- pte = pte_offset_map(pmd, uaddr);
+ pte = follow_table(mm, uaddr);
if (!pte || !pte_present(*pte) ||
(write_user && !pte_write(*pte)))
goto fault;
@@ -142,22 +153,12 @@ static unsigned long __dat_user_addr(unsigned long uaddr)
{
struct mm_struct *mm = current->mm;
unsigned long pfn, ret;
- pgd_t *pgd;
- pmd_t *pmd;
pte_t *pte;
int rc;
ret = 0;
retry:
- pgd = pgd_offset(mm, uaddr);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- goto fault;
-
- pmd = pmd_offset(pgd, uaddr);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
- goto fault;
-
- pte = pte_offset_map(pmd, uaddr);
+ pte = follow_table(mm, uaddr);
if (!pte || !pte_present(*pte))
goto fault;
@@ -229,8 +230,6 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
unsigned long uaddr = (unsigned long) src;
struct mm_struct *mm = current->mm;
unsigned long offset, pfn, done, len;
- pgd_t *pgd;
- pmd_t *pmd;
pte_t *pte;
size_t len_str;
@@ -240,15 +239,7 @@ static size_t strnlen_user_pt(size_t count, const char __user *src)
retry:
spin_lock(&mm->page_table_lock);
do {
- pgd = pgd_offset(mm, uaddr);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- goto fault;
-
- pmd = pmd_offset(pgd, uaddr);
- if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
- goto fault;
-
- pte = pte_offset_map(pmd, uaddr);
+ pte = follow_table(mm, uaddr);
if (!pte || !pte_present(*pte))
goto fault;
@@ -308,8 +299,6 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
uaddr, done, size;
unsigned long uaddr_from = (unsigned long) from;
unsigned long uaddr_to = (unsigned long) to;
- pgd_t *pgd_from, *pgd_to;
- pmd_t *pmd_from, *pmd_to;
pte_t *pte_from, *pte_to;
int write_user;
@@ -317,39 +306,14 @@ static size_t copy_in_user_pt(size_t n, void __user *to,
retry:
spin_lock(&mm->page_table_lock);
do {
- pgd_from = pgd_offset(mm, uaddr_from);
- if (pgd_none(*pgd_from) || unlikely(pgd_bad(*pgd_from))) {
- uaddr = uaddr_from;
- write_user = 0;
- goto fault;
- }
- pgd_to = pgd_offset(mm, uaddr_to);
- if (pgd_none(*pgd_to) || unlikely(pgd_bad(*pgd_to))) {
- uaddr = uaddr_to;
- write_user = 1;
- goto fault;
- }
-
- pmd_from = pmd_offset(pgd_from, uaddr_from);
- if (pmd_none(*pmd_from) || unlikely(pmd_bad(*pmd_from))) {
- uaddr = uaddr_from;
- write_user = 0;
- goto fault;
- }
- pmd_to = pmd_offset(pgd_to, uaddr_to);
- if (pmd_none(*pmd_to) || unlikely(pmd_bad(*pmd_to))) {
- uaddr = uaddr_to;
- write_user = 1;
- goto fault;
- }
-
- pte_from = pte_offset_map(pmd_from, uaddr_from);
+ pte_from = follow_table(mm, uaddr_from);
if (!pte_from || !pte_present(*pte_from)) {
uaddr = uaddr_from;
write_user = 0;
goto fault;
}
- pte_to = pte_offset_map(pmd_to, uaddr_to);
+
+ pte_to = follow_table(mm, uaddr_to);
if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) {
uaddr = uaddr_to;
write_user = 1;
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile
index f95449b29fa..66401930f83 100644
--- a/arch/s390/mm/Makefile
+++ b/arch/s390/mm/Makefile
@@ -2,6 +2,6 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
-obj-y := init.o fault.o extmem.o mmap.o vmem.o
+obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o
obj-$(CONFIG_CMM) += cmm.o
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 14c241ccdd4..2456b52ed06 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -211,7 +211,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
struct mm_struct *mm = tsk->mm;
up_read(&mm->mmap_sem);
- if (is_init(tsk)) {
+ if (is_global_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
return 1;
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 3a25bbf2eb0..b234bb4a6da 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -81,6 +81,7 @@ void show_mem(void)
static void __init setup_ro_region(void)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
pte_t new_pte;
@@ -91,7 +92,8 @@ static void __init setup_ro_region(void)
for (; address < end; address += PAGE_SIZE) {
pgd = pgd_offset_k(address);
- pmd = pmd_offset(pgd, address);
+ pud = pud_offset(pgd, address);
+ pmd = pmd_offset(pud, address);
pte = pte_offset_kernel(pmd, address);
new_pte = mk_pte_phys(address, __pgprot(_PAGE_RO));
*pte = new_pte;
@@ -103,32 +105,28 @@ static void __init setup_ro_region(void)
*/
void __init paging_init(void)
{
- pgd_t *pg_dir;
- int i;
- unsigned long pgdir_k;
static const int ssm_mask = 0x04000000L;
unsigned long max_zone_pfns[MAX_NR_ZONES];
+ unsigned long pgd_type;
- pg_dir = swapper_pg_dir;
-
+ init_mm.pgd = swapper_pg_dir;
+ S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
#ifdef CONFIG_64BIT
- pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERN_REGION_TABLE;
- for (i = 0; i < PTRS_PER_PGD; i++)
- pgd_clear_kernel(pg_dir + i);
+ S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
+ pgd_type = _REGION3_ENTRY_EMPTY;
#else
- pgdir_k = (__pa(swapper_pg_dir) & PAGE_MASK) | _KERNSEG_TABLE;
- for (i = 0; i < PTRS_PER_PGD; i++)
- pmd_clear_kernel((pmd_t *)(pg_dir + i));
+ S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH;
+ pgd_type = _SEGMENT_ENTRY_EMPTY;
#endif
+ clear_table((unsigned long *) init_mm.pgd, pgd_type,
+ sizeof(unsigned long)*2048);
vmem_map_init();
setup_ro_region();
- S390_lowcore.kernel_asce = pgdir_k;
-
/* enable virtual mapping in kernel mode */
- __ctl_load(pgdir_k, 1, 1);
- __ctl_load(pgdir_k, 7, 7);
- __ctl_load(pgdir_k, 13, 13);
+ __ctl_load(S390_lowcore.kernel_asce, 1, 1);
+ __ctl_load(S390_lowcore.kernel_asce, 7, 7);
+ __ctl_load(S390_lowcore.kernel_asce, 13, 13);
__raw_local_irq_ssm(ssm_mask);
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
new file mode 100644
index 00000000000..e60e0ae1340
--- /dev/null
+++ b/arch/s390/mm/pgtable.c
@@ -0,0 +1,94 @@
+/*
+ * arch/s390/mm/pgtable.c
+ *
+ * Copyright IBM Corp. 2007
+ * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/quicklist.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_64BIT
+#define ALLOC_ORDER 1
+#else
+#define ALLOC_ORDER 2
+#endif
+
+unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
+{
+ struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+
+ if (!page)
+ return NULL;
+ page->index = 0;
+ if (noexec) {
+ struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
+ if (!shadow) {
+ __free_pages(page, ALLOC_ORDER);
+ return NULL;
+ }
+ page->index = page_to_phys(shadow);
+ }
+ return (unsigned long *) page_to_phys(page);
+}
+
+void crst_table_free(unsigned long *table)
+{
+ unsigned long *shadow = get_shadow_table(table);
+
+ if (shadow)
+ free_pages((unsigned long) shadow, ALLOC_ORDER);
+ free_pages((unsigned long) table, ALLOC_ORDER);
+}
+
+/*
+ * page table entry allocation/free routines.
+ */
+unsigned long *page_table_alloc(int noexec)
+{
+ struct page *page = alloc_page(GFP_KERNEL);
+ unsigned long *table;
+
+ if (!page)
+ return NULL;
+ page->index = 0;
+ if (noexec) {
+ struct page *shadow = alloc_page(GFP_KERNEL);
+ if (!shadow) {
+ __free_page(page);
+ return NULL;
+ }
+ table = (unsigned long *) page_to_phys(shadow);
+ clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+ page->index = (addr_t) table;
+ }
+ table = (unsigned long *) page_to_phys(page);
+ clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+ return table;
+}
+
+void page_table_free(unsigned long *table)
+{
+ unsigned long *shadow = get_shadow_pte(table);
+
+ if (shadow)
+ free_page((unsigned long) shadow);
+ free_page((unsigned long) table);
+
+}
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index fd594d5fe14..fb9c5a85aa5 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -73,31 +73,28 @@ static void __init_refok *vmem_alloc_pages(unsigned int order)
return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
}
+#define vmem_pud_alloc() ({ BUG(); ((pud_t *) NULL); })
+
static inline pmd_t *vmem_pmd_alloc(void)
{
- pmd_t *pmd;
- int i;
+ pmd_t *pmd = NULL;
- pmd = vmem_alloc_pages(PMD_ALLOC_ORDER);
+#ifdef CONFIG_64BIT
+ pmd = vmem_alloc_pages(2);
if (!pmd)
return NULL;
- for (i = 0; i < PTRS_PER_PMD; i++)
- pmd_clear_kernel(pmd + i);
+ clear_table((unsigned long *) pmd, _SEGMENT_ENTRY_EMPTY, PAGE_SIZE*4);
+#endif
return pmd;
}
static inline pte_t *vmem_pte_alloc(void)
{
- pte_t *pte;
- pte_t empty_pte;
- int i;
+ pte_t *pte = vmem_alloc_pages(0);
- pte = vmem_alloc_pages(PTE_ALLOC_ORDER);
if (!pte)
return NULL;
- pte_val(empty_pte) = _PAGE_TYPE_EMPTY;
- for (i = 0; i < PTRS_PER_PTE; i++)
- pte[i] = empty_pte;
+ clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, PAGE_SIZE);
return pte;
}
@@ -108,6 +105,7 @@ static int vmem_add_range(unsigned long start, unsigned long size)
{
unsigned long address;
pgd_t *pg_dir;
+ pud_t *pu_dir;
pmd_t *pm_dir;
pte_t *pt_dir;
pte_t pte;
@@ -116,13 +114,21 @@ static int vmem_add_range(unsigned long start, unsigned long size)
for (address = start; address < start + size; address += PAGE_SIZE) {
pg_dir = pgd_offset_k(address);
if (pgd_none(*pg_dir)) {
+ pu_dir = vmem_pud_alloc();
+ if (!pu_dir)
+ goto out;
+ pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+ }
+
+ pu_dir = pud_offset(pg_dir, address);
+ if (pud_none(*pu_dir)) {
pm_dir = vmem_pmd_alloc();
if (!pm_dir)
goto out;
- pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+ pud_populate_kernel(&init_mm, pu_dir, pm_dir);
}
- pm_dir = pmd_offset(pg_dir, address);
+ pm_dir = pmd_offset(pu_dir, address);
if (pmd_none(*pm_dir)) {
pt_dir = vmem_pte_alloc();
if (!pt_dir)
@@ -148,6 +154,7 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
{
unsigned long address;
pgd_t *pg_dir;
+ pud_t *pu_dir;
pmd_t *pm_dir;
pte_t *pt_dir;
pte_t pte;
@@ -155,9 +162,10 @@ static void vmem_remove_range(unsigned long start, unsigned long size)
pte_val(pte) = _PAGE_TYPE_EMPTY;
for (address = start; address < start + size; address += PAGE_SIZE) {
pg_dir = pgd_offset_k(address);
- if (pgd_none(*pg_dir))
+ pu_dir = pud_offset(pg_dir, address);
+ if (pud_none(*pu_dir))
continue;
- pm_dir = pmd_offset(pg_dir, address);
+ pm_dir = pmd_offset(pu_dir, address);
if (pmd_none(*pm_dir))
continue;
pt_dir = pte_offset_kernel(pm_dir, address);
@@ -174,6 +182,7 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
unsigned long address, start_addr, end_addr;
struct page *map_start, *map_end;
pgd_t *pg_dir;
+ pud_t *pu_dir;
pmd_t *pm_dir;
pte_t *pt_dir;
pte_t pte;
@@ -188,13 +197,21 @@ static int vmem_add_mem_map(unsigned long start, unsigned long size)
for (address = start_addr; address < end_addr; address += PAGE_SIZE) {
pg_dir = pgd_offset_k(address);
if (pgd_none(*pg_dir)) {
+ pu_dir = vmem_pud_alloc();
+ if (!pu_dir)
+ goto out;
+ pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+ }
+
+ pu_dir = pud_offset(pg_dir, address);
+ if (pud_none(*pu_dir)) {
pm_dir = vmem_pmd_alloc();
if (!pm_dir)
goto out;
- pgd_populate_kernel(&init_mm, pg_dir, pm_dir);
+ pud_populate_kernel(&init_mm, pu_dir, pm_dir);
}
- pm_dir = pmd_offset(pg_dir, address);
+ pm_dir = pmd_offset(pu_dir, address);
if (pmd_none(*pm_dir)) {
pt_dir = vmem_pte_alloc();
if (!pt_dir)
diff --git a/arch/s390/oprofile/Kconfig b/arch/s390/oprofile/Kconfig
deleted file mode 100644
index 208220a5f23..00000000000
--- a/arch/s390/oprofile/Kconfig
+++ /dev/null
@@ -1,22 +0,0 @@
-
-menu "Profiling support"
-
-config PROFILING
- bool "Profiling support"
- help
- Say Y here to enable profiling support mechanisms used by
- profilers such as readprofile or OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 44982c1dfa2..247f8a65e73 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -758,7 +758,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/sh/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/sh/Kconfig.debug"
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index 790ed69b866..5c17de51987 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -104,24 +104,3 @@ NORET_TYPE void machine_kexec(struct kimage *image)
(*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
}
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel. By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
- unsigned long size, base;
- size = memparse(arg, &arg);
- if (*arg == '@') {
- base = memparse(arg+1, &arg);
- /* FIXME: Do I want a sanity check
- * to validate the memory range?
- */
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- return 0;
-}
-early_param("crashkernel", parse_crashkernel);
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index b4469992d6b..6d7f2b07e49 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -121,7 +121,7 @@ void machine_power_off(void)
void show_regs(struct pt_regs * regs)
{
printk("\n");
- printk("Pid : %d, Comm: %20s\n", current->pid, current->comm);
+ printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
print_symbol("PC is at %s\n", instruction_pointer(regs));
printk("PC : %08lx SP : %08lx SR : %08lx ",
regs->pc, regs->regs[15], regs->sr);
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index b3027a6775b..b749403f6b3 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -128,6 +128,37 @@ static void __init register_bootmem_low_pages(void)
free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
}
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+ unsigned long long free_mem;
+ unsigned long long crash_size, crash_base;
+ int ret;
+
+ free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+ ret = parse_crashkernel(boot_command_line, free_mem,
+ &crash_size, &crash_base);
+ if (ret == 0 && crash_size) {
+ if (crash_base > 0) {
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crash_base >> 20),
+ (unsigned long)(free_mem >> 20));
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+ reserve_bootmem(crash_base, crash_size);
+ } else
+ printk(KERN_INFO "crashkernel reservation failed - "
+ "you have to specify a base address\n");
+ }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
void __init setup_bootmem_allocator(unsigned long free_pfn)
{
unsigned long bootmap_size;
@@ -189,11 +220,8 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
}
}
#endif
-#ifdef CONFIG_KEXEC
- if (crashk_res.start != crashk_res.end)
- reserve_bootmem(crashk_res.start,
- crashk_res.end - crashk_res.start + 1);
-#endif
+
+ reserve_crashkernel();
}
#ifndef CONFIG_NEED_MULTIPLE_NODES
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 2f42442cf16..ca754fd4243 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -382,7 +382,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
set_fs(USER_DS);
pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
- current->comm, current->pid, frame, regs->pc, regs->pr);
+ current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
flush_cache_sigtramp(regs->pr);
@@ -462,7 +462,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
set_fs(USER_DS);
pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
- current->comm, current->pid, frame, regs->pc, regs->pr);
+ current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
flush_cache_sigtramp(regs->pr);
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index dcb46e71da1..cf99111cb33 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -95,8 +95,8 @@ void die(const char * str, struct pt_regs * regs, long err)
print_modules();
show_regs(regs);
- printk("Process: %s (pid: %d, stack limit = %p)\n",
- current->comm, current->pid, task_stack_page(current) + 1);
+ printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm,
+ task_pid_nr(current), task_stack_page(current) + 1);
if (!user_mode(regs) || in_interrupt())
dump_mem("Stack: ", regs->regs[15], THREAD_SIZE +
@@ -386,7 +386,8 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs)
printk(KERN_NOTICE "Fixing up unaligned userspace access "
"in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n",
- current->comm,current->pid,(u16*)regs->pc,instruction);
+ current->comm, task_pid_nr(current),
+ (u16 *)regs->pc, instruction);
}
ret = -EFAULT;
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 4729668ce5b..f33cedb353f 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -207,7 +207,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/sh/oprofile/Kconfig b/arch/sh/oprofile/Kconfig
deleted file mode 100644
index 5ade19801b9..00000000000
--- a/arch/sh/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/sh64/Kconfig b/arch/sh64/Kconfig
index b3327ce8e82..ba204bac49d 100644
--- a/arch/sh64/Kconfig
+++ b/arch/sh64/Kconfig
@@ -284,7 +284,7 @@ source "drivers/Kconfig"
source "fs/Kconfig"
-source "arch/sh64/oprofile/Kconfig"
+source "kernel/Kconfig.instrumentation"
source "arch/sh64/Kconfig.debug"
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c
index 388bb711f1b..b4d9534d2b0 100644
--- a/arch/sh64/kernel/pci_sh5.c
+++ b/arch/sh64/kernel/pci_sh5.c
@@ -480,7 +480,7 @@ static int __init pcibios_init(void)
return -EINVAL;
}
- /* The pci subsytem needs to know where memory is and how much
+ /* The pci subsystem needs to know where memory is and how much
* of it there is. I've simply made these globals. A better mechanism
* is probably needed.
*/
diff --git a/arch/sh64/kernel/traps.c b/arch/sh64/kernel/traps.c
index 9d0d58fb29f..c03101fab46 100644
--- a/arch/sh64/kernel/traps.c
+++ b/arch/sh64/kernel/traps.c
@@ -764,7 +764,7 @@ static int misaligned_fixup(struct pt_regs *regs)
--user_mode_unaligned_fixup_count;
/* Only do 'count' worth of these reports, to remove a potential DoS against syslog */
printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
- current->comm, current->pid, (__u32)regs->pc, opcode);
+ current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
} else
#endif
if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) {
@@ -774,7 +774,7 @@ static int misaligned_fixup(struct pt_regs *regs)
(__u32)regs->pc, opcode);
} else {
printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n",
- current->comm, current->pid, (__u32)regs->pc, opcode);
+ current->comm, task_pid_nr(current), (__u32)regs->pc, opcode);
}
}
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index dd81c669c79..7c79a1ba805 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -81,7 +81,7 @@ static inline void print_vma(struct vm_area_struct *vma)
static inline void print_task(struct task_struct *tsk)
{
- printk("Task pid %d\n", tsk->pid);
+ printk("Task pid %d\n", task_pid_nr(tsk));
}
static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address)
@@ -272,13 +272,13 @@ bad_area:
* usermode, so only need a few */
count++;
printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n",
- address, current->pid, current->comm,
+ address, task_pid_nr(current), current->comm,
(unsigned long) regs->pc);
#if 0
show_regs(regs);
#endif
}
- if (is_init(tsk)) {
+ if (is_global_init(tsk)) {
panic("INIT had user mode bad_area\n");
}
tsk->thread.address = address;
@@ -320,14 +320,14 @@ no_context:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (is_init(current)) {
+ if (is_global_init(current)) {
panic("INIT out of memory\n");
yield();
goto survive;
}
printk("fault:Out of memory\n");
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/sh64/oprofile/Kconfig b/arch/sh64/oprofile/Kconfig
deleted file mode 100644
index 19d37730b66..00000000000
--- a/arch/sh64/oprofile/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-
-menu "Profiling support"
- depends on EXPERIMENTAL
-
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
-endmenu
-
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index c0f4ba109da..527adc808ad 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -320,11 +320,7 @@ endmenu
source "fs/Kconfig"
-menu "Instrumentation Support"
-
-source "arch/sparc/oprofile/Kconfig"
-
-endmenu
+source "kernel/Kconfig.instrumentation"
source "arch/sparc/Kconfig.debug"
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 9c3ed88853f..97aa50d1e4a 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -727,9 +727,8 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
BUG_ON(direction == PCI_DMA_NONE);
/* IIep is write-through, not flushing. */
for_each_sg(sgl, sg, nents, n) {
- BUG_ON(page_address(sg->page) == NULL);
- sg->dvma_address =
- virt_to_phys(page_address(sg->page)) + sg->offset;
+ BUG_ON(page_address(sg_page(sg)) == NULL);
+ sg->dvma_address = virt_to_phys(sg_virt(sg));
sg->dvma_length = sg->length;
}
return nents;
@@ -748,9 +747,9 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
for_each_sg(sgl, sg, nents, n) {
- BUG_ON(page_address(sg->page) == NULL);
+ BUG_ON(page_address(sg_page(sg)) == NULL);
mmu_inval_dma_area(
- (unsigned long) page_address(sg->page),
+ (unsigned long) page_address(sg_page(sg)),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
}
}
@@ -798,9 +797,9 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
for_each_sg(sgl, sg, nents, n) {
- BUG_ON(page_address(sg->page) == NULL);
+ BUG_ON(page_address(sg_page(sg)) == NULL);
mmu_inval_dma_area(
- (unsigned long) page_address(sg->page),
+ (unsigned long) page_address(sg_page(sg)),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
}
}
@@ -814,9 +813,9 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
BUG_ON(direction == PCI_DMA_NONE);
if (direction != PCI_DMA_TODEVICE) {
for_each_sg(sgl, sg, nents, n) {
- BUG_ON(page_address(sg->page) == NULL);
+ BUG_ON(page_address(sg_page(sg)) == NULL);
mmu_inval_dma_area(
- (unsigned long) page_address(sg->page),
+ (unsigned long) page_address(sg_page(sg)),
(sg->length + PAGE_SIZE-1) & PAGE_MASK);
}
}
diff --git a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
index 003f8eed32f..fe562db475e 100644
--- a/arch/sparc/kernel/ptrace.c
+++ b/arch/sparc/kernel/ptrace.c
@@ -155,7 +155,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset,
/* Rest of them are completely unsupported. */
default:
printk("%s [%d]: Wants to read user offset %ld\n",
- current->comm, current->pid, offset);
+ current->comm, task_pid_nr(current), offset);
pt_error_return(regs, EIO);
return;
}
@@ -222,7 +222,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset,
/* Rest of them are completely unsupported or "no-touch". */
default:
printk("%s [%d]: Wants to write user offset %ld\n",
- current->comm, current->pid, offset);
+ current->comm, task_pid_nr(current), offset);
goto failure;
}
success:
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 6c0221e9a9f..42bf09db9a8 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -357,7 +357,7 @@ c_sys_nis_syscall (struct pt_regs *regs)
if (count++ > 5)
return -ENOSYS;
printk ("%s[%d]: Unimplemented SPARC system call %d\n",
- current->comm, current->pid, (int)regs->u_regs[1]);
+ current->comm, task_pid_nr(current), (int)regs->u_regs[1]);
#ifdef DEBUG_UNIMP_SYSCALL
show_regs (regs);
#endif
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index f807172cab0..28c187c5d9f 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -866,7 +866,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
rcu_read_lock();
ret = -EINVAL;
if (pgrp > 0)
- ret = kill_pgrp(find_pid(pgrp), sig, 0);
+ ret = kill_pgrp(find_vpid(pgrp), sig, 0);
rcu_read_unlock();
return ret;
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 3bc3bff51e0..d404e799452 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -38,7 +38,7 @@ struct trap_trace_entry trapbuf[1024];
void syscall_trace_entry(struct pt_regs *regs)
{
- printk("%s[%d]: ", current->comm, current->pid);
+ printk("%s[%d]: ", current->comm, task_pid_nr(current));
printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1],
(int) regs->u_regs[UREG_I0]);
}
@@ -99,7 +99,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
" /_| \\__/ |_\\\n"
" \\__U_/\n");
- printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+ printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
show_regs(regs);
add_taint(TAINT_DIE);
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 375b4db6370..1666087c5b8 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
spin_lock_irqsave(&iounit->lock, flags);
while (sz != 0) {
--sz;
- sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
+ sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length);
sg->dvma_length = sg->length;
sg = sg_next(sg);
}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 283656d9f6e..4b934270f05 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -238,7 +238,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
while (sz != 0) {
--sz;
n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
- sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+ sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
sg->dvma_length = (__u32) sg->length;
sg = sg_next(sg);
}
@@ -252,7 +252,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
while (sz != 0) {
--sz;
n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
- sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+ sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
sg->dvma_length = (__u32) sg->length;
sg = sg_next(sg);
}
@@ -273,7 +273,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
* XXX Is this a good assumption?
* XXX What if someone else unmaps it here and races us?
*/
- if ((page = (unsigned long) page_address(sg->page)) != 0) {
+ if ((page = (unsigned long) page_address(sg_page(sg))) != 0) {
for (i = 0; i < n; i++) {
if (page != oldpage) { /* Already flushed? */
flush_page_for_dma(page);
@@ -283,7 +283,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
}
}
- sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
+ sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset;
sg->dvma_length = (__u32) sg->length;
sg = sg_next(sg);
}
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index ee6708fc449..a2cc141291c 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1228,7 +1228,7 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
{
while (sz != 0) {
--sz;
- sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
+ sg->dvma_address = (__u32)sun4c_lockarea(sg_virt(sg), sg->length);
sg->dvma_length = sg->length;
sg = sg_next(sg);
}
diff --git a/arch/sparc/oprofile/Kconfig b/arch/sparc/oprofile/Kconfig
deleted file mode 100644
index d8a84088471..00000000000
--- a/arch/sparc/oprofile/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 59c4d752d28..03c4e5c1b94 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -72,6 +72,10 @@ config ARCH_NO_VIRT_TO_BUS
config OF
def_bool y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ bool
+ def_bool y
+
choice
prompt "Kernel page size"
default SPARC64_PAGE_SIZE_8KB
@@ -460,20 +464,7 @@ source "drivers/fc4/Kconfig"
source "fs/Kconfig"
-menu "Instrumentation Support"
-
-source "arch/sparc64/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes (EXPERIMENTAL)"
- depends on KALLSYMS && EXPERIMENTAL && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-endmenu
+source "kernel/Kconfig.instrumentation"
source "arch/sparc64/Kconfig.debug"
diff --git a/arch/sparc64/Makefile b/arch/sparc64/Makefile
index 6c92a42efe7..01159cb5f16 100644
--- a/arch/sparc64/Makefile
+++ b/arch/sparc64/Makefile
@@ -18,8 +18,6 @@ NEW_GCC := $(call cc-option-yn, -m64 -mcmodel=medlow)
NEW_GAS := $(shell if $(LD) -V 2>&1 | grep 'elf64_sparc' > /dev/null; then echo y; else echo n; fi)
UNDECLARED_REGS := $(shell if $(CC) -c -x assembler /dev/null -Wa,--help | grep undeclared-regs > /dev/null; then echo y; else echo n; fi; )
-export NEW_GCC
-
ifneq ($(NEW_GAS),y)
AS = sparc64-linux-as
LD = sparc64-linux-ld
@@ -58,8 +56,6 @@ core-y += arch/sparc64/kernel/ arch/sparc64/mm/
core-$(CONFIG_SOLARIS_EMUL) += arch/sparc64/solaris/
core-y += arch/sparc64/math-emu/
libs-y += arch/sparc64/prom/ arch/sparc64/lib/
-
-# FIXME: is drivers- right?
drivers-$(CONFIG_OPROFILE) += arch/sparc64/oprofile/
boot := arch/sparc64/boot
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 1aa2c4048e4..e023d4b2fef 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.23
-# Sat Oct 13 21:53:54 2007
+# Sun Oct 21 19:57:44 2007
#
CONFIG_SPARC=y
CONFIG_SPARC64=y
@@ -49,6 +49,10 @@ CONFIG_POSIX_MQUEUE=y
# CONFIG_AUDIT is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
# CONFIG_BLK_DEV_INITRD is not set
@@ -145,7 +149,10 @@ CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
-CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_STATIC is not set
+CONFIG_SPARSEMEM_EXTREME=y
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
+CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
@@ -275,10 +282,6 @@ CONFIG_VLAN_8021Q=m
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
# CONFIG_NET_SCHED is not set
#
@@ -372,8 +375,6 @@ CONFIG_IDEPCI_PCIBUS_ORDER=y
# CONFIG_BLK_DEV_GENERIC is not set
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_ONLYDISK=y
# CONFIG_BLK_DEV_AEC62XX is not set
CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_WDC_ALI15X3 is not set
@@ -401,6 +402,7 @@ CONFIG_BLK_DEV_ALI15X3=y
# CONFIG_BLK_DEV_TC86C001 is not set
# CONFIG_IDE_ARM is not set
CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDE_ARCH_OBSOLETE_INIT=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -441,6 +443,7 @@ CONFIG_SCSI_FC_ATTRS=y
CONFIG_SCSI_ISCSI_ATTRS=m
# CONFIG_SCSI_SAS_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
CONFIG_ISCSI_TCP=m
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
@@ -492,14 +495,8 @@ CONFIG_DM_MIRROR=m
CONFIG_DM_ZERO=m
# CONFIG_DM_MULTIPATH is not set
# CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
+# CONFIG_DM_UEVENT is not set
# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
#
# IEEE 1394 (FireWire) support
@@ -638,7 +635,6 @@ CONFIG_INPUT_MOUSEDEV_PSAUX=y
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set
@@ -714,11 +710,9 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
# CONFIG_LEGACY_PTYS is not set
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
-# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
@@ -786,8 +780,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
@@ -795,12 +787,12 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
+# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
@@ -836,6 +828,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_WATCHDOG is not set
#
# Sonics Silicon Backplane
@@ -858,12 +851,7 @@ CONFIG_SSB_POSSIBLE=y
#
# Graphics support
#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
CONFIG_FB=y
@@ -872,6 +860,7 @@ CONFIG_FB_DDC=y
CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
# CONFIG_FB_SYS_FILLRECT is not set
# CONFIG_FB_SYS_COPYAREA is not set
# CONFIG_FB_SYS_IMAGEBLIT is not set
@@ -890,6 +879,7 @@ CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_PM2 is not set
# CONFIG_FB_ASILIANT is not set
# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_UVESA is not set
# CONFIG_FB_SBUS is not set
# CONFIG_FB_XVR500 is not set
# CONFIG_FB_XVR2500 is not set
@@ -915,6 +905,12 @@ CONFIG_FB_RADEON_I2C=y
# CONFIG_FB_ARK is not set
# CONFIG_FB_PM3 is not set
# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
#
# Console display driver support
@@ -1066,6 +1062,7 @@ CONFIG_AC97_BUS=m
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
#
# USB Input Devices
@@ -1187,19 +1184,6 @@ CONFIG_USB_STORAGE=m
# CONFIG_RTC_CLASS is not set
#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
# Userspace I/O
#
# CONFIG_UIO is not set
@@ -1275,7 +1259,6 @@ CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
# CONFIG_CONFIGFS_FS is not set
#
@@ -1295,10 +1278,7 @@ CONFIG_RAMFS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETWORK_FILESYSTEMS=y
# CONFIG_NFS_FS is not set
# CONFIG_NFSD is not set
# CONFIG_SMB_FS is not set
@@ -1313,10 +1293,6 @@ CONFIG_RAMFS=y
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_SUN_PARTITION=y
-
-#
-# Native Language Support
-#
CONFIG_NLS=m
CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
@@ -1357,18 +1333,12 @@ CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
-
-#
-# Distributed Lock Manager
-#
# CONFIG_DLM is not set
-
-#
-# Instrumentation Support
-#
+CONFIG_INSTRUMENTATION=y
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y
+# CONFIG_MARKERS is not set
#
# Kernel hacking
@@ -1402,9 +1372,11 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_LIST is not set
CONFIG_FORCED_INLINING=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_STACK_DEBUG is not set
@@ -1417,6 +1389,7 @@ CONFIG_FORCED_INLINING=y
CONFIG_KEYS=y
# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_XOR_BLOCKS=m
CONFIG_ASYNC_CORE=m
CONFIG_ASYNC_MEMCPY=m
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 112c46e6657..ef50d217432 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -39,12 +39,3 @@ else
obj-y += sys_sunos32.o sunos_ioctl32.o
endif
endif
-
-ifneq ($(NEW_GCC),y)
- CMODEL_CFLAG := -mmedlow
-else
- CMODEL_CFLAG := -m64 -mcmodel=medlow
-endif
-
-head.o: head.S ttable.S itlb_miss.S dtlb_miss.S ktlb.S tsb.S \
- etrap.S rtrap.S winfixup.S entry.S
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 29af777d7ac..070a4846c0c 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -472,8 +472,7 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr,
spin_unlock_irqrestore(&iommu->lock, flags);
}
-#define SG_ENT_PHYS_ADDRESS(SG) \
- (__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
static void fill_sg(iopte_t *iopte, struct scatterlist *sg,
int nused, int nelems,
@@ -565,9 +564,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
/* Fast path single entry scatterlists. */
if (nelems == 1) {
sglist->dma_address =
- dma_4u_map_single(dev,
- (page_address(sglist->page) +
- sglist->offset),
+ dma_4u_map_single(dev, sg_virt(sglist),
sglist->length, direction);
if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
return 0;
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c
index d7ca900ec51..78e8277df65 100644
--- a/arch/sparc64/kernel/iommu_common.c
+++ b/arch/sparc64/kernel/iommu_common.c
@@ -73,7 +73,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
daddr = dma_sg->dma_address;
sglen = sg->length;
- sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+ sgaddr = (unsigned long) sg_virt(sg);
while (dlen > 0) {
unsigned long paddr;
@@ -123,7 +123,7 @@ static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg,
sg = sg_next(sg);
if (--nents <= 0)
break;
- sgaddr = (unsigned long) (page_address(sg->page) + sg->offset);
+ sgaddr = (unsigned long) sg_virt(sg);
sglen = sg->length;
}
if (dlen < 0) {
@@ -191,7 +191,7 @@ void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int np
printk("sg(%d): page_addr(%p) off(%x) length(%x) "
"dma_address[%016x] dma_length[%016x]\n",
i,
- page_address(sg->page), sg->offset,
+ page_address(sg_page(sg)), sg->offset,
sg->length,
sg->dma_address, sg->dma_length);
}
@@ -207,15 +207,14 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
unsigned long prev;
u32 dent_addr, dent_len;
- prev = (unsigned long) (page_address(sg->page) + sg->offset);
+ prev = (unsigned long) sg_virt(sg);
prev += (unsigned long) (dent_len = sg->length);
- dent_addr = (u32) ((unsigned long)(page_address(sg->page) + sg->offset)
- & (IO_PAGE_SIZE - 1UL));
+ dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL));
while (--nents) {
unsigned long addr;
sg = sg_next(sg);
- addr = (unsigned long) (page_address(sg->page) + sg->offset);
+ addr = (unsigned long) sg_virt(sg);
if (! VCONTIG(prev, addr)) {
dma_sg->dma_address = dent_addr;
dma_sg->dma_length = dent_len;
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 2c3bea22815..30431bd24e1 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -257,8 +257,8 @@ struct irq_handler_data {
unsigned long imap;
void (*pre_handler)(unsigned int, void *, void *);
- void *pre_handler_arg1;
- void *pre_handler_arg2;
+ void *arg1;
+ void *arg2;
};
#ifdef CONFIG_SMP
@@ -346,7 +346,7 @@ static void sun4u_irq_disable(unsigned int virt_irq)
}
}
-static void sun4u_irq_end(unsigned int virt_irq)
+static void sun4u_irq_eoi(unsigned int virt_irq)
{
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
struct irq_desc *desc = irq_desc + virt_irq;
@@ -401,7 +401,7 @@ static void sun4v_irq_disable(unsigned int virt_irq)
"err(%d)\n", ino, err);
}
-static void sun4v_irq_end(unsigned int virt_irq)
+static void sun4v_irq_eoi(unsigned int virt_irq)
{
unsigned int ino = virt_irq_table[virt_irq].dev_ino;
struct irq_desc *desc = irq_desc + virt_irq;
@@ -478,7 +478,7 @@ static void sun4v_virq_disable(unsigned int virt_irq)
dev_handle, dev_ino, err);
}
-static void sun4v_virq_end(unsigned int virt_irq)
+static void sun4v_virq_eoi(unsigned int virt_irq)
{
struct irq_desc *desc = irq_desc + virt_irq;
unsigned long dev_handle, dev_ino;
@@ -498,33 +498,11 @@ static void sun4v_virq_end(unsigned int virt_irq)
dev_handle, dev_ino, err);
}
-static void run_pre_handler(unsigned int virt_irq)
-{
- struct irq_handler_data *data = get_irq_chip_data(virt_irq);
- unsigned int ino;
-
- ino = virt_irq_table[virt_irq].dev_ino;
- if (likely(data->pre_handler)) {
- data->pre_handler(ino,
- data->pre_handler_arg1,
- data->pre_handler_arg2);
- }
-}
-
static struct irq_chip sun4u_irq = {
.typename = "sun4u",
.enable = sun4u_irq_enable,
.disable = sun4u_irq_disable,
- .end = sun4u_irq_end,
- .set_affinity = sun4u_set_affinity,
-};
-
-static struct irq_chip sun4u_irq_ack = {
- .typename = "sun4u+ack",
- .enable = sun4u_irq_enable,
- .disable = sun4u_irq_disable,
- .ack = run_pre_handler,
- .end = sun4u_irq_end,
+ .eoi = sun4u_irq_eoi,
.set_affinity = sun4u_set_affinity,
};
@@ -532,7 +510,7 @@ static struct irq_chip sun4v_irq = {
.typename = "sun4v",
.enable = sun4v_irq_enable,
.disable = sun4v_irq_disable,
- .end = sun4v_irq_end,
+ .eoi = sun4v_irq_eoi,
.set_affinity = sun4v_set_affinity,
};
@@ -540,31 +518,33 @@ static struct irq_chip sun4v_virq = {
.typename = "vsun4v",
.enable = sun4v_virq_enable,
.disable = sun4v_virq_disable,
- .end = sun4v_virq_end,
+ .eoi = sun4v_virq_eoi,
.set_affinity = sun4v_virt_set_affinity,
};
+static void fastcall pre_flow_handler(unsigned int virt_irq,
+ struct irq_desc *desc)
+{
+ struct irq_handler_data *data = get_irq_chip_data(virt_irq);
+ unsigned int ino = virt_irq_table[virt_irq].dev_ino;
+
+ data->pre_handler(ino, data->arg1, data->arg2);
+
+ handle_fasteoi_irq(virt_irq, desc);
+}
+
void irq_install_pre_handler(int virt_irq,
void (*func)(unsigned int, void *, void *),
void *arg1, void *arg2)
{
struct irq_handler_data *data = get_irq_chip_data(virt_irq);
- struct irq_chip *chip = get_irq_chip(virt_irq);
-
- if (WARN_ON(chip == &sun4v_irq || chip == &sun4v_virq)) {
- printk(KERN_ERR "IRQ: Trying to install pre-handler on "
- "sun4v irq %u\n", virt_irq);
- return;
- }
+ struct irq_desc *desc = irq_desc + virt_irq;
data->pre_handler = func;
- data->pre_handler_arg1 = arg1;
- data->pre_handler_arg2 = arg2;
-
- if (chip == &sun4u_irq_ack)
- return;
+ data->arg1 = arg1;
+ data->arg2 = arg2;
- set_irq_chip(virt_irq, &sun4u_irq_ack);
+ desc->handle_irq = pre_flow_handler;
}
unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -582,7 +562,10 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
if (!virt_irq) {
virt_irq = virt_irq_alloc(0, ino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, &sun4u_irq);
+ set_irq_chip_and_handler_name(virt_irq,
+ &sun4u_irq,
+ handle_fasteoi_irq,
+ "IVEC");
}
data = get_irq_chip_data(virt_irq);
@@ -617,7 +600,9 @@ static unsigned int sun4v_build_common(unsigned long sysino,
if (!virt_irq) {
virt_irq = virt_irq_alloc(0, sysino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, chip);
+ set_irq_chip_and_handler_name(virt_irq, chip,
+ handle_fasteoi_irq,
+ "IVEC");
}
data = get_irq_chip_data(virt_irq);
@@ -665,7 +650,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
virt_irq = virt_irq_alloc(devhandle, devino);
bucket_set_virt_irq(__pa(bucket), virt_irq);
- set_irq_chip(virt_irq, &sun4v_virq);
+
+ set_irq_chip_and_handler_name(virt_irq, &sun4v_virq,
+ handle_fasteoi_irq,
+ "IVEC");
data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
if (unlikely(!data))
@@ -724,6 +712,7 @@ void handler_irq(int irq, struct pt_regs *regs)
: "memory");
while (bucket_pa) {
+ struct irq_desc *desc;
unsigned long next_pa;
unsigned int virt_irq;
@@ -731,7 +720,9 @@ void handler_irq(int irq, struct pt_regs *regs)
virt_irq = bucket_get_virt_irq(bucket_pa);
bucket_clear_chain_pa(bucket_pa);
- __do_IRQ(virt_irq);
+ desc = irq_desc + virt_irq;
+
+ desc->handle_irq(virt_irq, desc);
bucket_pa = next_pa;
}
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c
index 85a2be0b096..c8313cb60f0 100644
--- a/arch/sparc64/kernel/ldc.c
+++ b/arch/sparc64/kernel/ldc.c
@@ -2057,7 +2057,7 @@ static void fill_cookies(struct cookie_state *sp, unsigned long pa,
static int sg_count_one(struct scatterlist *sg)
{
- unsigned long base = page_to_pfn(sg->page) << PAGE_SHIFT;
+ unsigned long base = page_to_pfn(sg_page(sg)) << PAGE_SHIFT;
long len = sg->length;
if ((sg->offset | len) & (8UL - 1))
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9b808640a19..63b3ebc0c3c 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -207,8 +207,7 @@ static struct {
{ "SUNW,sun4v-pci", sun4v_pci_init },
{ "pciex108e,80f0", fire_pci_init },
};
-#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
- sizeof(pci_controller_table[0]))
+#define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table)
static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
{
diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c
index 31a165fd3e4..d6d64b44af6 100644
--- a/arch/sparc64/kernel/pci_msi.c
+++ b/arch/sparc64/kernel/pci_msi.c
@@ -28,8 +28,15 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie)
unsigned long msi;
err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
- if (likely(err > 0))
- __do_IRQ(pbm->msi_irq_table[msi - pbm->msi_first]);
+ if (likely(err > 0)) {
+ struct irq_desc *desc;
+ unsigned int virt_irq;
+
+ virt_irq = pbm->msi_irq_table[msi - pbm->msi_first];
+ desc = irq_desc + virt_irq;
+
+ desc->handle_irq(virt_irq, desc);
+ }
if (unlikely(err < 0))
goto err_dequeue;
@@ -128,7 +135,8 @@ int sparc64_setup_msi_irq(unsigned int *virt_irq_p,
if (!*virt_irq_p)
goto out_err;
- set_irq_chip(*virt_irq_p, &msi_irq);
+ set_irq_chip_and_handler_name(*virt_irq_p, &msi_irq,
+ handle_simple_irq, "MSI");
err = alloc_msi(pbm);
if (unlikely(err < 0))
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index fe46ace3e59..8c4875bdb4a 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -365,8 +365,7 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr,
spin_unlock_irqrestore(&iommu->lock, flags);
}
-#define SG_ENT_PHYS_ADDRESS(SG) \
- (__pa(page_address((SG)->page)) + (SG)->offset)
+#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
static long fill_sg(long entry, struct device *dev,
struct scatterlist *sg,
@@ -477,9 +476,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
/* Fast path single entry scatterlists. */
if (nelems == 1) {
sglist->dma_address =
- dma_4v_map_single(dev,
- (page_address(sglist->page) +
- sglist->offset),
+ dma_4v_map_single(dev, sg_virt(sglist),
sglist->length, direction);
if (unlikely(sglist->dma_address == DMA_ERROR_CODE))
return 0;
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index 8f7a06e2c7e..170d6ca8de6 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -831,7 +831,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig)
rcu_read_lock();
ret = -EINVAL;
if (pgrp > 0)
- ret = kill_pgrp(find_pid(pgrp), sig, 0);
+ ret = kill_pgrp(find_vpid(pgrp), sig, 0);
rcu_read_unlock();
return ret;
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 34573a55b6e..e9c7e4f07ab 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -2225,7 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
" /_| \\__/ |_\\\n"
" \\__U_/\n");
- printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter);
+ printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
__asm__ __volatile__("flushw");
__show_regs(regs);
diff --git a/arch/sparc64/math-emu/Makefile b/arch/sparc64/math-emu/Makefile
index a0b06fd2946..cc5cb9baf6a 100644
--- a/arch/sparc64/math-emu/Makefile
+++ b/arch/sparc64/math-emu/Makefile
@@ -4,4 +4,4 @@
obj-y := math.o
-EXTRA_CFLAGS = -I. -Iinclude/math-emu -w
+EXTRA_CFLAGS = -Iinclude/math-emu -w
diff --git a/arch/sparc64/oprofile/Kconfig b/arch/sparc64/oprofile/Kconfig
deleted file mode 100644
index d8a84088471..00000000000
--- a/arch/sparc64/oprofile/Kconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-config PROFILING
- bool "Profiling support (EXPERIMENTAL)"
- help
- Say Y here to enable the extended profiling support mechanisms used
- by profilers such as OProfile.
-
-
-config OPROFILE
- tristate "OProfile system profiling (EXPERIMENTAL)"
- depends on PROFILING
- help
- OProfile is a profiling system capable of profiling the
- whole system, include the kernel, kernel modules, libraries,
- and applications.
-
- If unsure, say N.
-
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 3b67de7455f..c86cb3091a8 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -415,7 +415,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
switch (cmd) {
case 0: /* getpgrp */
- return process_group(current);
+ return task_pgrp_nr(current);
case 1: /* setpgrp */
{
int (*sys_setpgid)(pid_t,pid_t) =
@@ -426,7 +426,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
ret = sys_setpgid(0, 0);
if (ret) return ret;
proc_clear_tty(current);
- return process_group(current);
+ return task_pgrp_nr(current);
}
case 2: /* getsid */
{
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 740d8a922e4..dd1689b814c 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -3,7 +3,7 @@ config DEFCONFIG_LIST
option defconfig_list
default "arch/$ARCH/defconfig"
-# UML uses the generic IRQ sugsystem
+# UML uses the generic IRQ subsystem
config GENERIC_HARDIRQS
bool
default y
@@ -289,4 +289,6 @@ config INPUT
bool
default n
+source "kernel/Kconfig.instrumentation"
+
source "arch/um/Kconfig.debug"
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 76fe0b0da99..83bf15a3dda 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -35,7 +35,7 @@ static void line_timer_cb(struct work_struct *work)
/*
* Returns the free space inside the ring buffer of this line.
*
- * Should be called while holding line->lock (this does not modify datas).
+ * Should be called while holding line->lock (this does not modify data).
*/
static int write_room(struct line *line)
{
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 21ad3d7932b..2b45a1446c8 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -9,7 +9,7 @@
#include "chan_user.h"
#include "os.h"
-/* This address is used only as a unique identifer */
+/* This address is used only as a unique identifier */
static int null_chan;
static void *null_init(char *str, int device, const struct chan_opts *opts)
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 4739dd527b4..d07a97f8b99 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -8,7 +8,7 @@
/* trivial console driver -- simply dump everything to stderr */
/*
- * Don't register by default -- as this registeres very early in the
+ * Don't register by default -- as this registers very early in the
* boot process it becomes the default console.
*
* Initialized at init time.
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 25b248a0250..3a8cd3dfb51 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -1115,7 +1115,7 @@ static void do_ubd_request(struct request_queue *q)
}
prepare_request(req, io_req,
(unsigned long long) req->sector << 9,
- sg->offset, sg->length, sg->page);
+ sg->offset, sg->length, sg_page(sg));
last_sectors = sg->length >> 9;
n = os_write_file(thread_fd, &io_req,
diff --git a/arch/um/kernel/gmon_syms.c b/arch/um/kernel/gmon_syms.c
index 13aa115cd1b..734f873cab1 100644
--- a/arch/um/kernel/gmon_syms.c
+++ b/arch/um/kernel/gmon_syms.c
@@ -12,8 +12,8 @@ EXPORT_SYMBOL(__bb_init_func);
* versions in libgcov.
*
* Since SuSE backported the fix, we cannot handle it depending on GCC version.
- * So, unconditinally export it. But also give it a weak declaration, which will
- * be overriden by any other one.
+ * So, unconditionally export it. But also give it a weak declaration, which will
+ * be overridden by any other one.
*/
extern void __gcov_init(void *) __attribute__((weak));
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 277fce17b08..70c2d625b07 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -326,7 +326,7 @@ int deactivate_all_fds(void)
}
/*
- * do_IRQ handles all normal device IRQ's (the special
+ * do_IRQ handles all normal device IRQs (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
*/
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index a0eba083306..47b57b497d5 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -237,7 +237,7 @@ void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
/* User-mode eip? */
info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
- /* Send us the fakey SIGTRAP */
+ /* Send us the fake SIGTRAP */
force_sig_info(SIGTRAP, &info, tsk);
}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index bd060551e61..cb3321f8e0a 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -108,7 +108,7 @@ out_nosemaphore:
* us unable to handle the page fault gracefully.
*/
out_of_memory:
- if (is_init(current)) {
+ if (is_global_init(current)) {
up_read(&mm->mmap_sem);
yield();
down_read(&mm->mmap_sem);
diff --git a/arch/um/sys-i386/bug.c b/arch/um/sys-i386/bug.c
index 200c8ba2879..a4360b5207d 100644
--- a/arch/um/sys-i386/bug.c
+++ b/arch/um/sys-i386/bug.c
@@ -6,7 +6,7 @@
#include <linux/uaccess.h>
/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
*/
int is_valid_bugaddr(unsigned long eip)
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index b02266ab5c5..fcaff86b000 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -45,7 +45,7 @@ int do_get_thread_area(struct user_desc *info)
* XXX: Consider leaving one free slot for glibc usage at first place. This must
* be done here (and by changing GDT_ENTRY_TLS_* macros) and nowhere else.
*
- * Also, this must be tested when compiling in SKAS mode with dinamic linking
+ * Also, this must be tested when compiling in SKAS mode with dynamic linking
* and running against NPTL.
*/
static int get_free_idx(struct task_struct* task)
diff --git a/arch/um/sys-x86_64/bug.c b/arch/um/sys-x86_64/bug.c
index 200c8ba2879..a4360b5207d 100644
--- a/arch/um/sys-x86_64/bug.c
+++ b/arch/um/sys-x86_64/bug.c
@@ -6,7 +6,7 @@
#include <linux/uaccess.h>
/* Mostly copied from i386/x86_86 - eliminated the eip < PAGE_OFFSET because
- * that's not relevent in skas mode.
+ * that's not relevant in skas mode.
*/
int is_valid_bugaddr(unsigned long eip)
diff --git a/arch/um/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
index ce3e07fcf28..76544403181 100644
--- a/arch/um/sys-x86_64/sysrq.c
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -15,8 +15,8 @@ void __show_regs(struct pt_regs * regs)
{
printk("\n");
print_modules();
- printk("Pid: %d, comm: %.20s %s %s\n",
- current->pid, current->comm, print_tainted(), init_utsname()->release);
+ printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
+ current->comm, print_tainted(), init_utsname()->release);
printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
PT_REGS_RIP(regs));
printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs),
diff --git a/arch/v850/Kconfig b/arch/v850/Kconfig
index ace479ab273..b6a50b8b38d 100644
--- a/arch/v850/Kconfig
+++ b/arch/v850/Kconfig
@@ -331,6 +331,8 @@ source "sound/Kconfig"
source "drivers/usb/Kconfig"
+source "kernel/Kconfig.instrumentation"
+
source "arch/v850/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/v850/kernel/me2.c b/arch/v850/kernel/me2.c
index 38be5c194f6..007115dc9ce 100644
--- a/arch/v850/kernel/me2.c
+++ b/arch/v850/kernel/me2.c
@@ -58,13 +58,13 @@ void __init me2_init_irqs (void)
void me2_uart_pre_configure (unsigned chan, unsigned cflags, unsigned baud)
{
if (chan == 0) {
- /* Specify that the relevent pins on the chip should do
+ /* Specify that the relevant pins on the chip should do
serial I/O, not direct I/O. */
ME2_PORT1_PMC |= 0xC;
/* Specify that we're using the UART, not the CSI device. */
ME2_PORT1_PFC |= 0xC;
} else if (chan == 1) {
- /* Specify that the relevent pins on the chip should do
+ /* Specify that the relevant pins on the chip should do
serial I/O, not direct I/O. */
ME2_PORT2_PMC |= 0x6;
/* Specify that we're using the UART, not the CSI device. */
diff --git a/arch/v850/kernel/rte_mb_a_pci.c b/arch/v850/kernel/rte_mb_a_pci.c
index 35a4bd5515c..7165478824e 100644
--- a/arch/v850/kernel/rte_mb_a_pci.c
+++ b/arch/v850/kernel/rte_mb_a_pci.c
@@ -179,7 +179,7 @@ static int __devinit pcibios_init (void)
default uses. */
/* Significant address bits used for decoding PCI GCS5 space
- accessess. */
+ accesses. */
MB_A_PCI_DMRR = ~(MB_A_PCI_MEM_SIZE - 1);
/* I don't understand this, but the SolutionGear example code
@@ -775,7 +775,7 @@ pci_alloc_consistent (struct pci_dev *pdev, size_t size, dma_addr_t *dma_addr)
/* Free and unmap a consistent DMA buffer. CPU_ADDR and DMA_ADDR must
be values that were returned from pci_alloc_consistent. SIZE must be
the same as what as passed into pci_alloc_consistent. References to
- the memory and mappings assosciated with CPU_ADDR or DMA_ADDR past
+ the memory and mappings associated with CPU_ADDR or DMA_ADDR past
this call are illegal. */
void
pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr,
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index f35ea223752..a0ae2e7f6ce 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -27,13 +27,22 @@
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/boot.h>
+#include <asm/asm-offsets.h>
.section ".text.head","ax",@progbits
.globl startup_32
startup_32:
- cld
- cli
+ /* check to see if KEEP_SEGMENTS flag is meaningful */
+ cmpw $0x207, BP_version(%esi)
+ jb 1f
+
+ /* test KEEP_SEGMENTS flag to see if the bootloader is asking
+ * us to not reload segments */
+ testb $(1<<6), BP_loadflags(%esi)
+ jnz 2f
+
+1: cli
movl $(__BOOT_DS),%eax
movl %eax,%ds
movl %eax,%es
@@ -41,6 +50,8 @@ startup_32:
movl %eax,%gs
movl %eax,%ss
+2: cld
+
/* Calculate the delta between where we were compiled to run
* at and where we were actually loaded at. This can only be done
* with a short local call on x86. Nothing else will tell us what
diff --git a/arch/x86/boot/compressed/misc_32.c b/arch/x86/boot/compressed/misc_32.c
index b28505c544c..b74d60d1b2f 100644
--- a/arch/x86/boot/compressed/misc_32.c
+++ b/arch/x86/boot/compressed/misc_32.c
@@ -25,7 +25,7 @@
/*
* Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
* Background information:
*
* The file layout is:
@@ -94,7 +94,7 @@
* Adding 32768 instead of 32767 just makes for round numbers.
* Adding the decompressor_size is necessary as it musht live after all
* of the data as well. Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
*
*/
@@ -247,6 +247,9 @@ static void putstr(const char *s)
int x,y,pos;
char c;
+ if (RM_SCREEN_INFO.orig_video_mode == 0 && lines == 0 && cols == 0)
+ return;
+
x = RM_SCREEN_INFO.orig_x;
y = RM_SCREEN_INFO.orig_y;
diff --git a/arch/x86/boot/compressed/misc_64.c b/arch/x86/boot/compressed/misc_64.c
index f932b0e8909..6ea015aa65e 100644
--- a/arch/x86/boot/compressed/misc_64.c
+++ b/arch/x86/boot/compressed/misc_64.c
@@ -25,7 +25,7 @@
/*
* Getting to provable safe in place decompression is hard.
- * Worst case behaviours need to be analized.
+ * Worst case behaviours need to be analyzed.
* Background information:
*
* The file layout is:
@@ -94,7 +94,7 @@
* Adding 32768 instead of 32767 just makes for round numbers.
* Adding the decompressor_size is necessary as it musht live after all
* of the data as well. Last I measured the decompressor is about 14K.
- * 10K of actuall data and 4K of bss.
+ * 10K of actual data and 4K of bss.
*
*/
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index f3140e596d4..8353c81c41c 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -119,7 +119,7 @@ _start:
# Part 2 of the header, from the old setup.S
.ascii "HdrS" # header signature
- .word 0x0206 # header version number (>= 0x0105)
+ .word 0x0207 # header version number (>= 0x0105)
# or else old loadlin-1.5 will fail)
.globl realmode_swtch
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -214,6 +214,11 @@ cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
#added with boot protocol
#version 2.06
+hardware_subarch: .long 0 # subarchitecture, added with 2.07
+ # default to 0 for normal x86 PC
+
+hardware_subarch_data: .quad 0
+
# End of setup header #####################################################
.section ".inittext", "ax"
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c
index 5027650eb27..55822d2cf05 100644
--- a/arch/x86/ia32/ia32_binfmt.c
+++ b/arch/x86/ia32/ia32_binfmt.c
@@ -5,10 +5,6 @@
* This tricks binfmt_elf.c into loading 32bit binaries using lots
* of ugly preprocessor tricks. Talk about very very poor man's inheritance.
*/
-#define __ASM_X86_64_ELF_H 1
-
-#undef ELF_CLASS
-#define ELF_CLASS ELFCLASS32
#include <linux/types.h>
#include <linux/stddef.h>
@@ -19,6 +15,7 @@
#include <linux/binfmts.h>
#include <linux/mm.h>
#include <linux/security.h>
+#include <linux/elfcore-compat.h>
#include <asm/segment.h>
#include <asm/ptrace.h>
@@ -31,6 +28,20 @@
#include <asm/ia32.h>
#include <asm/vsyscall32.h>
+#undef ELF_ARCH
+#undef ELF_CLASS
+#define ELF_CLASS ELFCLASS32
+#define ELF_ARCH EM_386
+
+#undef elfhdr
+#undef elf_phdr
+#undef elf_note
+#undef elf_addr_t
+#define elfhdr elf32_hdr
+#define elf_phdr elf32_phdr
+#define elf_note elf32_note
+#define elf_addr_t Elf32_Off
+
#define ELF_NAME "elf/i386"
#define AT_SYSINFO 32
@@ -48,74 +59,20 @@ int sysctl_vsyscall32 = 1;
} while(0)
struct file;
-struct elf_phdr;
#define IA32_EMULATOR 1
-#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
-
-#undef ELF_ARCH
-#define ELF_ARCH EM_386
-
-#define ELF_DATA ELFDATA2LSB
+#undef ELF_ET_DYN_BASE
-#define USE_ELF_CORE_DUMP 1
-
-/* Override elfcore.h */
-#define _LINUX_ELFCORE_H 1
-typedef unsigned int elf_greg_t;
-
-#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-struct elf_siginfo
-{
- int si_signo; /* signal number */
- int si_code; /* extra code */
- int si_errno; /* errno */
-};
+#define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
-struct elf_prstatus
-{
- struct elf_siginfo pr_info; /* Info associated with signal */
- short pr_cursig; /* Current signal */
- unsigned int pr_sigpend; /* Set of pending signals */
- unsigned int pr_sighold; /* Set of held signals */
- pid_t pr_pid;
- pid_t pr_ppid;
- pid_t pr_pgrp;
- pid_t pr_sid;
- struct compat_timeval pr_utime; /* User time */
- struct compat_timeval pr_stime; /* System time */
- struct compat_timeval pr_cutime; /* Cumulative user time */
- struct compat_timeval pr_cstime; /* Cumulative system time */
- elf_gregset_t pr_reg; /* GP registers */
- int pr_fpvalid; /* True if math co-processor being used. */
-};
-
-#define ELF_PRARGSZ (80) /* Number of chars for args */
-
-struct elf_prpsinfo
-{
- char pr_state; /* numeric process state */
- char pr_sname; /* char for pr_state */
- char pr_zomb; /* zombie */
- char pr_nice; /* nice val */
- unsigned int pr_flag; /* flags */
- __u16 pr_uid;
- __u16 pr_gid;
- pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
- /* Lots missing */
- char pr_fname[16]; /* filename of executable */
- char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
-};
-
#define _GET_SEG(x) \
({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; })
/* Assumes current==process to be dumped */
+#undef ELF_CORE_COPY_REGS
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
pr_reg[0] = regs->rbx; \
pr_reg[1] = regs->rcx; \
@@ -135,36 +92,41 @@ struct elf_prpsinfo
pr_reg[15] = regs->rsp; \
pr_reg[16] = regs->ss;
-#define user user32
+
+#define elf_prstatus compat_elf_prstatus
+#define elf_prpsinfo compat_elf_prpsinfo
+#define elf_fpregset_t struct user_i387_ia32_struct
+#define elf_fpxregset_t struct user32_fxsr_struct
+#define user user32
#undef elf_read_implies_exec
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)
-//#include <asm/ia32.h>
-#include <linux/elf.h>
-
-typedef struct user_i387_ia32_struct elf_fpregset_t;
-typedef struct user32_fxsr_struct elf_fpxregset_t;
-
-static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs)
+#define elf_core_copy_regs elf32_core_copy_regs
+static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs,
+ struct pt_regs *regs)
{
- ELF_CORE_COPY_REGS((*elfregs), regs)
+ ELF_CORE_COPY_REGS((&elfregs->ebx), regs)
}
-static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs)
+#define elf_core_copy_task_regs elf32_core_copy_task_regs
+static inline int elf32_core_copy_task_regs(struct task_struct *t,
+ compat_elf_gregset_t* elfregs)
{
struct pt_regs *pp = task_pt_regs(t);
- ELF_CORE_COPY_REGS((*elfregs), pp);
+ ELF_CORE_COPY_REGS((&elfregs->ebx), pp);
/* fix wrong segments */
- (*elfregs)[7] = t->thread.ds;
- (*elfregs)[9] = t->thread.fsindex;
- (*elfregs)[10] = t->thread.gsindex;
- (*elfregs)[8] = t->thread.es;
+ elfregs->ds = t->thread.ds;
+ elfregs->fs = t->thread.fsindex;
+ elfregs->gs = t->thread.gsindex;
+ elfregs->es = t->thread.es;
return 1;
}
+#define elf_core_copy_task_fpregs elf32_core_copy_task_fpregs
static inline int
-elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu)
+elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs,
+ elf_fpregset_t *fpu)
{
struct _fpstate_ia32 *fpstate = (void*)fpu;
mm_segment_t oldfs = get_fs();
@@ -186,8 +148,9 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr
#define ELF_CORE_COPY_XFPREGS 1
#define ELF_CORE_XFPREG_TYPE NT_PRXFPREG
+#define elf_core_copy_task_xfpregs elf32_core_copy_task_xfpregs
static inline int
-elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
+elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
{
struct pt_regs *regs = task_pt_regs(t);
if (!tsk_used_math(t))
@@ -206,6 +169,10 @@ elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu)
extern int force_personality32;
+#undef ELF_EXEC_PAGESIZE
+#undef ELF_HWCAP
+#undef ELF_PLATFORM
+#undef SET_PERSONALITY
#define ELF_EXEC_PAGESIZE PAGE_SIZE
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
#define ELF_PLATFORM ("i686")
@@ -231,6 +198,7 @@ do { \
#define load_elf_binary load_elf32_binary
+#undef ELF_PLAT_INIT
#define ELF_PLAT_INIT(r, load_addr) elf32_init(r)
#undef start_thread
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index a3fa11f8f46..ccea590bbb9 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-extra-y := head_32.o init_task_32.o vmlinux.lds
+extra-y := head_32.o init_task.o vmlinux.lds
obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
@@ -17,6 +17,7 @@ obj-$(CONFIG_MCA) += mca_32.o
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
+obj-$(CONFIG_PCI) += early-quirks.o
obj-$(CONFIG_APM) += apm_32.o
obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
obj-$(CONFIG_SMP) += smpcommon_32.o
diff --git a/arch/x86/kernel/Makefile_64 b/arch/x86/kernel/Makefile_64
index 43da66213a4..dec06e76928 100644
--- a/arch/x86/kernel/Makefile_64
+++ b/arch/x86/kernel/Makefile_64
@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
-extra-y := head_64.o head64.o init_task_64.o vmlinux.lds
+extra-y := head_64.o head64.o init_task.o vmlinux.lds
EXTRA_AFLAGS := -traditional
obj-y := process_64.o signal_64.o entry_64.o traps_64.o irq_64.o \
ptrace_64.o time_64.o ioport_64.o ldt_64.o setup_64.o i8259_64.o sys_x86_64.o \
@@ -39,7 +39,7 @@ obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_AUDIT) += audit_64.o
obj-$(CONFIG_MODULES) += module_64.o
-obj-$(CONFIG_PCI) += early-quirks_64.o
+obj-$(CONFIG_PCI) += early-quirks.o
obj-y += topology.o
obj-y += intel_cacheinfo.o
diff --git a/arch/x86/kernel/acpi/Makefile_32 b/arch/x86/kernel/acpi/Makefile_32
index a4852a2e919..045dd54b33e 100644
--- a/arch/x86/kernel/acpi/Makefile_32
+++ b/arch/x86/kernel/acpi/Makefile_32
@@ -1,7 +1,4 @@
obj-$(CONFIG_ACPI) += boot.o
-ifneq ($(CONFIG_PCI),)
-obj-$(CONFIG_X86_IO_APIC) += earlyquirk_32.o
-endif
obj-$(CONFIG_ACPI_SLEEP) += sleep_32.o wakeup_32.o
ifneq ($(CONFIG_ACPI_PROCESSOR),)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index afd2afe9102..289247d974c 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -99,7 +99,7 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
/*
* The default interrupt routing model is PIC (8259). This gets
- * overriden if IOAPICs are enumerated (below).
+ * overridden if IOAPICs are enumerated (below).
*/
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
@@ -414,8 +414,8 @@ acpi_parse_nmi_src(struct acpi_subtable_header * header, const unsigned long end
*
* Port 0x4d0-4d1 are ECLR1 and ECLR2, the Edge/Level Control Registers
* for the 8259 PIC. bit[n] = 1 means irq[n] is Level, otherwise Edge.
- * ECLR1 is IRQ's 0-7 (IRQ 0, 1, 2 must be 0)
- * ECLR2 is IRQ's 8-15 (IRQ 8, 13 must be 0)
+ * ECLR1 is IRQs 0-7 (IRQ 0, 1, 2 must be 0)
+ * ECLR2 is IRQs 8-15 (IRQ 8, 13 must be 0)
*/
void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
@@ -427,7 +427,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
old = inb(0x4d0) | (inb(0x4d1) << 8);
/*
- * If we use ACPI to set PCI irq's, then we should clear ELCR
+ * If we use ACPI to set PCI IRQs, then we should clear ELCR
* since we will set it correctly as we enable the PCI irq
* routing.
*/
@@ -555,7 +555,7 @@ EXPORT_SYMBOL(acpi_map_lsapic);
int acpi_unmap_lsapic(int cpu)
{
- x86_cpu_to_apicid[cpu] = -1;
+ per_cpu(x86_cpu_to_apicid, cpu) = -1;
cpu_clear(cpu, cpu_present_map);
num_processors--;
diff --git a/arch/x86/kernel/acpi/cstate.c b/arch/x86/kernel/acpi/cstate.c
index 2d39f55d29a..10b67170b13 100644
--- a/arch/x86/kernel/acpi/cstate.c
+++ b/arch/x86/kernel/acpi/cstate.c
@@ -29,7 +29,7 @@
void acpi_processor_power_init_bm_check(struct acpi_processor_flags *flags,
unsigned int cpu)
{
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
flags->bm_check = 0;
if (num_online_cpus() == 1)
@@ -72,7 +72,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
struct acpi_processor_cx *cx, struct acpi_power_register *reg)
{
struct cstate_entry *percpu_entry;
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
cpumask_t saved_mask;
int retval;
diff --git a/arch/x86/kernel/acpi/earlyquirk_32.c b/arch/x86/kernel/acpi/earlyquirk_32.c
deleted file mode 100644
index 23f78efc577..00000000000
--- a/arch/x86/kernel/acpi/earlyquirk_32.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Do early PCI probing for bug detection when the main PCI subsystem is
- * not up yet.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/acpi.h>
-
-#include <asm/pci-direct.h>
-#include <asm/acpi.h>
-#include <asm/apic.h>
-
-#ifdef CONFIG_ACPI
-
-static int __init nvidia_hpet_check(struct acpi_table_header *header)
-{
- return 0;
-}
-#endif
-
-static int __init check_bridge(int vendor, int device)
-{
-#ifdef CONFIG_ACPI
- static int warned;
- /* According to Nvidia all timer overrides are bogus unless HPET
- is enabled. */
- if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) {
- if (!warned && acpi_table_parse(ACPI_SIG_HPET,
- nvidia_hpet_check)) {
- warned = 1;
- acpi_skip_timer_override = 1;
- printk(KERN_INFO "Nvidia board "
- "detected. Ignoring ACPI "
- "timer override.\n");
- printk(KERN_INFO "If you got timer trouble "
- "try acpi_use_timer_override\n");
-
- }
- }
-#endif
- if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) {
- timer_over_8254 = 0;
- printk(KERN_INFO "ATI board detected. Disabling timer routing "
- "over 8254.\n");
- }
- return 0;
-}
-
-void __init check_acpi_pci(void)
-{
- int num, slot, func;
-
- /* Assume the machine supports type 1. If not it will
- always read ffffffff and should not have any side effect.
- Actually a few buggy systems can machine check. Allow the user
- to disable it by command line option at least -AK */
- if (!early_pci_allowed())
- return;
-
- /* Poor man's PCI discovery */
- for (num = 0; num < 32; num++) {
- for (slot = 0; slot < 32; slot++) {
- for (func = 0; func < 8; func++) {
- u32 class;
- u32 vendor;
- class = read_pci_config(num, slot, func,
- PCI_CLASS_REVISION);
- if (class == 0xffffffff)
- break;
-
- if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
- continue;
-
- vendor = read_pci_config(num, slot, func,
- PCI_VENDOR_ID);
-
- if (check_bridge(vendor & 0xffff, vendor >> 16))
- return;
- }
-
- }
- }
-}
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c
index b54fded4983..2ed0a4ce62f 100644
--- a/arch/x86/kernel/acpi/processor.c
+++ b/arch/x86/kernel/acpi/processor.c
@@ -63,7 +63,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
{
unsigned int cpu = pr->id;
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
pr->pdc = NULL;
if (c->x86_vendor == X86_VENDOR_INTEL)
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 3bd2688bd44..d6405e0842b 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -357,14 +357,14 @@ void alternatives_smp_switch(int smp)
if (smp) {
printk(KERN_INFO "SMP alternatives: switching to SMP code\n");
clear_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- clear_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ clear_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
list_for_each_entry(mod, &smp_alt_modules, next)
alternatives_smp_lock(mod->locks, mod->locks_end,
mod->text, mod->text_end);
} else {
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
list_for_each_entry(mod, &smp_alt_modules, next)
alternatives_smp_unlock(mod->locks, mod->locks_end,
mod->text, mod->text_end);
@@ -432,7 +432,7 @@ void __init alternative_instructions(void)
if (1 == num_possible_cpus()) {
printk(KERN_INFO "SMP alternatives: switching to UP code\n");
set_bit(X86_FEATURE_UP, boot_cpu_data.x86_capability);
- set_bit(X86_FEATURE_UP, cpu_data[0].x86_capability);
+ set_bit(X86_FEATURE_UP, cpu_data(0).x86_capability);
alternatives_smp_unlock(__smp_locks, __smp_locks_end,
_text, _etext);
}
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 793341fffc8..08b07c17696 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -947,7 +947,7 @@ void __devinit setup_local_APIC(void)
* Set up LVT0, LVT1:
*
* set up through-local-APIC on the BP's LINT0. This is not
- * strictly necessery in pure symmetric-IO mode, but sometimes
+ * strictly necessary in pure symmetric-IO mode, but sometimes
* we delegate interrupts to the 8259A.
*/
/*
@@ -998,7 +998,7 @@ void __devinit setup_local_APIC(void)
} else {
if (esr_disable)
/*
- * Something untraceble is creating bad interrupts on
+ * Something untraceable is creating bad interrupts on
* secondary quads ... for the moment, just leave the
* ESR disabled - we can't do anything useful with the
* errors anyway - mbligh
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index 32f2365c26e..17089a04102 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -57,7 +57,7 @@
* screen-blanking and gpm (Stephen Rothwell); Linux 1.99.4
* 1.2a:Simple change to stop mysterious bug reports with SMP also added
* levels to the printk calls. APM is not defined for SMP machines.
- * The new replacment for it is, but Linux doesn't yet support this.
+ * The new replacement for it is, but Linux doesn't yet support this.
* Alan Cox Linux 2.1.55
* 1.3: Set up a valid data descriptor 0x40 for buggy BIOS's
* 1.4: Upgraded to support APM 1.2. Integrated ThinkPad suspend patch by
diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index f1b7cdda82b..f8764716b0c 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -15,6 +15,7 @@
#include <asm/fixmap.h>
#include <asm/processor.h>
#include <asm/thread_info.h>
+#include <asm/bootparam.h>
#include <asm/elf.h>
#include <xen/interface/xen.h>
@@ -146,4 +147,10 @@ void foo(void)
OFFSET(LGUEST_PAGES_regs_errcode, lguest_pages, regs.errcode);
OFFSET(LGUEST_PAGES_regs, lguest_pages, regs);
#endif
+
+ BLANK();
+ OFFSET(BP_scratch, boot_params, scratch);
+ OFFSET(BP_loadflags, boot_params, hdr.loadflags);
+ OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
+ OFFSET(BP_version, boot_params, hdr.version);
}
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 5f8af875f45..1ff88c7f45c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -266,7 +266,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c)
#ifdef CONFIG_X86_HT
/*
* On a AMD multi core setup the lower bits of the APIC id
- * distingush the cores.
+ * distinguish the cores.
*/
if (c->x86_max_cores > 1) {
int cpu = smp_processor_id();
diff --git a/arch/x86/kernel/cpu/centaur.c b/arch/x86/kernel/cpu/centaur.c
index 473eac883c7..9681fa15ddf 100644
--- a/arch/x86/kernel/cpu/centaur.c
+++ b/arch/x86/kernel/cpu/centaur.c
@@ -53,7 +53,7 @@ static u32 __cpuinit ramtop(void) /* 16388 */
continue;
/*
* Don't MCR over reserved space. Ignore the ISA hole
- * we frob around that catastrophy already
+ * we frob around that catastrophe already
*/
if (e820.map[i].type == E820_RESERVED)
@@ -287,7 +287,7 @@ static void __cpuinit init_c3(struct cpuinfo_x86 *c)
c->x86_capability[5] = cpuid_edx(0xC0000001);
}
- /* Cyrix III family needs CX8 & PGE explicity enabled. */
+ /* Cyrix III family needs CX8 & PGE explicitly enabled. */
if (c->x86_model >=6 && c->x86_model <= 9) {
rdmsr (MSR_VIA_FCR, lo, hi);
lo |= (1<<1 | 1<<7);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d506201d397..e2fcf2051bd 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -207,7 +207,7 @@ static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early)
static int __init x86_fxsr_setup(char * s)
{
- /* Tell all the other CPU's to not use it... */
+ /* Tell all the other CPUs to not use it... */
disable_x86_fxsr = 1;
/*
diff --git a/arch/x86/kernel/cpu/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig_32
index d8c6f132dc7..d8c6f132dc7 100644
--- a/arch/x86/kernel/cpu/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig_32
diff --git a/arch/x86/kernel/cpufreq/Kconfig b/arch/x86/kernel/cpu/cpufreq/Kconfig_64
index a3fd51926cb..9c9699fdcf5 100644
--- a/arch/x86/kernel/cpufreq/Kconfig
+++ b/arch/x86/kernel/cpu/cpufreq/Kconfig_64
@@ -19,7 +19,7 @@ config X86_POWERNOW_K8
To compile this driver as a module, choose M here: the
module will be called powernow-k8.
- For details, take a look at <file:Documentation/cpu-freq/>.
+ For details, take a look at <file:Documentation/cpu-freq/>.
If in doubt, say N.
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 2ca43ba32bc..fea0af0476b 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -77,7 +77,7 @@ static unsigned int acpi_pstate_strict;
static int check_est_cpu(unsigned int cpuid)
{
- struct cpuinfo_x86 *cpu = &cpu_data[cpuid];
+ struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
if (cpu->x86_vendor != X86_VENDOR_INTEL ||
!cpu_has(cpu, X86_FEATURE_EST))
@@ -560,7 +560,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
unsigned int cpu = policy->cpu;
struct acpi_cpufreq_data *data;
unsigned int result = 0;
- struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+ struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
struct acpi_processor_performance *perf;
dprintk("acpi_cpufreq_cpu_init\n");
diff --git a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
index 32f0bda3fc9..f03e9153618 100644
--- a/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -260,7 +260,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
freqs.old = nforce2_get(policy->cpu);
freqs.new = target_fsb * fid * 100;
- freqs.cpu = 0; /* Only one CPU on nForce2 plattforms */
+ freqs.cpu = 0; /* Only one CPU on nForce2 platforms */
if (freqs.old == freqs.new)
return 0;
diff --git a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
index c11baaf9f2b..326a4c81f68 100644
--- a/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
+++ b/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
@@ -305,7 +305,7 @@ static struct cpufreq_driver eps_driver = {
static int __init eps_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
/* This driver will work only on Centaur C7 processors with
* Enhanced SpeedStep/PowerSaver registers */
diff --git a/arch/x86/kernel/cpu/cpufreq/elanfreq.c b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
index 1e7ae7dafcf..94619c22f56 100644
--- a/arch/x86/kernel/cpu/cpufreq/elanfreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/elanfreq.c
@@ -199,7 +199,7 @@ static int elanfreq_target (struct cpufreq_policy *policy,
static int elanfreq_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
unsigned int i;
int result;
@@ -280,7 +280,7 @@ static struct cpufreq_driver elanfreq_driver = {
static int __init elanfreq_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
/* Test if we have the right hardware */
if ((c->x86_vendor != X86_VENDOR_AMD) ||
diff --git a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
index ed2bda127c4..2ed7db2fd25 100644
--- a/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
@@ -12,12 +12,12 @@
* of any nature resulting due to the use of this software. This
* software is provided AS-IS with no warranties.
*
- * Theoritical note:
+ * Theoretical note:
*
* (see Geode(tm) CS5530 manual (rev.4.1) page.56)
*
* CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
- * are based on Suspend Moduration.
+ * are based on Suspend Modulation.
*
* Suspend Modulation works by asserting and de-asserting the SUSP# pin
* to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
@@ -101,11 +101,11 @@
/* SUSCFG bits */
#define SUSMOD (1<<0) /* enable/disable suspend modulation */
-/* the belows support only with cs5530 (after rev.1.2)/cs5530A */
+/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */
#define SMISPDUP (1<<1) /* select how SMI re-enable suspend modulation: */
/* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
#define SUSCFG (1<<2) /* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
-/* the belows support only with cs5530A */
+/* the below is supported only with cs5530A */
#define PWRSVE_ISA (1<<3) /* stop ISA clock */
#define PWRSVE (1<<4) /* active idle */
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 5045f5d583c..749d00cb2eb 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -780,7 +780,7 @@ static int longhaul_setup_southbridge(void)
static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
char *cpuname=NULL;
int ret;
u32 lo, hi;
@@ -959,7 +959,7 @@ static struct cpufreq_driver longhaul_driver = {
static int __init longhaul_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
return -ENODEV;
diff --git a/arch/x86/kernel/cpu/cpufreq/longrun.c b/arch/x86/kernel/cpu/cpufreq/longrun.c
index b2689514295..af4a867a097 100644
--- a/arch/x86/kernel/cpu/cpufreq/longrun.c
+++ b/arch/x86/kernel/cpu/cpufreq/longrun.c
@@ -172,7 +172,7 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
u32 save_lo, save_hi;
u32 eax, ebx, ecx, edx;
u32 try_hi;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
if (!low_freq || !high_freq)
return -EINVAL;
@@ -298,7 +298,7 @@ static struct cpufreq_driver longrun_driver = {
*/
static int __init longrun_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
!cpu_has(c, X86_FEATURE_LONGRUN))
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 793eae854f4..14791ec55cf 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -195,7 +195,7 @@ static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = &cpu_data[policy->cpu];
+ struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
int cpuid = 0;
unsigned int i;
@@ -279,7 +279,7 @@ static struct cpufreq_driver p4clockmod_driver = {
static int __init cpufreq_p4_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
int ret;
/*
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index 6d028533931..eb9b62b0830 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -1,6 +1,6 @@
/*
* This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pnkl, Dominik Brodowski.
+ * (C) 2000-2003 Dave Jones, Arjan van de Ven, Janne Pänkälä, Dominik Brodowski.
*
* Licensed under the terms of the GNU GPL License version 2.
*
@@ -215,7 +215,7 @@ static struct cpufreq_driver powernow_k6_driver = {
*/
static int __init powernow_k6_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
((c->x86_model != 12) && (c->x86_model != 13)))
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index f3686a5f230..b5a9863d6cd 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -114,7 +114,7 @@ static int check_fsb(unsigned int fsbspeed)
static int check_powernow(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
unsigned int maxei, eax, ebx, ecx, edx;
if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 !=6)) {
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index c06ac680c9c..9c36a53676b 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -168,7 +168,7 @@ static void count_off_irt(struct powernow_k8_data *data)
return;
}
-/* the voltage stabalization time */
+/* the voltage stabilization time */
static void count_off_vst(struct powernow_k8_data *data)
{
udelay(data->vstable * VST_UNITS_20US);
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
index b06c812208c..7c4f6e0faed 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
@@ -148,10 +148,10 @@ struct powernow_k8_data {
#define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
#define MAXIMUM_VID_STEPS 1 /* Current cpus only allow a single step of 25mV */
-#define VST_UNITS_20US 20 /* Voltage Stabalization Time is in units of 20us */
+#define VST_UNITS_20US 20 /* Voltage Stabilization Time is in units of 20us */
/*
- * Most values of interest are enocoded in a single field of the _PSS
+ * Most values of interest are encoded in a single field of the _PSS
* entries: the "control" value.
*/
diff --git a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
index d9f3e90a7ae..42da9bd677d 100644
--- a/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
+++ b/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
@@ -102,7 +102,7 @@ static int sc520_freq_target (struct cpufreq_policy *policy,
static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
int result;
/* capability check */
@@ -151,7 +151,7 @@ static struct cpufreq_driver sc520_freq_driver = {
static int __init sc520_freq_init(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
int err;
/* Test if we have the right hardware */
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
index 811d4743854..3031f119619 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -230,7 +230,7 @@ static struct cpu_model models[] =
static int centrino_cpu_init_table(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+ struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
struct cpu_model *model;
for(model = models; model->cpu_id != NULL; model++)
@@ -340,7 +340,7 @@ static unsigned int get_cur_freq(unsigned int cpu)
static int centrino_cpu_init(struct cpufreq_policy *policy)
{
- struct cpuinfo_x86 *cpu = &cpu_data[policy->cpu];
+ struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
unsigned freq;
unsigned l, h;
int ret;
@@ -612,7 +612,7 @@ static struct cpufreq_driver centrino_driver = {
*/
static int __init centrino_init(void)
{
- struct cpuinfo_x86 *cpu = cpu_data;
+ struct cpuinfo_x86 *cpu = &cpu_data(0);
if (!cpu_has(cpu, X86_FEATURE_EST))
return -ENODEV;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
index b1acc8ce316..76c3ab0da46 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
@@ -228,7 +228,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_processor_frequency);
unsigned int speedstep_detect_processor (void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
u32 ebx, msr_lo, msr_hi;
dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c
index 122d2d75aa9..88d66fb8411 100644
--- a/arch/x86/kernel/cpu/cyrix.c
+++ b/arch/x86/kernel/cpu/cyrix.c
@@ -93,7 +93,7 @@ static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c)
local_irq_save(flags);
ccr3 = getCx86(CX86_CCR3);
- setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
ccr5 = getCx86(CX86_CCR5);
if (ccr5 & 2)
setCx86(CX86_CCR5, ccr5 & 0xfd); /* reset SLOP */
@@ -115,9 +115,9 @@ static void __cpuinit set_cx86_reorder(void)
printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n");
ccr3 = getCx86(CX86_CCR3);
- setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
- /* Load/Store Serialize to mem access disable (=reorder it) */
+ /* Load/Store Serialize to mem access disable (=reorder it) */
setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80);
/* set load/store serialize from 1GB to 4GB */
ccr3 |= 0xe0;
@@ -146,7 +146,7 @@ static void __cpuinit set_cx86_inc(void)
printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n");
ccr3 = getCx86(CX86_CCR3);
- setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
+ setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */
/* PCR1 -- Performance Control */
/* Incrementor on, whatever that is */
setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02);
@@ -256,7 +256,7 @@ static void __cpuinit init_cyrix(struct cpuinfo_x86 *c)
u32 vendor, device;
/* It isn't really a PCI quirk directly, but the cure is the
same. The MediaGX has deep magic SMM stuff that handles the
- SB emulation. It thows away the fifo on disable_dma() which
+ SB emulation. It throws away the fifo on disable_dma() which
is wrong and ruins the audio.
Bug2: VSA1 has a wrap bug so that using maximum sized DMA
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 297a2411694..9921b01fe19 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -295,7 +295,7 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */
unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
#ifdef CONFIG_X86_HT
- unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data);
+ unsigned int cpu = c->cpu_index;
#endif
if (c->cpuid_level > 3) {
@@ -417,14 +417,14 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
if (new_l2) {
l2 = new_l2;
#ifdef CONFIG_X86_HT
- cpu_llc_id[cpu] = l2_id;
+ per_cpu(cpu_llc_id, cpu) = l2_id;
#endif
}
if (new_l3) {
l3 = new_l3;
#ifdef CONFIG_X86_HT
- cpu_llc_id[cpu] = l3_id;
+ per_cpu(cpu_llc_id, cpu) = l3_id;
#endif
}
@@ -459,7 +459,7 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
struct _cpuid4_info *this_leaf, *sibling_leaf;
unsigned long num_threads_sharing;
int index_msb, i;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
this_leaf = CPUID4_INFO_IDX(cpu, index);
num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
@@ -470,8 +470,8 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
index_msb = get_count_order(num_threads_sharing);
for_each_online_cpu(i) {
- if (c[i].apicid >> index_msb ==
- c[cpu].apicid >> index_msb) {
+ if (cpu_data(i).apicid >> index_msb ==
+ c->apicid >> index_msb) {
cpu_set(i, this_leaf->shared_cpu_map);
if (i != cpu && cpuid4_info[i]) {
sibling_leaf = CPUID4_INFO_IDX(i, index);
diff --git a/arch/x86/kernel/cpu/mtrr/cyrix.c b/arch/x86/kernel/cpu/mtrr/cyrix.c
index 2287d4863a8..9964be3de2b 100644
--- a/arch/x86/kernel/cpu/mtrr/cyrix.c
+++ b/arch/x86/kernel/cpu/mtrr/cyrix.c
@@ -147,10 +147,10 @@ static void prepare_set(void)
write_cr0(cr0);
wbinvd();
- /* Cyrix ARRs - everything else were excluded at the top */
+ /* Cyrix ARRs - everything else was excluded at the top */
ccr3 = getCx86(CX86_CCR3);
- /* Cyrix ARRs - everything else were excluded at the top */
+ /* Cyrix ARRs - everything else was excluded at the top */
setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10);
}
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 56f64e34829..992f08dfbb6 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -182,7 +182,7 @@ static inline void k8_enable_fixed_iorrs(void)
/**
* Checks and updates an fixed-range MTRR if it differs from the value it
- * should have. If K8 extenstions are wanted, update the K8 SYSCFG MSR also.
+ * should have. If K8 extentions are wanted, update the K8 SYSCFG MSR also.
* see AMD publication no. 24593, chapter 7.8.1, page 233 for more information
* \param msr MSR address of the MTTR which should be checked and updated
* \param changed pointer which indicates whether the MTRR needed to be changed
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 5e4be30ff90..9abbdf7562c 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -748,7 +748,7 @@ static int __init mtrr_init_finialize(void)
if (use_intel())
mtrr_state_warn();
else {
- /* The CPUs haven't MTRR and seemes not support SMP. They have
+ /* The CPUs haven't MTRR and seem to not support SMP. They have
* specific drivers, we use a tricky method to support
* suspend/resume for them.
* TBD: is there any system with such CPU which supports
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 54cdbf1a40f..c02541e6e65 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -120,7 +120,9 @@ int reserve_perfctr_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_perfctr_msr_to_bit(msr);
- BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+ /* register not managed by the allocator? */
+ if (counter > NMI_MAX_COUNTER_BITS)
+ return 1;
if (!test_and_set_bit(counter, perfctr_nmi_owner))
return 1;
@@ -132,7 +134,9 @@ void release_perfctr_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_perfctr_msr_to_bit(msr);
- BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+ /* register not managed by the allocator? */
+ if (counter > NMI_MAX_COUNTER_BITS)
+ return;
clear_bit(counter, perfctr_nmi_owner);
}
@@ -142,7 +146,9 @@ int reserve_evntsel_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_evntsel_msr_to_bit(msr);
- BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+ /* register not managed by the allocator? */
+ if (counter > NMI_MAX_COUNTER_BITS)
+ return 1;
if (!test_and_set_bit(counter, evntsel_nmi_owner))
return 1;
@@ -154,7 +160,9 @@ void release_evntsel_nmi(unsigned int msr)
unsigned int counter;
counter = nmi_evntsel_msr_to_bit(msr);
- BUG_ON(counter > NMI_MAX_COUNTER_BITS);
+ /* register not managed by the allocator? */
+ if (counter > NMI_MAX_COUNTER_BITS)
+ return;
clear_bit(counter, evntsel_nmi_owner);
}
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 879a0f789b1..2d42b414b77 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -85,12 +85,13 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/* nothing */
};
struct cpuinfo_x86 *c = v;
- int i, n = c - cpu_data;
+ int i, n = 0;
int fpu_exception;
#ifdef CONFIG_SMP
if (!cpu_online(n))
return 0;
+ n = c->cpu_index;
#endif
seq_printf(m, "processor\t: %d\n"
"vendor_id\t: %s\n"
@@ -175,11 +176,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+ if (*pos == 0) /* just in case, cpu 0 is not the first */
+ *pos = first_cpu(cpu_possible_map);
+ if ((*pos) < NR_CPUS && cpu_possible(*pos))
+ return &cpu_data(*pos);
+ return NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
- ++*pos;
+ *pos = next_cpu(*pos, cpu_possible_map);
return c_start(m, pos);
}
static void c_stop(struct seq_file *m, void *v)
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 70dcf912d9f..05c9936a16c 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -114,7 +114,7 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,
static int cpuid_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
- struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */
@@ -134,15 +134,18 @@ static const struct file_operations cpuid_fops = {
.open = cpuid_open,
};
-static int __cpuinit cpuid_device_create(int i)
+static __cpuinit int cpuid_device_create(int cpu)
{
- int err = 0;
struct device *dev;
- dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), "cpu%d",i);
- if (IS_ERR(dev))
- err = PTR_ERR(dev);
- return err;
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
+ "cpu%d", cpu);
+ return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+
+static void cpuid_device_destroy(int cpu)
+{
+ device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
}
static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
@@ -150,18 +153,21 @@ static int __cpuinit cpuid_class_cpu_callback(struct notifier_block *nfb,
void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
+ int err = 0;
switch (action) {
- case CPU_ONLINE:
- case CPU_ONLINE_FROZEN:
- cpuid_device_create(cpu);
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ err = cpuid_device_create(cpu);
break;
+ case CPU_UP_CANCELED:
+ case CPU_UP_CANCELED_FROZEN:
case CPU_DEAD:
case CPU_DEAD_FROZEN:
- device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+ cpuid_device_destroy(cpu);
break;
}
- return NOTIFY_OK;
+ return err ? NOTIFY_BAD : NOTIFY_OK;
}
static struct notifier_block __cpuinitdata cpuid_class_cpu_notifier =
@@ -198,7 +204,7 @@ static int __init cpuid_init(void)
out_class:
i = 0;
for_each_online_cpu(i) {
- device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, i));
+ cpuid_device_destroy(i);
}
class_destroy(cpuid_class);
out_chrdev:
@@ -212,7 +218,7 @@ static void __exit cpuid_exit(void)
int cpu = 0;
for_each_online_cpu(cpu)
- device_destroy(cpuid_class, MKDEV(CPUID_MAJOR, cpu));
+ cpuid_device_destroy(cpu);
class_destroy(cpuid_class);
unregister_chrdev(CPUID_MAJOR, "cpu/cpuid");
unregister_hotcpu_notifier(&cpuid_class_cpu_notifier);
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 32e75d0731a..72d0c56c1b4 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -47,6 +47,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!kdump_buf_page) {
printk(KERN_WARNING "Kdump: Kdump buffer page not"
" allocated\n");
+ kunmap_atomic(vaddr, KM_PTE0);
return -EFAULT;
}
copy_page(kdump_buf_page, vaddr);
diff --git a/arch/x86/kernel/e820_32.c b/arch/x86/kernel/e820_32.c
index 3c86b979a40..18f500d185a 100644
--- a/arch/x86/kernel/e820_32.c
+++ b/arch/x86/kernel/e820_32.c
@@ -51,6 +51,13 @@ struct resource code_resource = {
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
};
+struct resource bss_resource = {
+ .name = "Kernel bss",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
static struct resource system_rom_resource = {
.name = "System ROM",
.start = 0xf0000,
@@ -254,7 +261,9 @@ static void __init probe_roms(void)
* and also for regions reported as reserved by the e820.
*/
static void __init
-legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource)
+legacy_init_iomem_resources(struct resource *code_resource,
+ struct resource *data_resource,
+ struct resource *bss_resource)
{
int i;
@@ -287,8 +296,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
*/
request_resource(res, code_resource);
request_resource(res, data_resource);
+ request_resource(res, bss_resource);
#ifdef CONFIG_KEXEC
- request_resource(res, &crashk_res);
+ if (crashk_res.start != crashk_res.end)
+ request_resource(res, &crashk_res);
#endif
}
}
@@ -306,9 +317,11 @@ static int __init request_standard_resources(void)
printk("Setting up standard PCI resources\n");
if (efi_enabled)
- efi_initialize_iomem_resources(&code_resource, &data_resource);
+ efi_initialize_iomem_resources(&code_resource,
+ &data_resource, &bss_resource);
else
- legacy_init_iomem_resources(&code_resource, &data_resource);
+ legacy_init_iomem_resources(&code_resource,
+ &data_resource, &bss_resource);
/* EFI systems may still have VGA */
request_resource(&iomem_resource, &video_ram_resource);
@@ -705,7 +718,7 @@ void __init e820_register_memory(void)
int i;
/*
- * Search for the bigest gap in the low 32 bits of the e820
+ * Search for the biggest gap in the low 32 bits of the e820
* memory space.
*/
last = 0x100000000ull;
diff --git a/arch/x86/kernel/e820_64.c b/arch/x86/kernel/e820_64.c
index e422b8159f6..04698e0b056 100644
--- a/arch/x86/kernel/e820_64.c
+++ b/arch/x86/kernel/e820_64.c
@@ -47,7 +47,7 @@ unsigned long end_pfn_map;
*/
static unsigned long __initdata end_user_pfn = MAXMEM>>PAGE_SHIFT;
-extern struct resource code_resource, data_resource;
+extern struct resource code_resource, data_resource, bss_resource;
/* Check for some hardcoded bad areas that early boot is not allowed to touch */
static inline int bad_addr(unsigned long *addrp, unsigned long size)
@@ -225,8 +225,10 @@ void __init e820_reserve_resources(void)
*/
request_resource(res, &code_resource);
request_resource(res, &data_resource);
+ request_resource(res, &bss_resource);
#ifdef CONFIG_KEXEC
- request_resource(res, &crashk_res);
+ if (crashk_res.start != crashk_res.end)
+ request_resource(res, &crashk_res);
#endif
}
}
@@ -728,3 +730,22 @@ __init void e820_setup_gap(void)
printk(KERN_INFO "Allocating PCI resources starting at %lx (gap: %lx:%lx)\n",
pci_mem_start, gapstart, gapsize);
}
+
+int __init arch_get_ram_range(int slot, u64 *addr, u64 *size)
+{
+ int i;
+
+ if (slot < 0 || slot >= e820.nr_map)
+ return -1;
+ for (i = slot; i < e820.nr_map; i++) {
+ if (e820.map[i].type != E820_RAM)
+ continue;
+ break;
+ }
+ if (i == e820.nr_map || e820.map[i].addr > (max_pfn << PAGE_SHIFT))
+ return -1;
+ *addr = e820.map[i].addr;
+ *size = min_t(u64, e820.map[i].size + e820.map[i].addr,
+ max_pfn << PAGE_SHIFT) - *addr;
+ return i + 1;
+}
diff --git a/arch/x86/kernel/early-quirks_64.c b/arch/x86/kernel/early-quirks.c
index 13aa4fd728f..dc34acbd54a 100644
--- a/arch/x86/kernel/early-quirks_64.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -13,9 +13,13 @@
#include <linux/acpi.h>
#include <linux/pci_ids.h>
#include <asm/pci-direct.h>
-#include <asm/proto.h>
-#include <asm/iommu.h>
#include <asm/dma.h>
+#include <asm/io_apic.h>
+#include <asm/apic.h>
+
+#ifdef CONFIG_IOMMU
+#include <asm/iommu.h>
+#endif
static void __init via_bugs(void)
{
@@ -23,7 +27,8 @@ static void __init via_bugs(void)
if ((end_pfn > MAX_DMA32_PFN || force_iommu) &&
!iommu_aperture_allowed) {
printk(KERN_INFO
- "Looks like a VIA chipset. Disabling IOMMU. Override with iommu=allowed\n");
+ "Looks like a VIA chipset. Disabling IOMMU."
+ " Override with iommu=allowed\n");
iommu_aperture_disabled = 1;
}
#endif
@@ -40,6 +45,7 @@ static int __init nvidia_hpet_check(struct acpi_table_header *header)
static void __init nvidia_bugs(void)
{
#ifdef CONFIG_ACPI
+#ifdef CONFIG_X86_IO_APIC
/*
* All timer overrides on Nvidia are
* wrong unless HPET is enabled.
@@ -59,17 +65,20 @@ static void __init nvidia_bugs(void)
"try acpi_use_timer_override\n");
}
#endif
+#endif
/* RED-PEN skip them on mptables too? */
}
static void __init ati_bugs(void)
{
+#ifdef CONFIG_X86_IO_APIC
if (timer_over_8254 == 1) {
timer_over_8254 = 0;
printk(KERN_INFO
- "ATI board detected. Disabling timer routing over 8254.\n");
+ "ATI board detected. Disabling timer routing over 8254.\n");
}
+#endif
}
struct chipset {
@@ -104,7 +113,7 @@ void __init early_quirks(void)
if (class == 0xffffffff)
break;
- if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
+ if ((class >> 16) != PCI_CLASS_BRIDGE_PCI)
continue;
vendor = read_pci_config(num, slot, func,
diff --git a/arch/x86/kernel/efi_32.c b/arch/x86/kernel/efi_32.c
index b42558c48e9..e2be78f4939 100644
--- a/arch/x86/kernel/efi_32.c
+++ b/arch/x86/kernel/efi_32.c
@@ -603,7 +603,8 @@ void __init efi_enter_virtual_mode(void)
void __init
efi_initialize_iomem_resources(struct resource *code_resource,
- struct resource *data_resource)
+ struct resource *data_resource,
+ struct resource *bss_resource)
{
struct resource *res;
efi_memory_desc_t *md;
@@ -675,6 +676,7 @@ efi_initialize_iomem_resources(struct resource *code_resource,
if (md->type == EFI_CONVENTIONAL_MEMORY) {
request_resource(res, code_resource);
request_resource(res, data_resource);
+ request_resource(res, bss_resource);
#ifdef CONFIG_KEXEC
request_resource(res, &crashk_res);
#endif
diff --git a/arch/x86/kernel/genapic_64.c b/arch/x86/kernel/genapic_64.c
index 4ae03e3e829..ce703e21c91 100644
--- a/arch/x86/kernel/genapic_64.c
+++ b/arch/x86/kernel/genapic_64.c
@@ -24,10 +24,19 @@
#include <acpi/acpi_bus.h>
#endif
-/* which logical CPU number maps to which CPU (physical APIC ID) */
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly
+/*
+ * which logical CPU number maps to which CPU (physical APIC ID)
+ *
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time. Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata
= { [0 ... NR_CPUS-1] = BAD_APICID };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
struct genapic __read_mostly *genapic = &apic_flat;
diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c
index 91c7526768e..07352b74bda 100644
--- a/arch/x86/kernel/genapic_flat_64.c
+++ b/arch/x86/kernel/genapic_flat_64.c
@@ -172,7 +172,7 @@ static unsigned int physflat_cpu_mask_to_apicid(cpumask_t cpumask)
*/
cpu = first_cpu(cpumask);
if ((unsigned)cpu < NR_CPUS)
- return x86_cpu_to_apicid[cpu];
+ return per_cpu(x86_cpu_to_apicid, cpu);
else
return BAD_APICID;
}
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index a7eee0a4751..6b3469311e4 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -58,7 +58,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
for (i = 0; i < IDT_ENTRIES; i++)
set_intr_gate(i, early_idt_handler);
- asm volatile("lidt %0" :: "m" (idt_descr));
+ load_idt((const struct desc_ptr *)&idt_descr);
early_printk("Kernel alive\n");
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S
index 39677965e16..00b1c2c5645 100644
--- a/arch/x86/kernel/head_32.S
+++ b/arch/x86/kernel/head_32.S
@@ -79,22 +79,30 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_
*/
.section .text.head,"ax",@progbits
ENTRY(startup_32)
+ /* check to see if KEEP_SEGMENTS flag is meaningful */
+ cmpw $0x207, BP_version(%esi)
+ jb 1f
+
+ /* test KEEP_SEGMENTS flag to see if the bootloader is asking
+ us to not reload segments */
+ testb $(1<<6), BP_loadflags(%esi)
+ jnz 2f
/*
* Set segments to known values.
*/
- cld
- lgdt boot_gdt_descr - __PAGE_OFFSET
+1: lgdt boot_gdt_descr - __PAGE_OFFSET
movl $(__BOOT_DS),%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%fs
movl %eax,%gs
+2:
/*
* Clear BSS first so that there are no surprises...
- * No need to cld as DF is already clear from cld above...
*/
+ cld
xorl %eax,%eax
movl $__bss_start - __PAGE_OFFSET,%edi
movl $__bss_stop - __PAGE_OFFSET,%ecx
@@ -128,6 +136,35 @@ ENTRY(startup_32)
movsl
1:
+#ifdef CONFIG_PARAVIRT
+ cmpw $0x207, (boot_params + BP_version - __PAGE_OFFSET)
+ jb default_entry
+
+ /* Paravirt-compatible boot parameters. Look to see what architecture
+ we're booting under. */
+ movl (boot_params + BP_hardware_subarch - __PAGE_OFFSET), %eax
+ cmpl $num_subarch_entries, %eax
+ jae bad_subarch
+
+ movl subarch_entries - __PAGE_OFFSET(,%eax,4), %eax
+ subl $__PAGE_OFFSET, %eax
+ jmp *%eax
+
+bad_subarch:
+WEAK(lguest_entry)
+WEAK(xen_entry)
+ /* Unknown implementation; there's really
+ nothing we can do at this point. */
+ ud2a
+.data
+subarch_entries:
+ .long default_entry /* normal x86/PC */
+ .long lguest_entry /* lguest hypervisor */
+ .long xen_entry /* Xen hypervisor */
+num_subarch_entries = (. - subarch_entries) / 4
+.previous
+#endif /* CONFIG_PARAVIRT */
+
/*
* Initialize page tables. This creates a PDE and a set of page
* tables, which are located immediately beyond _end. The variable
@@ -140,6 +177,7 @@ ENTRY(startup_32)
*/
page_pde_offset = (__PAGE_OFFSET >> 20);
+default_entry:
movl $(pg0 - __PAGE_OFFSET), %edi
movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index f8367074da0..53303f2e547 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -69,12 +69,15 @@ static inline void hpet_clear_mapping(void)
* HPET command line enable / disable
*/
static int boot_hpet_disable;
+int hpet_force_user;
static int __init hpet_setup(char* str)
{
if (str) {
if (!strncmp("disable", str, 7))
boot_hpet_disable = 1;
+ if (!strncmp("force", str, 5))
+ hpet_force_user = 1;
}
return 1;
}
@@ -350,7 +353,7 @@ static int hpet_clocksource_register(void)
*
* hpet period is in femto seconds per cycle
* so we need to convert this to ns/cyc units
- * aproximated by mult/2^shift
+ * approximated by mult/2^shift
*
* fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
* fsec/cyc * 1ns/1000000fsec * 2^shift = mult
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c
index 5cc8841ca2c..a42c8074532 100644
--- a/arch/x86/kernel/i8253.c
+++ b/arch/x86/kernel/i8253.c
@@ -86,7 +86,7 @@ static int pit_next_event(unsigned long delta, struct clock_event_device *evt)
* On UP the PIT can serve all of the possible timer functions. On SMP systems
* it can be solely used for the global tick.
*
- * The profiling and update capabilites are switched off once the local apic is
+ * The profiling and update capabilities are switched off once the local apic is
* registered. This mechanism replaces the previous #ifdef LOCAL_APIC -
* !using_apic_timer decisions in do_timer_interrupt_hook()
*/
diff --git a/arch/x86/kernel/i8259_32.c b/arch/x86/kernel/i8259_32.c
index d34a10cc13a..f634fc715c9 100644
--- a/arch/x86/kernel/i8259_32.c
+++ b/arch/x86/kernel/i8259_32.c
@@ -403,7 +403,8 @@ void __init native_init_IRQ(void)
int vector = FIRST_EXTERNAL_VECTOR + i;
if (i >= NR_IRQS)
break;
- if (vector != SYSCALL_VECTOR)
+ /* SYSCALL_VECTOR was reserved in trap_init. */
+ if (!test_bit(vector, used_vectors))
set_intr_gate(vector, interrupt[i]);
}
diff --git a/arch/x86/kernel/init_task_32.c b/arch/x86/kernel/init_task.c
index d26fc063a76..468c9c43784 100644
--- a/arch/x86/kernel/init_task_32.c
+++ b/arch/x86/kernel/init_task.c
@@ -15,7 +15,6 @@ static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
struct mm_struct init_mm = INIT_MM(init_mm);
-
EXPORT_SYMBOL(init_mm);
/*
@@ -25,7 +24,7 @@ EXPORT_SYMBOL(init_mm);
* way process stacks are handled. This is done by having a special
* "init_task" linker map entry..
*/
-union thread_union init_thread_union
+union thread_union init_thread_union
__attribute__((__section__(".data.init_task"))) =
{ INIT_THREAD_INFO(init_task) };
@@ -35,12 +34,14 @@ union thread_union init_thread_union
* All other task structs will be allocated on slabs in fork.c
*/
struct task_struct init_task = INIT_TASK(init_task);
-
EXPORT_SYMBOL(init_task);
/*
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's.
- */
+ * no more per-task TSS's. The TSS size is kept cacheline-aligned
+ * so they are allowed to end up in the .data.cacheline_aligned
+ * section. Since TSS's are completely CPU-local, we want them
+ * on exact cacheline boundaries, to eliminate cacheline ping-pong.
+ */
DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
diff --git a/arch/x86/kernel/init_task_64.c b/arch/x86/kernel/init_task_64.c
deleted file mode 100644
index 4ff33d4f855..00000000000
--- a/arch/x86/kernel/init_task_64.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/desc.h>
-
-static struct fs_struct init_fs = INIT_FS;
-static struct files_struct init_files = INIT_FILES;
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-struct mm_struct init_mm = INIT_MM(init_mm);
-
-EXPORT_SYMBOL(init_mm);
-
-/*
- * Initial task structure.
- *
- * We need to make sure that this is 8192-byte aligned due to the
- * way process stacks are handled. This is done by having a special
- * "init_task" linker map entry..
- */
-union thread_union init_thread_union
- __attribute__((__section__(".data.init_task"))) =
- { INIT_THREAD_INFO(init_task) };
-
-/*
- * Initial task structure.
- *
- * All other task structs will be allocated on slabs in fork.c
- */
-struct task_struct init_task = INIT_TASK(init_task);
-
-EXPORT_SYMBOL(init_task);
-/*
- * per-CPU TSS segments. Threads are completely 'soft' on Linux,
- * no more per-task TSS's. The TSS size is kept cacheline-aligned
- * so they are allowed to end up in the .data.cacheline_aligned
- * section. Since TSS's are completely CPU-local, we want them
- * on exact cacheline boundaries, to eliminate cacheline ping-pong.
- */
-DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
-
-/* Copies of the original ist values from the tss are only accessed during
- * debugging, no special alignment required.
- */
-DEFINE_PER_CPU(struct orig_ist, orig_ist);
-
-#define ALIGN_TO_4K __attribute__((section(".data.init_task")))
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index 5f10c718953..f35c6eb33da 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -584,7 +584,7 @@ tryanotherirq:
imbalance = move_this_load;
- /* For physical_balance case, we accumlated both load
+ /* For physical_balance case, we accumulated both load
* values in the one of the siblings cpu_irq[],
* to use the same code for physical and logical processors
* as much as possible.
@@ -1198,7 +1198,7 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }
static int __assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
- int vector, offset, i;
+ int vector, offset;
BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
@@ -1215,11 +1215,8 @@ next:
}
if (vector == current_vector)
return -ENOSPC;
- if (vector == SYSCALL_VECTOR)
+ if (test_and_set_bit(vector, used_vectors))
goto next;
- for (i = 0; i < NR_IRQ_VECTORS; i++)
- if (irq_vector[i] == vector)
- goto next;
current_vector = vector;
current_offset = offset;
@@ -2295,6 +2292,12 @@ static inline void __init check_timer(void)
void __init setup_IO_APIC(void)
{
+ int i;
+
+ /* Reserve all the system vectors. */
+ for (i = FIRST_SYSTEM_VECTOR; i < NR_VECTORS; i++)
+ set_bit(i, used_vectors);
+
enable_IO_APIC();
if (acpi_ioapic)
@@ -2472,7 +2475,7 @@ void destroy_irq(unsigned int irq)
}
/*
- * MSI mesage composition
+ * MSI message composition
*/
#ifdef CONFIG_PCI_MSI
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 1c2c7bf6a9d..953328b55a3 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -31,6 +31,7 @@
#include <linux/sysdev.h>
#include <linux/msi.h>
#include <linux/htirq.h>
+#include <linux/dmar.h>
#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
#endif
@@ -1770,7 +1771,7 @@ __setup("no_timer_check", notimercheck);
/*
*
- * IRQ's that are handled by the PIC in the MPS IOAPIC case.
+ * IRQs that are handled by the PIC in the MPS IOAPIC case.
* - IRQ2 is the cascade IRQ, and cannot be a io-apic IRQ.
* Linux doesn't really care, as it's not actually used
* for any interrupt handling anyway.
@@ -1921,7 +1922,7 @@ void destroy_irq(unsigned int irq)
}
/*
- * MSI mesage composition
+ * MSI message composition
*/
#ifdef CONFIG_PCI_MSI
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
@@ -2031,8 +2032,64 @@ void arch_teardown_msi_irq(unsigned int irq)
destroy_irq(irq);
}
-#endif /* CONFIG_PCI_MSI */
+#ifdef CONFIG_DMAR
+#ifdef CONFIG_SMP
+static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
+{
+ struct irq_cfg *cfg = irq_cfg + irq;
+ struct msi_msg msg;
+ unsigned int dest;
+ cpumask_t tmp;
+
+ cpus_and(tmp, mask, cpu_online_map);
+ if (cpus_empty(tmp))
+ return;
+
+ if (assign_irq_vector(irq, mask))
+ return;
+
+ cpus_and(tmp, cfg->domain, mask);
+ dest = cpu_mask_to_apicid(tmp);
+
+ dmar_msi_read(irq, &msg);
+
+ msg.data &= ~MSI_DATA_VECTOR_MASK;
+ msg.data |= MSI_DATA_VECTOR(cfg->vector);
+ msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+ msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+ dmar_msi_write(irq, &msg);
+ irq_desc[irq].affinity = mask;
+}
+#endif /* CONFIG_SMP */
+
+struct irq_chip dmar_msi_type = {
+ .name = "DMAR_MSI",
+ .unmask = dmar_msi_unmask,
+ .mask = dmar_msi_mask,
+ .ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+ .set_affinity = dmar_msi_set_affinity,
+#endif
+ .retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_dmar_msi(unsigned int irq)
+{
+ int ret;
+ struct msi_msg msg;
+
+ ret = msi_compose_msg(NULL, irq, &msg);
+ if (ret < 0)
+ return ret;
+ dmar_msi_write(irq, &msg);
+ set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
+ "edge");
+ return 0;
+}
+#endif
+#endif /* CONFIG_PCI_MSI */
/*
* Hypertransport interrupt support
*/
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 8459ca64bc2..11b935f4f88 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -149,28 +149,6 @@ NORET_TYPE void machine_kexec(struct kimage *image)
image->start, cpu_has_pae);
}
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel. By reserving this memory we guarantee
- * that linux never sets it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init parse_crashkernel(char *arg)
-{
- unsigned long size, base;
- size = memparse(arg, &arg);
- if (*arg == '@') {
- base = memparse(arg+1, &arg);
- /* FIXME: Do I want a sanity check
- * to validate the memory range?
- */
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- return 0;
-}
-early_param("crashkernel", parse_crashkernel);
-
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 7450b69710b..0d8577f0542 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -231,33 +231,6 @@ NORET_TYPE void machine_kexec(struct kimage *image)
image->start);
}
-/* crashkernel=size@addr specifies the location to reserve for
- * a crash kernel. By reserving this memory we guarantee
- * that linux never set's it up as a DMA target.
- * Useful for holding code to do something appropriate
- * after a kernel panic.
- */
-static int __init setup_crashkernel(char *arg)
-{
- unsigned long size, base;
- char *p;
- if (!arg)
- return -EINVAL;
- size = memparse(arg, &p);
- if (arg == p)
- return -EINVAL;
- if (*p == '@') {
- base = memparse(p+1, &p);
- /* FIXME: Do I want a sanity check to validate the
- * memory range? Yes you do, but it's too early for
- * e820 -AK */
- crashk_res.start = base;
- crashk_res.end = base + size - 1;
- }
- return 0;
-}
-early_param("crashkernel", setup_crashkernel);
-
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
diff --git a/arch/x86/kernel/mce_64.c b/arch/x86/kernel/mce_64.c
index 66e6b797b2c..07bbfe7aa7f 100644
--- a/arch/x86/kernel/mce_64.c
+++ b/arch/x86/kernel/mce_64.c
@@ -320,7 +320,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
#ifdef CONFIG_X86_MCE_INTEL
/***
* mce_log_therm_throt_event - Logs the thermal throttling event to mcelog
- * @cpu: The CPU on which the event occured.
+ * @cpu: The CPU on which the event occurred.
* @status: Event status information
*
* This function should be called by the thermal interrupt after the
@@ -688,7 +688,7 @@ static int __init mcheck_disable(char *str)
return 1;
}
-/* mce=off disables machine check. Note you can reenable it later
+/* mce=off disables machine check. Note you can re-enable it later
using sysfs.
mce=TOLERANCELEVEL (number, see above)
mce=bootlog Log MCEs from before booting. Disabled by default on AMD.
@@ -799,7 +799,8 @@ static __cpuinit int mce_create_device(unsigned int cpu)
{
int err;
int i;
- if (!mce_available(&cpu_data[cpu]))
+
+ if (!mce_available(&cpu_data(cpu)))
return -EIO;
memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject));
diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/mce_amd_64.c
index 0d2afd96aca..752fb16a817 100644
--- a/arch/x86/kernel/mce_amd_64.c
+++ b/arch/x86/kernel/mce_amd_64.c
@@ -472,11 +472,11 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
sprintf(name, "threshold_bank%i", bank);
#ifdef CONFIG_SMP
- if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */
+ if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
i = first_cpu(per_cpu(cpu_core_map, cpu));
/* first core not up yet */
- if (cpu_data[i].cpu_core_id)
+ if (cpu_data(i).cpu_core_id)
goto out;
/* already linked */
diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
index 09cf7811035..09c315214a5 100644
--- a/arch/x86/kernel/microcode.c
+++ b/arch/x86/kernel/microcode.c
@@ -132,7 +132,7 @@ static struct ucode_cpu_info {
static void collect_cpu_info(int cpu_num)
{
- struct cpuinfo_x86 *c = cpu_data + cpu_num;
+ struct cpuinfo_x86 *c = &cpu_data(cpu_num);
struct ucode_cpu_info *uci = ucode_cpu_info + cpu_num;
unsigned int val[2];
@@ -522,7 +522,7 @@ static struct platform_device *microcode_pdev;
static int cpu_request_microcode(int cpu)
{
char name[30];
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
const struct firmware *firmware;
void *buf;
unsigned long size;
@@ -570,7 +570,7 @@ static int cpu_request_microcode(int cpu)
static int apply_microcode_check_cpu(int cpu)
{
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
cpumask_t old;
unsigned int val[2];
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c
index 13abb4ebfb7..7a05a7f6099 100644
--- a/arch/x86/kernel/mpparse_32.c
+++ b/arch/x86/kernel/mpparse_32.c
@@ -1001,7 +1001,7 @@ void __init mp_config_acpi_legacy_irqs (void)
/*
* Use the default configuration for the IRQs 0-15. Unless
- * overriden by (MADT) interrupt source override entries.
+ * overridden by (MADT) interrupt source override entries.
*/
for (i = 0; i < 16; i++) {
int idx;
diff --git a/arch/x86/kernel/mpparse_64.c b/arch/x86/kernel/mpparse_64.c
index 8bf0ca03ac8..ef4aab12358 100644
--- a/arch/x86/kernel/mpparse_64.c
+++ b/arch/x86/kernel/mpparse_64.c
@@ -57,6 +57,8 @@ unsigned long mp_lapic_addr = 0;
/* Processor that is doing the boot up */
unsigned int boot_cpu_id = -1U;
+EXPORT_SYMBOL(boot_cpu_id);
+
/* Internal processor count */
unsigned int num_processors __cpuinitdata = 0;
@@ -86,7 +88,7 @@ static int __init mpf_checksum(unsigned char *mp, int len)
return sum & 0xFF;
}
-static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
+static void __cpuinit MP_processor_info(struct mpc_config_processor *m)
{
int cpu;
cpumask_t tmp_map;
@@ -123,7 +125,18 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
cpu = 0;
}
bios_cpu_apicid[cpu] = m->mpc_apicid;
- x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+ /*
+ * We get called early in the the start_kernel initialization
+ * process when the per_cpu data area is not yet setup, so we
+ * use a static array that is removed after the per_cpu data
+ * area is created.
+ */
+ if (x86_cpu_to_apicid_ptr) {
+ u8 *x86_cpu_to_apicid = (u8 *)x86_cpu_to_apicid_ptr;
+ x86_cpu_to_apicid[cpu] = m->mpc_apicid;
+ } else {
+ per_cpu(x86_cpu_to_apicid, cpu) = m->mpc_apicid;
+ }
cpu_set(cpu, cpu_possible_map);
cpu_set(cpu, cpu_present_map);
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index e18e516cf54..ee6eba4ecfe 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -112,7 +112,7 @@ static ssize_t msr_write(struct file *file, const char __user *buf,
static int msr_open(struct inode *inode, struct file *file)
{
unsigned int cpu = iminor(file->f_path.dentry->d_inode);
- struct cpuinfo_x86 *c = &(cpu_data)[cpu];
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
if (cpu >= NR_CPUS || !cpu_online(cpu))
return -ENXIO; /* No such CPU */
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 5098f58063a..1a20fe31338 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -411,8 +411,10 @@ static int calgary_nontranslate_map_sg(struct device* dev,
int i;
for_each_sg(sg, s, nelems, i) {
- BUG_ON(!s->page);
- s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+ struct page *p = sg_page(s);
+
+ BUG_ON(!p);
+ s->dma_address = virt_to_bus(sg_virt(s));
s->dma_length = s->length;
}
return nelems;
@@ -432,9 +434,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
for_each_sg(sg, s, nelems, i) {
- BUG_ON(!s->page);
+ BUG_ON(!sg_page(s));
- vaddr = (unsigned long)page_address(s->page) + s->offset;
+ vaddr = (unsigned long) sg_virt(s);
npages = num_dma_pages(vaddr, s->length);
entry = iommu_range_alloc(tbl, npages);
diff --git a/arch/x86/kernel/pci-dma_64.c b/arch/x86/kernel/pci-dma_64.c
index b2b42bdb0a1..393e2725a6e 100644
--- a/arch/x86/kernel/pci-dma_64.c
+++ b/arch/x86/kernel/pci-dma_64.c
@@ -7,11 +7,12 @@
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/dmar.h>
#include <asm/io.h>
#include <asm/iommu.h>
#include <asm/calgary.h>
-int iommu_merge __read_mostly = 0;
+int iommu_merge __read_mostly = 1;
EXPORT_SYMBOL(iommu_merge);
dma_addr_t bad_dma_address __read_mostly;
@@ -305,6 +306,8 @@ void __init pci_iommu_alloc(void)
detect_calgary();
#endif
+ detect_intel_iommu();
+
#ifdef CONFIG_SWIOTLB
pci_swiotlb_init();
#endif
@@ -316,6 +319,8 @@ static int __init pci_iommu_init(void)
calgary_iommu_init();
#endif
+ intel_iommu_init();
+
#ifdef CONFIG_IOMMU
gart_iommu_init();
#endif
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 5cdfab65e93..c56e9ee6496 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -302,7 +302,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
#endif
for_each_sg(sg, s, nents, i) {
- unsigned long addr = page_to_phys(s->page) + s->offset;
+ unsigned long addr = sg_phys(s);
if (nonforced_iommu(dev, addr, s->length)) {
addr = dma_map_area(dev, addr, s->length, dir);
if (addr == bad_dma_address) {
@@ -397,7 +397,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
start_sg = sgmap = sg;
ps = NULL; /* shut up gcc */
for_each_sg(sg, s, nents, i) {
- dma_addr_t addr = page_to_phys(s->page) + s->offset;
+ dma_addr_t addr = sg_phys(s);
s->dma_address = addr;
BUG_ON(s->length == 0);
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index e85d4360360..faf70bdca33 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -62,8 +62,8 @@ static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
int i;
for_each_sg(sg, s, nents, i) {
- BUG_ON(!s->page);
- s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
+ BUG_ON(!sg_page(s));
+ s->dma_address = virt_to_bus(sg_virt(s));
if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
return 0;
s->dma_length = s->length;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 097aeafce5f..7b899584d29 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -295,34 +295,52 @@ static int __init idle_setup(char *str)
}
early_param("idle", idle_setup);
-void show_regs(struct pt_regs * regs)
+void __show_registers(struct pt_regs *regs, int all)
{
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
unsigned long d0, d1, d2, d3, d6, d7;
+ unsigned long esp;
+ unsigned short ss, gs;
+
+ if (user_mode_vm(regs)) {
+ esp = regs->esp;
+ ss = regs->xss & 0xffff;
+ savesegment(gs, gs);
+ } else {
+ esp = (unsigned long) (&regs->esp);
+ savesegment(ss, ss);
+ savesegment(gs, gs);
+ }
printk("\n");
- printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
- printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
+ printk("Pid: %d, comm: %s %s (%s %.*s)\n",
+ task_pid_nr(current), current->comm,
+ print_tainted(), init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
+
+ printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
+ 0xffff & regs->xcs, regs->eip, regs->eflags,
+ smp_processor_id());
print_symbol("EIP is at %s\n", regs->eip);
- if (user_mode_vm(regs))
- printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
- printk(" EFLAGS: %08lx %s (%s %.*s)\n",
- regs->eflags, print_tainted(), init_utsname()->release,
- (int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
- regs->eax,regs->ebx,regs->ecx,regs->edx);
- printk("ESI: %08lx EDI: %08lx EBP: %08lx",
- regs->esi, regs->edi, regs->ebp);
- printk(" DS: %04x ES: %04x FS: %04x\n",
- 0xffff & regs->xds,0xffff & regs->xes, 0xffff & regs->xfs);
+ regs->eax, regs->ebx, regs->ecx, regs->edx);
+ printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
+ regs->esi, regs->edi, regs->ebp, esp);
+ printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
+ regs->xds & 0xffff, regs->xes & 0xffff,
+ regs->xfs & 0xffff, gs, ss);
+
+ if (!all)
+ return;
cr0 = read_cr0();
cr2 = read_cr2();
cr3 = read_cr3();
cr4 = read_cr4_safe();
- printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
+ printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n",
+ cr0, cr2, cr3, cr4);
get_debugreg(d0, 0);
get_debugreg(d1, 1);
@@ -330,10 +348,16 @@ void show_regs(struct pt_regs * regs)
get_debugreg(d3, 3);
printk("DR0: %08lx DR1: %08lx DR2: %08lx DR3: %08lx\n",
d0, d1, d2, d3);
+
get_debugreg(d6, 6);
get_debugreg(d7, 7);
- printk("DR6: %08lx DR7: %08lx\n", d6, d7);
+ printk("DR6: %08lx DR7: %08lx\n",
+ d6, d7);
+}
+void show_regs(struct pt_regs *regs)
+{
+ __show_registers(regs, 1);
show_trace(NULL, regs, &regs->esp);
}
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 99102ec5fad..ff5431cc03e 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -632,7 +632,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
/* User-mode eip? */
info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
- /* Send us the fakey SIGTRAP */
+ /* Send us the fake SIGTRAP */
force_sig_info(SIGTRAP, &info, tsk);
}
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index d769e204f94..a4ce1911efd 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -45,9 +45,12 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
if (!(config & 0x2))
pci_write_config_byte(dev, 0xf4, config);
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH,
+ quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH,
+ quirk_intel_irqbalance);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH,
+ quirk_intel_irqbalance);
#endif
#if defined(CONFIG_HPET_TIMER)
@@ -56,7 +59,8 @@ unsigned long force_hpet_address;
static enum {
NONE_FORCE_HPET_RESUME,
OLD_ICH_FORCE_HPET_RESUME,
- ICH_FORCE_HPET_RESUME
+ ICH_FORCE_HPET_RESUME,
+ VT8237_FORCE_HPET_RESUME
} force_hpet_resume_type;
static void __iomem *rcba_base;
@@ -146,17 +150,17 @@ static void ich_force_enable_hpet(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
- ich_force_enable_hpet);
+ ich_force_enable_hpet);
static struct pci_dev *cached_dev;
@@ -232,10 +236,91 @@ static void old_ich_force_enable_hpet(struct pci_dev *dev)
printk(KERN_DEBUG "Failed to force enable HPET\n");
}
+/*
+ * Undocumented chipset features. Make sure that the user enforced
+ * this.
+ */
+static void old_ich_force_enable_hpet_user(struct pci_dev *dev)
+{
+ if (hpet_force_user)
+ old_ich_force_enable_hpet(dev);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
+ old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+ old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+ old_ich_force_enable_hpet_user);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
+ old_ich_force_enable_hpet_user);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
- old_ich_force_enable_hpet);
+ old_ich_force_enable_hpet);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
- old_ich_force_enable_hpet);
+ old_ich_force_enable_hpet);
+
+
+static void vt8237_force_hpet_resume(void)
+{
+ u32 val;
+
+ if (!force_hpet_address || !cached_dev)
+ return;
+
+ val = 0xfed00000 | 0x80;
+ pci_write_config_dword(cached_dev, 0x68, val);
+
+ pci_read_config_dword(cached_dev, 0x68, &val);
+ if (val & 0x80)
+ printk(KERN_DEBUG "Force enabled HPET at resume\n");
+ else
+ BUG();
+}
+
+static void vt8237_force_enable_hpet(struct pci_dev *dev)
+{
+ u32 uninitialized_var(val);
+
+ if (!hpet_force_user || hpet_address || force_hpet_address)
+ return;
+
+ pci_read_config_dword(dev, 0x68, &val);
+ /*
+ * Bit 7 is HPET enable bit.
+ * Bit 31:10 is HPET base address (contrary to what datasheet claims)
+ */
+ if (val & 0x80) {
+ force_hpet_address = (val & ~0x3ff);
+ printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+ force_hpet_address);
+ return;
+ }
+
+ /*
+ * HPET is disabled. Trying enabling at FED00000 and check
+ * whether it sticks
+ */
+ val = 0xfed00000 | 0x80;
+ pci_write_config_dword(dev, 0x68, val);
+
+ pci_read_config_dword(dev, 0x68, &val);
+ if (val & 0x80) {
+ force_hpet_address = (val & ~0x3ff);
+ printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+ force_hpet_address);
+ cached_dev = dev;
+ force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
+ return;
+ }
+
+ printk(KERN_DEBUG "Failed to force enable HPET\n");
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
+ vt8237_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
+ vt8237_force_enable_hpet);
+
void force_hpet_resume(void)
{
@@ -246,6 +331,9 @@ void force_hpet_resume(void)
case OLD_ICH_FORCE_HPET_RESUME:
return old_ich_force_hpet_resume();
+ case VT8237_FORCE_HPET_RESUME:
+ return vt8237_force_hpet_resume();
+
default:
break;
}
diff --git a/arch/x86/kernel/reboot_64.c b/arch/x86/kernel/reboot_64.c
index 368db2b9c5a..776eb06b651 100644
--- a/arch/x86/kernel/reboot_64.c
+++ b/arch/x86/kernel/reboot_64.c
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <asm/io.h>
#include <asm/delay.h>
+#include <asm/desc.h>
#include <asm/hw_irq.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -136,7 +137,7 @@ void machine_emergency_restart(void)
}
case BOOT_TRIPLE:
- __asm__ __volatile__("lidt (%0)": :"r" (&no_idt));
+ load_idt((const struct desc_ptr *)&no_idt);
__asm__ __volatile__("int3");
reboot_type = BOOT_KBD;
diff --git a/arch/x86/kernel/reboot_fixups_32.c b/arch/x86/kernel/reboot_fixups_32.c
index 8b30b26ad06..1a07bbea7be 100644
--- a/arch/x86/kernel/reboot_fixups_32.c
+++ b/arch/x86/kernel/reboot_fixups_32.c
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <asm/reboot_fixups.h>
#include <asm/msr.h>
+#include <asm/geode.h>
static void cs5530a_warm_reset(struct pci_dev *dev)
{
@@ -24,11 +25,8 @@ static void cs5530a_warm_reset(struct pci_dev *dev)
static void cs5536_warm_reset(struct pci_dev *dev)
{
- /*
- * 6.6.2.12 Soft Reset (DIVIL_SOFT_RESET)
- * writing 1 to the LSB of this MSR causes a hard reset.
- */
- wrmsrl(0x51400017, 1ULL);
+ /* writing 1 to the LSB of this MSR causes a hard reset */
+ wrmsrl(MSR_DIVIL_SOFT_RESET, 1ULL);
udelay(50); /* shouldn't get here but be safe and spin a while */
}
diff --git a/arch/x86/kernel/setup64.c b/arch/x86/kernel/setup64.c
index ba918823505..3558ac78c92 100644
--- a/arch/x86/kernel/setup64.c
+++ b/arch/x86/kernel/setup64.c
@@ -185,6 +185,12 @@ void __cpuinit check_efer(void)
unsigned long kernel_eflags;
/*
+ * Copies of the original ist values from the tss are only accessed during
+ * debugging, no special alignment required.
+ */
+DEFINE_PER_CPU(struct orig_ist, orig_ist);
+
+/*
* cpu_init() initializes state that is per-CPU. Some data is already
* initialized (naturally) in the bootstrap process, such as the GDT
* and IDT. We reload them nevertheless, this function acts as a
@@ -224,8 +230,8 @@ void __cpuinit cpu_init (void)
memcpy(cpu_gdt(cpu), cpu_gdt_table, GDT_SIZE);
cpu_gdt_descr[cpu].size = GDT_SIZE;
- asm volatile("lgdt %0" :: "m" (cpu_gdt_descr[cpu]));
- asm volatile("lidt %0" :: "m" (idt_descr));
+ load_gdt((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
+ load_idt((const struct desc_ptr *)&idt_descr);
memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
syscall_init();
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index b87a6fd5ba4..cc0e91447b7 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -60,6 +60,7 @@
#include <asm/vmi.h>
#include <setup_arch.h>
#include <bios_ebda.h>
+#include <asm/cacheflush.h>
/* This value is set up by the early boot code to point to the value
immediately after the boot time page tables. It contains a *physical*
@@ -73,6 +74,7 @@ int disable_pse __devinitdata = 0;
*/
extern struct resource code_resource;
extern struct resource data_resource;
+extern struct resource bss_resource;
/* cpu data as detected by the assembly code in head.S */
struct cpuinfo_x86 new_cpu_data __cpuinitdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
@@ -378,6 +380,49 @@ extern unsigned long __init setup_memory(void);
extern void zone_sizes_init(void);
#endif /* !CONFIG_NEED_MULTIPLE_NODES */
+static inline unsigned long long get_total_mem(void)
+{
+ unsigned long long total;
+
+ total = max_low_pfn - min_low_pfn;
+#ifdef CONFIG_HIGHMEM
+ total += highend_pfn - highstart_pfn;
+#endif
+
+ return total << PAGE_SHIFT;
+}
+
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+ unsigned long long total_mem;
+ unsigned long long crash_size, crash_base;
+ int ret;
+
+ total_mem = get_total_mem();
+
+ ret = parse_crashkernel(boot_command_line, total_mem,
+ &crash_size, &crash_base);
+ if (ret == 0 && crash_size > 0) {
+ if (crash_base > 0) {
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crash_base >> 20),
+ (unsigned long)(total_mem >> 20));
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+ reserve_bootmem(crash_base, crash_size);
+ } else
+ printk(KERN_INFO "crashkernel reservation failed - "
+ "you have to specify a base address\n");
+ }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
void __init setup_bootmem_allocator(void)
{
unsigned long bootmap_size;
@@ -453,11 +498,7 @@ void __init setup_bootmem_allocator(void)
}
}
#endif
-#ifdef CONFIG_KEXEC
- if (crashk_res.start != crashk_res.end)
- reserve_bootmem(crashk_res.start,
- crashk_res.end - crashk_res.start + 1);
-#endif
+ reserve_crashkernel();
}
/*
@@ -561,6 +602,8 @@ void __init setup_arch(char **cmdline_p)
code_resource.end = virt_to_phys(_etext)-1;
data_resource.start = virt_to_phys(_etext);
data_resource.end = virt_to_phys(_edata)-1;
+ bss_resource.start = virt_to_phys(&__bss_start);
+ bss_resource.end = virt_to_phys(&__bss_stop)-1;
parse_early_param();
@@ -585,7 +628,7 @@ void __init setup_arch(char **cmdline_p)
/*
* NOTE: before this point _nobody_ is allowed to allocate
* any memory using the bootmem allocator. Although the
- * alloctor is now initialised only the first 8Mb of the kernel
+ * allocator is now initialised only the first 8Mb of the kernel
* virtual address space has been mapped. All allocations before
* paging_init() has completed must use the alloc_bootmem_low_pages()
* variant (which allocates DMA'able memory) and care must be taken
@@ -622,9 +665,7 @@ void __init setup_arch(char **cmdline_p)
#endif
#ifdef CONFIG_PCI
-#ifdef CONFIG_X86_IO_APIC
- check_acpi_pci(); /* Checks more than just ACPI actually */
-#endif
+ early_quirks();
#endif
#ifdef CONFIG_ACPI
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index 5a19f0cc5b6..e7a9e36bd52 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -58,6 +58,7 @@
#include <asm/numa.h>
#include <asm/sections.h>
#include <asm/dmi.h>
+#include <asm/cacheflush.h>
/*
* Machine setup..
@@ -133,6 +134,12 @@ struct resource code_resource = {
.end = 0,
.flags = IORESOURCE_RAM,
};
+struct resource bss_resource = {
+ .name = "Kernel bss",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_RAM,
+};
#ifdef CONFIG_PROC_VMCORE
/* elfcorehdr= specifies the location of elf core header
@@ -191,6 +198,37 @@ static inline void copy_edd(void)
}
#endif
+#ifdef CONFIG_KEXEC
+static void __init reserve_crashkernel(void)
+{
+ unsigned long long free_mem;
+ unsigned long long crash_size, crash_base;
+ int ret;
+
+ free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
+
+ ret = parse_crashkernel(boot_command_line, free_mem,
+ &crash_size, &crash_base);
+ if (ret == 0 && crash_size) {
+ if (crash_base > 0) {
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crash_base >> 20),
+ (unsigned long)(free_mem >> 20));
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+ reserve_bootmem(crash_base, crash_size);
+ } else
+ printk(KERN_INFO "crashkernel reservation failed - "
+ "you have to specify a base address\n");
+ }
+}
+#else
+static inline void __init reserve_crashkernel(void)
+{}
+#endif
+
#define EBDA_ADDR_POINTER 0x40E
unsigned __initdata ebda_addr;
@@ -245,6 +283,8 @@ void __init setup_arch(char **cmdline_p)
code_resource.end = virt_to_phys(&_etext)-1;
data_resource.start = virt_to_phys(&_etext);
data_resource.end = virt_to_phys(&_edata)-1;
+ bss_resource.start = virt_to_phys(&__bss_start);
+ bss_resource.end = virt_to_phys(&__bss_stop)-1;
early_identify_cpu(&boot_cpu_data);
@@ -271,6 +311,11 @@ void __init setup_arch(char **cmdline_p)
dmi_scan_machine();
+#ifdef CONFIG_SMP
+ /* setup to use the static apicid table during kernel startup */
+ x86_cpu_to_apicid_ptr = (void *)&x86_cpu_to_apicid_init;
+#endif
+
#ifdef CONFIG_ACPI
/*
* Initialize the ACPI boot-time table parser (gets the RSDP and SDT).
@@ -357,13 +402,7 @@ void __init setup_arch(char **cmdline_p)
}
}
#endif
-#ifdef CONFIG_KEXEC
- if (crashk_res.start != crashk_res.end) {
- reserve_bootmem_generic(crashk_res.start,
- crashk_res.end - crashk_res.start + 1);
- }
-#endif
-
+ reserve_crashkernel();
paging_init();
#ifdef CONFIG_PCI
@@ -529,7 +568,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
but in the same order as the HT nodeids.
If that doesn't result in a usable node fall back to the
path for the previous case. */
- int ht_nodeid = apicid - (cpu_data[0].phys_proc_id << bits);
+ int ht_nodeid = apicid - (cpu_data(0).phys_proc_id << bits);
if (ht_nodeid >= 0 &&
apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
node = apicid_to_node[ht_nodeid];
@@ -853,6 +892,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP
c->phys_proc_id = (cpuid_ebx(1) >> 24) & 0xff;
+ c->cpu_index = 0;
#endif
}
@@ -959,6 +999,7 @@ void __cpuinit print_cpu_info(struct cpuinfo_x86 *c)
static int show_cpuinfo(struct seq_file *m, void *v)
{
struct cpuinfo_x86 *c = v;
+ int cpu = 0;
/*
* These flag bits must match the definitions in <asm/cpufeature.h>.
@@ -1037,8 +1078,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
- if (!cpu_online(c-cpu_data))
+ if (!cpu_online(c->cpu_index))
return 0;
+ cpu = c->cpu_index;
#endif
seq_printf(m,"processor\t: %u\n"
@@ -1046,7 +1088,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"cpu family\t: %d\n"
"model\t\t: %d\n"
"model name\t: %s\n",
- (unsigned)(c-cpu_data),
+ (unsigned)cpu,
c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown",
c->x86,
(int)c->x86_model,
@@ -1058,7 +1100,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
seq_printf(m, "stepping\t: unknown\n");
if (cpu_has(c,X86_FEATURE_TSC)) {
- unsigned int freq = cpufreq_quick_get((unsigned)(c-cpu_data));
+ unsigned int freq = cpufreq_quick_get((unsigned)cpu);
if (!freq)
freq = cpu_khz;
seq_printf(m, "cpu MHz\t\t: %u.%03u\n",
@@ -1071,7 +1113,6 @@ static int show_cpuinfo(struct seq_file *m, void *v)
#ifdef CONFIG_SMP
if (smp_num_siblings * c->x86_max_cores > 1) {
- int cpu = c - cpu_data;
seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
seq_printf(m, "siblings\t: %d\n",
cpus_weight(per_cpu(cpu_core_map, cpu)));
@@ -1129,12 +1170,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
static void *c_start(struct seq_file *m, loff_t *pos)
{
- return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+ if (*pos == 0) /* just in case, cpu 0 is not the first */
+ *pos = first_cpu(cpu_possible_map);
+ if ((*pos) < NR_CPUS && cpu_possible(*pos))
+ return &cpu_data(*pos);
+ return NULL;
}
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
- ++*pos;
+ *pos = next_cpu(*pos, cpu_possible_map);
return c_start(m, pos);
}
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 0d79df3c563..9bdd83022f5 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -200,8 +200,8 @@ badframe:
if (show_unhandled_signals && printk_ratelimit())
printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
" esp:%lx oeax:%lx\n",
- current->pid > 1 ? KERN_INFO : KERN_EMERG,
- current->comm, current->pid, frame, regs->eip,
+ task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
+ current->comm, task_pid_nr(current), frame, regs->eip,
regs->esp, regs->orig_eax);
force_sig(SIGSEGV, current);
@@ -594,7 +594,7 @@ static void fastcall do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- /* Reenable any watchpoints before delivering the
+ /* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
* inside the kernel.
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 683802bec41..ab086b0357f 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -410,7 +410,7 @@ static void do_signal(struct pt_regs *regs)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
- /* Reenable any watchpoints before delivering the
+ /* Re-enable any watchpoints before delivering the
* signal to user space. The processor register will
* have been cleared if the watchpoint triggered
* inside the kernel.
diff --git a/arch/x86/kernel/smp_32.c b/arch/x86/kernel/smp_32.c
index 791d9f8036a..f3211530839 100644
--- a/arch/x86/kernel/smp_32.c
+++ b/arch/x86/kernel/smp_32.c
@@ -69,7 +69,7 @@
*
* B stepping CPUs may hang. There are hardware work arounds
* for this. We warn about it in case your board doesn't have the work
- * arounds. Basically thats so I can tell anyone with a B stepping
+ * arounds. Basically that's so I can tell anyone with a B stepping
* CPU and SMP problems "tough".
*
* Specific items [From Pentium Processor Specification Update]
@@ -273,7 +273,7 @@ void leave_mm(unsigned long cpu)
* 1a1) cpu_clear(cpu, old_mm->cpu_vm_mask);
* Stop ipi delivery for the old mm. This is not synchronized with
* the other cpus, but smp_invalidate_interrupt ignore flush ipis
- * for the wrong mm, and in the worst case we perform a superflous
+ * for the wrong mm, and in the worst case we perform a superfluous
* tlb flush.
* 1a2) set cpu_tlbstate to TLBSTATE_OK
* Now the smp_invalidate_interrupt won't call leave_mm if cpu0
@@ -610,7 +610,7 @@ static void stop_this_cpu (void * dummy)
*/
cpu_clear(smp_processor_id(), cpu_online_map);
disable_local_APIC();
- if (cpu_data[smp_processor_id()].hlt_works_ok)
+ if (cpu_data(smp_processor_id()).hlt_works_ok)
for(;;) halt();
for (;;);
}
@@ -676,7 +676,7 @@ static int convert_apicid_to_cpu(int apic_id)
int i;
for (i = 0; i < NR_CPUS; i++) {
- if (x86_cpu_to_apicid[i] == apic_id)
+ if (per_cpu(x86_cpu_to_apicid, i) == apic_id)
return i;
}
return -1;
diff --git a/arch/x86/kernel/smp_64.c b/arch/x86/kernel/smp_64.c
index 5c2964727d1..03fa6ed559c 100644
--- a/arch/x86/kernel/smp_64.c
+++ b/arch/x86/kernel/smp_64.c
@@ -322,17 +322,27 @@ void unlock_ipi_call_lock(void)
}
/*
- * this function sends a 'generic call function' IPI to one other CPU
- * in the system.
- *
- * cpu is a standard Linux logical CPU number.
+ * this function sends a 'generic call function' IPI to all other CPU
+ * of the system defined in the mask.
*/
-static void
-__smp_call_function_single(int cpu, void (*func) (void *info), void *info,
- int nonatomic, int wait)
+
+static int
+__smp_call_function_mask(cpumask_t mask,
+ void (*func)(void *), void *info,
+ int wait)
{
struct call_data_struct data;
- int cpus = 1;
+ cpumask_t allbutself;
+ int cpus;
+
+ allbutself = cpu_online_map;
+ cpu_clear(smp_processor_id(), allbutself);
+
+ cpus_and(mask, mask, allbutself);
+ cpus = cpus_weight(mask);
+
+ if (!cpus)
+ return 0;
data.func = func;
data.info = info;
@@ -343,19 +353,55 @@ __smp_call_function_single(int cpu, void (*func) (void *info), void *info,
call_data = &data;
wmb();
- /* Send a message to all other CPUs and wait for them to respond */
- send_IPI_mask(cpumask_of_cpu(cpu), CALL_FUNCTION_VECTOR);
+
+ /* Send a message to other CPUs */
+ if (cpus_equal(mask, allbutself))
+ send_IPI_allbutself(CALL_FUNCTION_VECTOR);
+ else
+ send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
/* Wait for response */
while (atomic_read(&data.started) != cpus)
cpu_relax();
if (!wait)
- return;
+ return 0;
while (atomic_read(&data.finished) != cpus)
cpu_relax();
+
+ return 0;
+}
+/**
+ * smp_call_function_mask(): Run a function on a set of other CPUs.
+ * @mask: The set of cpus to run on. Must not include the current cpu.
+ * @func: The function to run. This must be fast and non-blocking.
+ * @info: An arbitrary pointer to pass to the function.
+ * @wait: If true, wait (atomically) until function has completed on other CPUs.
+ *
+ * Returns 0 on success, else a negative status code.
+ *
+ * If @wait is true, then returns once @func has returned; otherwise
+ * it returns just before the target cpu calls @func.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function_mask(cpumask_t mask,
+ void (*func)(void *), void *info,
+ int wait)
+{
+ int ret;
+
+ /* Can deadlock when called with interrupts disabled */
+ WARN_ON(irqs_disabled());
+
+ spin_lock(&call_lock);
+ ret = __smp_call_function_mask(mask, func, info, wait);
+ spin_unlock(&call_lock);
+ return ret;
}
+EXPORT_SYMBOL(smp_call_function_mask);
/*
* smp_call_function_single - Run a function on a specific CPU
@@ -374,6 +420,7 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
int nonatomic, int wait)
{
/* prevent preemption and reschedule on another processor */
+ int ret;
int me = get_cpu();
/* Can deadlock when called with interrupts disabled */
@@ -387,51 +434,14 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info,
return 0;
}
- spin_lock(&call_lock);
- __smp_call_function_single(cpu, func, info, nonatomic, wait);
- spin_unlock(&call_lock);
+ ret = smp_call_function_mask(cpumask_of_cpu(cpu), func, info, wait);
+
put_cpu();
- return 0;
+ return ret;
}
EXPORT_SYMBOL(smp_call_function_single);
/*
- * this function sends a 'generic call function' IPI to all other CPUs
- * in the system.
- */
-static void __smp_call_function (void (*func) (void *info), void *info,
- int nonatomic, int wait)
-{
- struct call_data_struct data;
- int cpus = num_online_cpus()-1;
-
- if (!cpus)
- return;
-
- data.func = func;
- data.info = info;
- atomic_set(&data.started, 0);
- data.wait = wait;
- if (wait)
- atomic_set(&data.finished, 0);
-
- call_data = &data;
- wmb();
- /* Send a message to all other CPUs and wait for them to respond */
- send_IPI_allbutself(CALL_FUNCTION_VECTOR);
-
- /* Wait for response */
- while (atomic_read(&data.started) != cpus)
- cpu_relax();
-
- if (!wait)
- return;
-
- while (atomic_read(&data.finished) != cpus)
- cpu_relax();
-}
-
-/*
* smp_call_function - run a function on all other CPUs.
* @func: The function to run. This must be fast and non-blocking.
* @info: An arbitrary pointer to pass to the function.
@@ -449,10 +459,7 @@ static void __smp_call_function (void (*func) (void *info), void *info,
int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
int wait)
{
- spin_lock(&call_lock);
- __smp_call_function(func,info,nonatomic,wait);
- spin_unlock(&call_lock);
- return 0;
+ return smp_call_function_mask(cpu_online_map, func, info, wait);
}
EXPORT_SYMBOL(smp_call_function);
@@ -479,7 +486,7 @@ void smp_send_stop(void)
/* Don't deadlock on the call lock in panic */
nolock = !spin_trylock(&call_lock);
local_irq_save(flags);
- __smp_call_function(stop_this_cpu, NULL, 0, 0);
+ __smp_call_function_mask(cpu_online_map, stop_this_cpu, NULL, 0);
if (!nolock)
spin_unlock(&call_lock);
disable_local_APIC();
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index be3faac0471..ef0f34ede1a 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -67,7 +67,7 @@ int smp_num_siblings = 1;
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
/* representing HT siblings of each logical CPU */
DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
@@ -89,12 +89,20 @@ EXPORT_SYMBOL(cpu_possible_map);
static cpumask_t smp_commenced_mask;
/* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
-u8 x86_cpu_to_apicid[NR_CPUS] __read_mostly =
- { [0 ... NR_CPUS-1] = 0xff };
-EXPORT_SYMBOL(x86_cpu_to_apicid);
+/*
+ * The following static array is used during kernel startup
+ * and the x86_cpu_to_apicid_ptr contains the address of the
+ * array during this time. Is it zeroed when the per_cpu
+ * data area is removed.
+ */
+u8 x86_cpu_to_apicid_init[NR_CPUS] __initdata =
+ { [0 ... NR_CPUS-1] = BAD_APICID };
+void *x86_cpu_to_apicid_ptr;
+DEFINE_PER_CPU(u8, x86_cpu_to_apicid) = BAD_APICID;
+EXPORT_PER_CPU_SYMBOL(x86_cpu_to_apicid);
u8 apicid_2_node[MAX_APICID];
@@ -150,9 +158,10 @@ void __init smp_alloc_memory(void)
void __cpuinit smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c = cpu_data + id;
+ struct cpuinfo_x86 *c = &cpu_data(id);
*c = boot_cpu_data;
+ c->cpu_index = id;
if (id!=0)
identify_secondary_cpu(c);
/*
@@ -294,7 +303,7 @@ static int cpucount;
/* maps the cpu to the sched domain representing multi-core */
cpumask_t cpu_coregroup_map(int cpu)
{
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
/*
* For perf, we return last level cache shared map.
* And for power savings, we return cpu_core_map
@@ -311,41 +320,41 @@ static cpumask_t cpu_sibling_setup_map;
void __cpuinit set_cpu_sibling_map(int cpu)
{
int i;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
cpu_set(cpu, cpu_sibling_setup_map);
if (smp_num_siblings > 1) {
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
- c[cpu].cpu_core_id == c[i].cpu_core_id) {
+ if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+ c->cpu_core_id == cpu_data(i).cpu_core_id) {
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
- cpu_set(i, c[cpu].llc_shared_map);
- cpu_set(cpu, c[i].llc_shared_map);
+ cpu_set(i, c->llc_shared_map);
+ cpu_set(cpu, cpu_data(i).llc_shared_map);
}
}
} else {
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
- cpu_set(cpu, c[cpu].llc_shared_map);
+ cpu_set(cpu, c->llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
- c[cpu].booted_cores = 1;
+ c->booted_cores = 1;
return;
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (cpu_llc_id[cpu] != BAD_APICID &&
- cpu_llc_id[cpu] == cpu_llc_id[i]) {
- cpu_set(i, c[cpu].llc_shared_map);
- cpu_set(cpu, c[i].llc_shared_map);
+ if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+ per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+ cpu_set(i, c->llc_shared_map);
+ cpu_set(cpu, cpu_data(i).llc_shared_map);
}
- if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+ if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
@@ -357,15 +366,15 @@ void __cpuinit set_cpu_sibling_map(int cpu)
* the booted_cores for this new cpu
*/
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
- c[cpu].booted_cores++;
+ c->booted_cores++;
/*
* increment the core count for all
* the other cpus in this package
*/
if (i != cpu)
- c[i].booted_cores++;
- } else if (i != cpu && !c[cpu].booted_cores)
- c[cpu].booted_cores = c[i].booted_cores;
+ cpu_data(i).booted_cores++;
+ } else if (i != cpu && !c->booted_cores)
+ c->booted_cores = cpu_data(i).booted_cores;
}
}
}
@@ -412,7 +421,7 @@ static void __cpuinit start_secondary(void *unused)
/*
* We need to hold call_lock, so there is no inconsistency
* between the time smp_call_function() determines number of
- * IPI receipients, and the time when the determination is made
+ * IPI recipients, and the time when the determination is made
* for which cpus receive the IPI. Holding this
* lock helps us to not include this cpu in a currently in progress
* smp_call_function().
@@ -804,7 +813,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
irq_ctx_init(cpu);
- x86_cpu_to_apicid[cpu] = apicid;
+ per_cpu(x86_cpu_to_apicid, cpu) = apicid;
/*
* This grunge runs the startup process for
* the targeted processor.
@@ -844,7 +853,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
/* number CPUs logically, starting from 1 (BSP is 0) */
Dprintk("OK.\n");
printk("CPU%d: ", cpu);
- print_cpu_info(&cpu_data[cpu]);
+ print_cpu_info(&cpu_data(cpu));
Dprintk("CPU has booted.\n");
} else {
boot_error= 1;
@@ -866,7 +875,7 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */
cpucount--;
} else {
- x86_cpu_to_apicid[cpu] = apicid;
+ per_cpu(x86_cpu_to_apicid, cpu) = apicid;
cpu_set(cpu, cpu_present_map);
}
@@ -915,7 +924,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu)
struct warm_boot_cpu_info info;
int apicid, ret;
- apicid = x86_cpu_to_apicid[cpu];
+ apicid = per_cpu(x86_cpu_to_apicid, cpu);
if (apicid == BAD_APICID) {
ret = -ENODEV;
goto exit;
@@ -961,11 +970,11 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
*/
smp_store_cpu_info(0); /* Final full version of the data */
printk("CPU%d: ", 0);
- print_cpu_info(&cpu_data[0]);
+ print_cpu_info(&cpu_data(0));
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
boot_cpu_logical_apicid = logical_smp_processor_id();
- x86_cpu_to_apicid[0] = boot_cpu_physical_apicid;
+ per_cpu(x86_cpu_to_apicid, 0) = boot_cpu_physical_apicid;
current_thread_info()->cpu = 0;
@@ -1008,6 +1017,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
+ map_cpu_to_logical_apicid();
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
@@ -1029,6 +1039,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
}
smpboot_clear_io_apic_irqs();
phys_cpu_present_map = physid_mask_of_physid(0);
+ map_cpu_to_logical_apicid();
cpu_set(0, per_cpu(cpu_sibling_map, 0));
cpu_set(0, per_cpu(cpu_core_map, 0));
return;
@@ -1082,7 +1093,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
Dprintk("Before bogomips.\n");
for (cpu = 0; cpu < NR_CPUS; cpu++)
if (cpu_isset(cpu, cpu_callout_map))
- bogosum += cpu_data[cpu].loops_per_jiffy;
+ bogosum += cpu_data(cpu).loops_per_jiffy;
printk(KERN_INFO
"Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
@@ -1152,7 +1163,7 @@ void __init native_smp_prepare_boot_cpu(void)
void remove_siblinginfo(int cpu)
{
int sibling;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -1160,15 +1171,15 @@ void remove_siblinginfo(int cpu)
* last thread sibling in this cpu core going down
*/
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
- c[sibling].booted_cores--;
+ cpu_data(sibling).booted_cores--;
}
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
- c[cpu].phys_proc_id = 0;
- c[cpu].cpu_core_id = 0;
+ c->phys_proc_id = 0;
+ c->cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
}
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index e351ac4ab5b..b7e768dd87c 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -65,7 +65,7 @@ int smp_num_siblings = 1;
EXPORT_SYMBOL(smp_num_siblings);
/* Last level cache ID of each logical CPU */
-u8 cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
+DEFINE_PER_CPU(u8, cpu_llc_id) = BAD_APICID;
/* Bitmask of currently online CPUs */
cpumask_t cpu_online_map __read_mostly;
@@ -84,8 +84,8 @@ cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);
/* Per CPU bogomips and other parameters */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
+EXPORT_PER_CPU_SYMBOL(cpu_info);
/* Set when the idlers are all forked */
int smp_threads_ready;
@@ -138,9 +138,10 @@ static unsigned long __cpuinit setup_trampoline(void)
static void __cpuinit smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c = cpu_data + id;
+ struct cpuinfo_x86 *c = &cpu_data(id);
*c = boot_cpu_data;
+ c->cpu_index = id;
identify_cpu(c);
print_cpu_info(c);
}
@@ -237,7 +238,7 @@ void __cpuinit smp_callin(void)
/* maps the cpu to the sched domain representing multi-core */
cpumask_t cpu_coregroup_map(int cpu)
{
- struct cpuinfo_x86 *c = cpu_data + cpu;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
/*
* For perf, we return last level cache shared map.
* And for power savings, we return cpu_core_map
@@ -254,41 +255,41 @@ static cpumask_t cpu_sibling_setup_map;
static inline void set_cpu_sibling_map(int cpu)
{
int i;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
cpu_set(cpu, cpu_sibling_setup_map);
if (smp_num_siblings > 1) {
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
- c[cpu].cpu_core_id == c[i].cpu_core_id) {
+ if (c->phys_proc_id == cpu_data(i).phys_proc_id &&
+ c->cpu_core_id == cpu_data(i).cpu_core_id) {
cpu_set(i, per_cpu(cpu_sibling_map, cpu));
cpu_set(cpu, per_cpu(cpu_sibling_map, i));
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
- cpu_set(i, c[cpu].llc_shared_map);
- cpu_set(cpu, c[i].llc_shared_map);
+ cpu_set(i, c->llc_shared_map);
+ cpu_set(cpu, cpu_data(i).llc_shared_map);
}
}
} else {
cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
}
- cpu_set(cpu, c[cpu].llc_shared_map);
+ cpu_set(cpu, c->llc_shared_map);
if (current_cpu_data.x86_max_cores == 1) {
per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
- c[cpu].booted_cores = 1;
+ c->booted_cores = 1;
return;
}
for_each_cpu_mask(i, cpu_sibling_setup_map) {
- if (cpu_llc_id[cpu] != BAD_APICID &&
- cpu_llc_id[cpu] == cpu_llc_id[i]) {
- cpu_set(i, c[cpu].llc_shared_map);
- cpu_set(cpu, c[i].llc_shared_map);
+ if (per_cpu(cpu_llc_id, cpu) != BAD_APICID &&
+ per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) {
+ cpu_set(i, c->llc_shared_map);
+ cpu_set(cpu, cpu_data(i).llc_shared_map);
}
- if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
+ if (c->phys_proc_id == cpu_data(i).phys_proc_id) {
cpu_set(i, per_cpu(cpu_core_map, cpu));
cpu_set(cpu, per_cpu(cpu_core_map, i));
/*
@@ -300,15 +301,15 @@ static inline void set_cpu_sibling_map(int cpu)
* the booted_cores for this new cpu
*/
if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
- c[cpu].booted_cores++;
+ c->booted_cores++;
/*
* increment the core count for all
* the other cpus in this package
*/
if (i != cpu)
- c[i].booted_cores++;
- } else if (i != cpu && !c[cpu].booted_cores)
- c[cpu].booted_cores = c[i].booted_cores;
+ cpu_data(i).booted_cores++;
+ } else if (i != cpu && !c->booted_cores)
+ c->booted_cores = cpu_data(i).booted_cores;
}
}
}
@@ -350,7 +351,7 @@ void __cpuinit start_secondary(void)
/*
* We need to hold call_lock, so there is no inconsistency
* between the time smp_call_function() determines number of
- * IPI receipients, and the time when the determination is made
+ * IPI recipients, and the time when the determination is made
* for which cpus receive the IPI in genapic_flat.c. Holding this
* lock helps us to not include this cpu in a currently in progress
* smp_call_function().
@@ -694,7 +695,7 @@ do_rest:
clear_node_cpumask(cpu); /* was set by numa_add_cpu */
cpu_clear(cpu, cpu_present_map);
cpu_clear(cpu, cpu_possible_map);
- x86_cpu_to_apicid[cpu] = BAD_APICID;
+ per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
return -EIO;
}
@@ -841,6 +842,26 @@ static int __init smp_sanity_check(unsigned max_cpus)
}
/*
+ * Copy apicid's found by MP_processor_info from initial array to the per cpu
+ * data area. The x86_cpu_to_apicid_init array is then expendable and the
+ * x86_cpu_to_apicid_ptr is zeroed indicating that the static array is no
+ * longer available.
+ */
+void __init smp_set_apicids(void)
+{
+ int cpu;
+
+ for_each_cpu_mask(cpu, cpu_possible_map) {
+ if (per_cpu_offset(cpu))
+ per_cpu(x86_cpu_to_apicid, cpu) =
+ x86_cpu_to_apicid_init[cpu];
+ }
+
+ /* indicate the static array will be going away soon */
+ x86_cpu_to_apicid_ptr = NULL;
+}
+
+/*
* Prepare for SMP bootup. The MP table or ACPI has been read
* earlier. Just do some sanity checking here and enable APIC mode.
*/
@@ -849,6 +870,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
nmi_watchdog_default();
current_cpu_data = boot_cpu_data;
current_thread_info()->cpu = 0; /* needed? */
+ smp_set_apicids();
set_cpu_sibling_map(0);
if (smp_sanity_check(max_cpus) < 0) {
@@ -968,7 +990,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
static void remove_siblinginfo(int cpu)
{
int sibling;
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
@@ -976,15 +998,15 @@ static void remove_siblinginfo(int cpu)
* last thread sibling in this cpu core going down
*/
if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
- c[sibling].booted_cores--;
+ cpu_data(sibling).booted_cores--;
}
for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
cpus_clear(per_cpu(cpu_sibling_map, cpu));
cpus_clear(per_cpu(cpu_core_map, cpu));
- c[cpu].phys_proc_id = 0;
- c[cpu].cpu_core_id = 0;
+ c->phys_proc_id = 0;
+ c->cpu_core_id = 0;
cpu_clear(cpu, cpu_sibling_setup_map);
}
diff --git a/arch/x86/kernel/summit_32.c b/arch/x86/kernel/summit_32.c
index 91c7acc8d99..72f46340159 100644
--- a/arch/x86/kernel/summit_32.c
+++ b/arch/x86/kernel/summit_32.c
@@ -64,7 +64,7 @@ static int __init setup_pci_node_map_for_wpeg(int wpeg_num, int last_bus)
switch (rio_devs[wpeg_num]->type){
case CompatWPEG:
- /* The Compatability Winnipeg controls the 2 legacy buses,
+ /* The Compatibility Winnipeg controls the 2 legacy buses,
* the 66MHz PCI bus [2 slots] and the 2 "extra" buses in case
* a PCI-PCI bridge card is used in either slot: total 5 buses.
*/
diff --git a/arch/x86/kernel/suspend_64.c b/arch/x86/kernel/suspend_64.c
index f8fafe527ff..bc9f59c246f 100644
--- a/arch/x86/kernel/suspend_64.c
+++ b/arch/x86/kernel/suspend_64.c
@@ -32,9 +32,9 @@ void __save_processor_state(struct saved_context *ctxt)
/*
* descriptor tables
*/
- asm volatile ("sgdt %0" : "=m" (ctxt->gdt_limit));
- asm volatile ("sidt %0" : "=m" (ctxt->idt_limit));
- asm volatile ("str %0" : "=m" (ctxt->tr));
+ store_gdt((struct desc_ptr *)&ctxt->gdt_limit);
+ store_idt((struct desc_ptr *)&ctxt->idt_limit);
+ store_tr(ctxt->tr);
/* XMM0..XMM15 should be handled by kernel_fpu_begin(). */
/*
@@ -91,8 +91,9 @@ void __restore_processor_state(struct saved_context *ctxt)
* now restore the descriptor tables to their proper values
* ltr is done i fix_processor_context().
*/
- asm volatile ("lgdt %0" :: "m" (ctxt->gdt_limit));
- asm volatile ("lidt %0" :: "m" (ctxt->idt_limit));
+ load_gdt((const struct desc_ptr *)&ctxt->gdt_limit);
+ load_idt((const struct desc_ptr *)&ctxt->idt_limit);
+
/*
* segment registers
@@ -123,7 +124,7 @@ void fix_processor_context(void)
int cpu = smp_processor_id();
struct tss_struct *t = &per_cpu(init_tss, cpu);
- set_tss_desc(cpu,t); /* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
+ set_tss_desc(cpu,t); /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
cpu_gdt(cpu)[GDT_ENTRY_TSS].type = 9;
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index b132d3957df..cc9acace7e2 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -63,6 +63,9 @@
int panic_on_unrecovered_nmi;
+DECLARE_BITMAP(used_vectors, NR_VECTORS);
+EXPORT_SYMBOL_GPL(used_vectors);
+
asmlinkage int system_call(void);
/* Do we ignore FPU interrupts ? */
@@ -288,48 +291,24 @@ EXPORT_SYMBOL(dump_stack);
void show_registers(struct pt_regs *regs)
{
int i;
- int in_kernel = 1;
- unsigned long esp;
- unsigned short ss, gs;
-
- esp = (unsigned long) (&regs->esp);
- savesegment(ss, ss);
- savesegment(gs, gs);
- if (user_mode_vm(regs)) {
- in_kernel = 0;
- esp = regs->esp;
- ss = regs->xss & 0xffff;
- }
+
print_modules();
- printk(KERN_EMERG "CPU: %d\n"
- KERN_EMERG "EIP: %04x:[<%08lx>] %s VLI\n"
- KERN_EMERG "EFLAGS: %08lx (%s %.*s)\n",
- smp_processor_id(), 0xffff & regs->xcs, regs->eip,
- print_tainted(), regs->eflags, init_utsname()->release,
- (int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
- print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip);
- printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n",
- regs->eax, regs->ebx, regs->ecx, regs->edx);
- printk(KERN_EMERG "esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n",
- regs->esi, regs->edi, regs->ebp, esp);
- printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n",
- regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss);
+ __show_registers(regs, 0);
printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)",
- TASK_COMM_LEN, current->comm, current->pid,
+ TASK_COMM_LEN, current->comm, task_pid_nr(current),
current_thread_info(), current, task_thread_info(current));
/*
* When in-kernel, we also print out the stack and code at the
* time of the fault..
*/
- if (in_kernel) {
+ if (!user_mode_vm(regs)) {
u8 *eip;
unsigned int code_prologue = code_bytes * 43 / 64;
unsigned int code_len = code_bytes;
unsigned char c;
printk("\n" KERN_EMERG "Stack: ");
- show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
+ show_stack_log_lvl(NULL, regs, &regs->esp, KERN_EMERG);
printk(KERN_EMERG "Code: ");
@@ -374,11 +353,11 @@ int is_valid_bugaddr(unsigned long eip)
void die(const char * str, struct pt_regs * regs, long err)
{
static struct {
- spinlock_t lock;
+ raw_spinlock_t lock;
u32 lock_owner;
int lock_owner_depth;
} die = {
- .lock = __SPIN_LOCK_UNLOCKED(die.lock),
+ .lock = __RAW_SPIN_LOCK_UNLOCKED,
.lock_owner = -1,
.lock_owner_depth = 0
};
@@ -389,13 +368,14 @@ void die(const char * str, struct pt_regs * regs, long err)
if (die.lock_owner != raw_smp_processor_id()) {
console_verbose();
- spin_lock_irqsave(&die.lock, flags);
+ __raw_spin_lock(&die.lock);
+ raw_local_save_flags(flags);
die.lock_owner = smp_processor_id();
die.lock_owner_depth = 0;
bust_spinlocks(1);
}
else
- local_save_flags(flags);
+ raw_local_save_flags(flags);
if (++die.lock_owner_depth < 3) {
unsigned long esp;
@@ -439,7 +419,8 @@ void die(const char * str, struct pt_regs * regs, long err)
bust_spinlocks(0);
die.lock_owner = -1;
add_taint(TAINT_DIE);
- spin_unlock_irqrestore(&die.lock, flags);
+ __raw_spin_unlock(&die.lock);
+ raw_local_irq_restore(flags);
if (!regs)
return;
@@ -622,7 +603,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
printk_ratelimit())
printk(KERN_INFO
"%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
regs->eip, regs->esp, error_code);
force_sig(SIGSEGV, current);
@@ -1142,6 +1123,8 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
void __init trap_init(void)
{
+ int i;
+
#ifdef CONFIG_EISA
void __iomem *p = ioremap(0x0FFFD9, 4);
if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1201,6 +1184,11 @@ void __init trap_init(void)
set_system_gate(SYSCALL_VECTOR,&system_call);
+ /* Reserve all the builtin and the syscall vector. */
+ for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
+ set_bit(i, used_vectors);
+ set_bit(SYSCALL_VECTOR, used_vectors);
+
/*
* Should be a barrier for any external CPU state.
*/
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c
index b4a9b3db199..d0c2bc7ab2e 100644
--- a/arch/x86/kernel/traps_64.c
+++ b/arch/x86/kernel/traps_64.c
@@ -201,7 +201,7 @@ static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
#define MSG(txt) ops->warning(data, txt)
/*
- * x86-64 can have upto three kernel stacks:
+ * x86-64 can have up to three kernel stacks:
* process stack
* interrupt stack
* severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
@@ -462,7 +462,7 @@ void out_of_line_bug(void)
EXPORT_SYMBOL(out_of_line_bug);
#endif
-static DEFINE_SPINLOCK(die_lock);
+static raw_spinlock_t die_lock = __RAW_SPIN_LOCK_UNLOCKED;
static int die_owner = -1;
static unsigned int die_nest_count;
@@ -474,13 +474,13 @@ unsigned __kprobes long oops_begin(void)
oops_enter();
/* racy, but better than risking deadlock. */
- local_irq_save(flags);
+ raw_local_irq_save(flags);
cpu = smp_processor_id();
- if (!spin_trylock(&die_lock)) {
+ if (!__raw_spin_trylock(&die_lock)) {
if (cpu == die_owner)
/* nested oops. should stop eventually */;
else
- spin_lock(&die_lock);
+ __raw_spin_lock(&die_lock);
}
die_nest_count++;
die_owner = cpu;
@@ -494,12 +494,10 @@ void __kprobes oops_end(unsigned long flags)
die_owner = -1;
bust_spinlocks(0);
die_nest_count--;
- if (die_nest_count)
- /* We still own the lock */
- local_irq_restore(flags);
- else
+ if (!die_nest_count)
/* Nest count reaches zero, release the lock. */
- spin_unlock_irqrestore(&die_lock, flags);
+ __raw_spin_unlock(&die_lock);
+ raw_local_irq_restore(flags);
if (panic_on_oops)
panic("Fatal exception");
oops_exit();
diff --git a/arch/x86/kernel/tsc_32.c b/arch/x86/kernel/tsc_32.c
index e87a3939ed4..d78444c788a 100644
--- a/arch/x86/kernel/tsc_32.c
+++ b/arch/x86/kernel/tsc_32.c
@@ -59,7 +59,7 @@ int check_tsc_unstable(void)
}
EXPORT_SYMBOL_GPL(check_tsc_unstable);
-/* Accellerators for sched_clock()
+/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
* basic equation:
* ns = cycles / (freq / ns_per_sec)
@@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(check_tsc_unstable);
* And since SC is a constant power of two, we can convert the div
* into a shift.
*
- * We can use khz divisor instead of mhz to keep a better percision, since
+ * We can use khz divisor instead of mhz to keep a better precision, since
* cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
* (mathieu.desnoyers@polymtl.ca)
*
@@ -181,8 +181,8 @@ int recalibrate_cpu_khz(void)
if (cpu_has_tsc) {
cpu_khz = calculate_cpu_khz();
tsc_khz = cpu_khz;
- cpu_data[0].loops_per_jiffy =
- cpufreq_scale(cpu_data[0].loops_per_jiffy,
+ cpu_data(0).loops_per_jiffy =
+ cpufreq_scale(cpu_data(0).loops_per_jiffy,
cpu_khz_old, cpu_khz);
return 0;
} else
@@ -215,7 +215,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
return 0;
}
ref_freq = freq->old;
- loops_per_jiffy_ref = cpu_data[freq->cpu].loops_per_jiffy;
+ loops_per_jiffy_ref = cpu_data(freq->cpu).loops_per_jiffy;
cpu_khz_ref = cpu_khz;
}
@@ -223,7 +223,7 @@ time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
(val == CPUFREQ_POSTCHANGE && freq->old > freq->new) ||
(val == CPUFREQ_RESUMECHANGE)) {
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
- cpu_data[freq->cpu].loops_per_jiffy =
+ cpu_data(freq->cpu).loops_per_jiffy =
cpufreq_scale(loops_per_jiffy_ref,
ref_freq, freq->new);
diff --git a/arch/x86/kernel/tsc_64.c b/arch/x86/kernel/tsc_64.c
index 9f22e542c37..9c70af45b42 100644
--- a/arch/x86/kernel/tsc_64.c
+++ b/arch/x86/kernel/tsc_64.c
@@ -73,13 +73,13 @@ static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
struct cpufreq_freqs *freq = data;
unsigned long *lpj, dummy;
- if (cpu_has(&cpu_data[freq->cpu], X86_FEATURE_CONSTANT_TSC))
+ if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC))
return 0;
lpj = &dummy;
if (!(freq->flags & CPUFREQ_CONST_LOOPS))
#ifdef CONFIG_SMP
- lpj = &cpu_data[freq->cpu].loops_per_jiffy;
+ lpj = &cpu_data(freq->cpu).loops_per_jiffy;
#else
lpj = &boot_cpu_data.loops_per_jiffy;
#endif
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 585541ca1a7..ad4005c6d4a 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -48,12 +48,12 @@
({unsigned long v; \
extern char __vsyscall_0; \
asm("" : "=r" (v) : "0" (x)); \
- ((v - VSYSCALL_FIRST_PAGE) + __pa_symbol(&__vsyscall_0)); })
+ ((v - VSYSCALL_START) + __pa_symbol(&__vsyscall_0)); })
/*
* vsyscall_gtod_data contains data that is :
* - readonly from vsyscalls
- * - writen by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
+ * - written by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
* Try to keep this structure as small as possible to avoid cache line ping pongs
*/
int __vgetcpu_mode __section_vgetcpu_mode;
@@ -291,7 +291,7 @@ static void __cpuinit vsyscall_set_cpu(int cpu)
#ifdef CONFIG_NUMA
node = cpu_to_node(cpu);
#endif
- if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP))
+ if (cpu_has(&cpu_data(cpu), X86_FEATURE_RDTSCP))
write_rdtscp_aux((node << 12) | cpu);
/* Store cpu number in limit so that it can be loaded quickly
diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c
index f6edb11364d..952e7a89c2a 100644
--- a/arch/x86/lib/delay_32.c
+++ b/arch/x86/lib/delay_32.c
@@ -82,7 +82,7 @@ inline void __const_udelay(unsigned long xloops)
__asm__("mull %0"
:"=d" (xloops), "=&a" (d0)
:"1" (xloops), "0"
- (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (HZ/4)));
+ (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (HZ/4)));
__delay(++xloops);
}
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c
index 2dbebd30834..0ebbfb9e7c7 100644
--- a/arch/x86/lib/delay_64.c
+++ b/arch/x86/lib/delay_64.c
@@ -40,7 +40,8 @@ EXPORT_SYMBOL(__delay);
inline void __const_udelay(unsigned long xloops)
{
- __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1);
+ __delay(((xloops * HZ *
+ cpu_data(raw_smp_processor_id()).loops_per_jiffy) >> 32) + 1);
}
EXPORT_SYMBOL(__const_udelay);
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
index 9f38b12b4af..8bab2b2efaf 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -748,7 +748,7 @@ survive:
retval = get_user_pages(current, current->mm,
(unsigned long )to, 1, 1, 0, &pg, NULL);
- if (retval == -ENOMEM && is_init(current)) {
+ if (retval == -ENOMEM && is_global_init(current)) {
up_read(&current->mm->mmap_sem);
congestion_wait(WRITE, HZ/50);
goto survive;
diff --git a/arch/x86/mach-default/setup.c b/arch/x86/mach-default/setup.c
index 3f08010f351..0c28a071824 100644
--- a/arch/x86/mach-default/setup.c
+++ b/arch/x86/mach-default/setup.c
@@ -108,7 +108,7 @@ void __init time_init_hook(void)
* mca_nmi_hook - hook into MCA specific NMI chain
*
* Description:
- * The MCA (Microchannel Arcitecture) has an NMI chain for NMI sources
+ * The MCA (Microchannel Architecture) has an NMI chain for NMI sources
* along the MCA bus. Use this to hook into that chain if you will need
* it.
**/
@@ -131,7 +131,7 @@ static __init int no_ipi_broadcast(char *str)
return 1;
}
-__setup("no_ipi_broadcast", no_ipi_broadcast);
+__setup("no_ipi_broadcast=", no_ipi_broadcast);
static int __init print_ipi_mode(void)
{
diff --git a/arch/x86/mach-generic/default.c b/arch/x86/mach-generic/default.c
index 8685208d851..1af0cc7648f 100644
--- a/arch/x86/mach-generic/default.c
+++ b/arch/x86/mach-generic/default.c
@@ -1,5 +1,5 @@
/*
- * Default generic APIC driver. This handles upto 8 CPUs.
+ * Default generic APIC driver. This handles up to 8 CPUs.
*/
#define APIC_DEFINITION 1
#include <linux/threads.h>
diff --git a/arch/x86/mach-generic/probe.c b/arch/x86/mach-generic/probe.c
index 4121d155180..f410d3cb565 100644
--- a/arch/x86/mach-generic/probe.c
+++ b/arch/x86/mach-generic/probe.c
@@ -56,7 +56,7 @@ void __init generic_bigsmp_probe(void)
/*
* This routine is used to switch to bigsmp mode when
* - There is no apic= option specified by the user
- * - generic_apic_probe() has choosen apic_default as the sub_arch
+ * - generic_apic_probe() has chosen apic_default as the sub_arch
* - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
*/
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index e4928aa6bdf..361ac5107b3 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -36,8 +36,8 @@ static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR
/* per CPU data structure (for /proc/cpuinfo et al), visible externally
* indexed physically */
-struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
-EXPORT_SYMBOL(cpu_data);
+DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned;
+EXPORT_PER_CPU_SYMBOL(cpu_info);
/* physical ID of the CPU used to boot the system */
unsigned char boot_cpu_id;
@@ -389,7 +389,7 @@ find_smp_config(void)
/* The boot CPU must be extended */
voyager_extended_vic_processors = 1<<boot_cpu_id;
- /* initially, all of the first 8 cpu's can boot */
+ /* initially, all of the first 8 CPUs can boot */
voyager_allowed_boot_processors = 0xff;
/* set up everything for just this CPU, we can alter
* this as we start the other CPUs later */
@@ -430,7 +430,7 @@ find_smp_config(void)
void __init
smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c=&cpu_data[id];
+ struct cpuinfo_x86 *c = &cpu_data(id);
*c = boot_cpu_data;
@@ -634,7 +634,7 @@ do_boot_cpu(__u8 cpu)
cpu, smp_processor_id()));
printk("CPU%d: ", cpu);
- print_cpu_info(&cpu_data[cpu]);
+ print_cpu_info(&cpu_data(cpu));
wmb();
cpu_set(cpu, cpu_callout_map);
cpu_set(cpu, cpu_present_map);
@@ -683,7 +683,7 @@ smp_boot_cpus(void)
*/
smp_store_cpu_info(boot_cpu_id);
printk("CPU%d: ", boot_cpu_id);
- print_cpu_info(&cpu_data[boot_cpu_id]);
+ print_cpu_info(&cpu_data(boot_cpu_id));
if(is_cpu_quad()) {
/* booting on a Quad CPU */
@@ -714,7 +714,7 @@ smp_boot_cpus(void)
unsigned long bogosum = 0;
for (i = 0; i < NR_CPUS; i++)
if (cpu_isset(i, cpu_online_map))
- bogosum += cpu_data[i].loops_per_jiffy;
+ bogosum += cpu_data(i).loops_per_jiffy;
printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
bogosum/(500000/HZ),
@@ -1010,7 +1010,7 @@ static struct call_data_struct * call_data;
/* execute a thread on a new CPU. The function to be called must be
* previously set up. This is used to schedule a function for
- * execution on all CPU's - set up the function then broadcast a
+ * execution on all CPUs - set up the function then broadcast a
* function_interrupt CPI to come here on each CPU */
static void
smp_call_function_interrupt(void)
@@ -1095,7 +1095,7 @@ voyager_smp_call_function_mask (cpumask_t cpumask,
* CPI here. We don't use this actually for counting so losing
* ticks doesn't matter
*
- * FIXME: For those CPU's which actually have a local APIC, we could
+ * FIXME: For those CPUs which actually have a local APIC, we could
* try to use it to trigger this interrupt instead of having to
* broadcast the timer tick. Unfortunately, all my pentium DYADs have
* no local APIC, so I can't do this
@@ -1287,7 +1287,7 @@ smp_local_timer_interrupt(void)
/*
* We take the 'long' return path, and there every subsystem
- * grabs the apropriate locks (kernel lock/ irq lock).
+ * grabs the appropriate locks (kernel lock/ irq lock).
*
* we might want to decouple profiling from the 'long path',
* and do the profiling totally in assembly.
@@ -1759,7 +1759,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
if(cpus_addr(mask)[0] == 0)
- /* can't have no cpu's to accept the interrupt -- extremely
+ /* can't have no CPUs to accept the interrupt -- extremely
* bad things will happen */
return;
@@ -1791,7 +1791,7 @@ set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
}
/* this is magic, we now have the correct affinity maps, so
* enable the interrupt. This will send an enable CPI to
- * those cpu's who need to enable it in their local masks,
+ * those CPUs who need to enable it in their local masks,
* causing them to correct for the new affinity . If the
* interrupt is currently globally disabled, it will simply be
* disabled again as it comes in (voyager lazy disable). If
diff --git a/arch/x86/mach-voyager/voyager_thread.c b/arch/x86/mach-voyager/voyager_thread.c
index f9d59533815..50f9366c411 100644
--- a/arch/x86/mach-voyager/voyager_thread.c
+++ b/arch/x86/mach-voyager/voyager_thread.c
@@ -64,7 +64,7 @@ check_from_kernel(void)
{
if(voyager_status.switch_off) {
- /* FIXME: This should be configureable via proc */
+ /* FIXME: This should be configurable via proc */
execute("umask 600; echo 0 > /etc/initrunlvl; kill -HUP 1");
} else if(voyager_status.power_fail) {
VDEBUG(("Voyager daemon detected AC power failure\n"));
diff --git a/arch/x86/mm/boot_ioremap_32.c b/arch/x86/mm/boot_ioremap_32.c
index 4de95a17a7d..f14da2a53ec 100644
--- a/arch/x86/mm/boot_ioremap_32.c
+++ b/arch/x86/mm/boot_ioremap_32.c
@@ -10,7 +10,7 @@
/*
* We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
- * keeps that from happenning. If anyone has a better way, I'm listening.
+ * keeps that from happening. If anyone has a better way, I'm listening.
*
* boot_pte_t is defined only if this all works correctly
*/
diff --git a/arch/x86/mm/discontig_32.c b/arch/x86/mm/discontig_32.c
index 13893772cc4..fe608a45ffb 100644
--- a/arch/x86/mm/discontig_32.c
+++ b/arch/x86/mm/discontig_32.c
@@ -273,7 +273,7 @@ unsigned long __init setup_memory(void)
* When mapping a NUMA machine we allocate the node_mem_map arrays
* from node local memory. They are then mapped directly into KVA
* between zone normal and vmalloc space. Calculate the size of
- * this space and use it to adjust the boundry between ZONE_NORMAL
+ * this space and use it to adjust the boundary between ZONE_NORMAL
* and ZONE_HIGHMEM.
*/
find_max_pfn();
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index 6555c3d1437..503dfc05111 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -354,7 +354,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
- * kernel and should generate an OOPS. Unfortunatly, in the case of an
+ * kernel and should generate an OOPS. Unfortunately, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem
* we will deadlock attempting to validate the fault against the
* address space. Luckily the kernel only validly references user
@@ -362,7 +362,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
* exceptions table.
*
* As the vast majority of faults will be valid we will only perform
- * the source reference check when there is a possibilty of a deadlock.
+ * the source reference check when there is a possibility of a deadlock.
* Attempt to lock the address space, if we cannot we then validate the
* source. If this is invalid we can skip the address space check,
* thus avoiding the deadlock.
@@ -471,8 +471,8 @@ bad_area_nosemaphore:
printk_ratelimit()) {
printk("%s%s[%d]: segfault at %08lx eip %08lx "
"esp %08lx error %lx\n",
- tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
- tsk->comm, tsk->pid, address, regs->eip,
+ task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+ tsk->comm, task_pid_nr(tsk), address, regs->eip,
regs->esp, error_code);
}
tsk->thread.cr2 = address;
@@ -564,7 +564,8 @@ no_context:
* it's allocated already.
*/
if ((page >> PAGE_SHIFT) < max_low_pfn
- && (page & _PAGE_PRESENT)) {
+ && (page & _PAGE_PRESENT)
+ && !(page & _PAGE_PSE)) {
page &= PAGE_MASK;
page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
& (PTRS_PER_PTE - 1)];
@@ -587,7 +588,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(tsk)) {
+ if (is_global_init(tsk)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 5e0e54906c4..644b4f7ece1 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -169,7 +169,7 @@ void dump_pagetable(unsigned long address)
pmd = pmd_offset(pud, address);
if (bad_address(pmd)) goto bad;
printk("PMD %lx ", pmd_val(*pmd));
- if (!pmd_present(*pmd)) goto ret;
+ if (!pmd_present(*pmd) || pmd_large(*pmd)) goto ret;
pte = pte_offset_kernel(pmd, address);
if (bad_address(pte)) goto bad;
@@ -285,7 +285,6 @@ static int vmalloc_fault(unsigned long address)
return 0;
}
-static int page_fault_trace;
int show_unhandled_signals = 1;
/*
@@ -354,10 +353,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
if (likely(regs->eflags & X86_EFLAGS_IF))
local_irq_enable();
- if (unlikely(page_fault_trace))
- printk("pagefault rip:%lx rsp:%lx cs:%lu ss:%lu address %lx error %lx\n",
- regs->rip,regs->rsp,regs->cs,regs->ss,address,error_code);
-
if (unlikely(error_code & PF_RSVD))
pgtable_bad(address, regs, error_code);
@@ -378,7 +373,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
again:
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
- * kernel and should generate an OOPS. Unfortunatly, in the case of an
+ * kernel and should generate an OOPS. Unfortunately, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem
* we will deadlock attempting to validate the fault against the
* address space. Luckily the kernel only validly references user
@@ -386,7 +381,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
* exceptions table.
*
* As the vast majority of faults will be valid we will only perform
- * the source reference check when there is a possibilty of a deadlock.
+ * the source reference check when there is a possibility of a deadlock.
* Attempt to lock the address space, if we cannot we then validate the
* source. If this is invalid we can skip the address space check,
* thus avoiding the deadlock.
@@ -488,7 +483,7 @@ bad_area_nosemaphore:
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
printk_ratelimit()) {
printk(
- "%s%s[%d]: segfault at %016lx rip %016lx rsp %016lx error %lx\n",
+ "%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
tsk->comm, tsk->pid, address, regs->rip,
regs->rsp, error_code);
@@ -554,7 +549,7 @@ no_context:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
goto again;
}
@@ -621,10 +616,3 @@ void vmalloc_sync_all(void)
BUILD_BUG_ON(!(((MODULES_END - 1) & PGDIR_MASK) ==
(__START_KERNEL & PGDIR_MASK)));
}
-
-static int __init enable_pagefaulttrace(char *str)
-{
- page_fault_trace = 1;
- return 1;
-}
-__setup("pagefaulttrace", enable_pagefaulttrace);
diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c
index 5eec5e56d07..3d6926ba899 100644
--- a/arch/x86/mm/numa_64.c
+++ b/arch/x86/mm/numa_64.c
@@ -612,7 +612,7 @@ void __init init_cpu_to_node(void)
{
int i;
for (i = 0; i < NR_CPUS; i++) {
- u8 apicid = x86_cpu_to_apicid[i];
+ u8 apicid = x86_cpu_to_apicid_init[i];
if (apicid == BAD_APICID)
continue;
if (apicid_to_node[apicid] == NUMA_NO_NODE)
diff --git a/arch/x86/mm/pageattr_64.c b/arch/x86/mm/pageattr_64.c
index 8a4f65bf956..c40afbaaf93 100644
--- a/arch/x86/mm/pageattr_64.c
+++ b/arch/x86/mm/pageattr_64.c
@@ -61,10 +61,10 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
return base;
}
-static void cache_flush_page(void *adr)
+void clflush_cache_range(void *adr, int size)
{
int i;
- for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
clflush(adr+i);
}
@@ -80,7 +80,7 @@ static void flush_kernel_map(void *arg)
asm volatile("wbinvd" ::: "memory");
else list_for_each_entry(pg, l, lru) {
void *adr = page_address(pg);
- cache_flush_page(adr);
+ clflush_cache_range(adr, PAGE_SIZE);
}
__flush_tlb_all();
}
@@ -230,9 +230,14 @@ void global_flush_tlb(void)
struct page *pg, *next;
struct list_head l;
- down_read(&init_mm.mmap_sem);
+ /*
+ * Write-protect the semaphore, to exclude two contexts
+ * doing a list_replace_init() call in parallel and to
+ * exclude new additions to the deferred_pages list:
+ */
+ down_write(&init_mm.mmap_sem);
list_replace_init(&deferred_pages, &l);
- up_read(&init_mm.mmap_sem);
+ up_write(&init_mm.mmap_sem);
flush_map(&l);
diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c
index 56089ccc394..ea85172fc0c 100644
--- a/arch/x86/mm/srat_64.c
+++ b/arch/x86/mm/srat_64.c
@@ -218,7 +218,7 @@ static inline int save_add_info(void) {return 0;}
/*
* Update nodes_add and decide if to include add are in the zone.
* Both SPARSE and RESERVE need nodes_add infomation.
- * This code supports one contigious hot add area per node.
+ * This code supports one contiguous hot add area per node.
*/
static int reserve_hotadd(int node, unsigned long start, unsigned long end)
{
diff --git a/arch/x86/oprofile/backtrace.c b/arch/x86/oprofile/backtrace.c
index c049ce414f0..0ed046a187f 100644
--- a/arch/x86/oprofile/backtrace.c
+++ b/arch/x86/oprofile/backtrace.c
@@ -13,25 +13,45 @@
#include <linux/mm.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
+#include <asm/stacktrace.h>
-struct frame_head {
- struct frame_head * ebp;
- unsigned long ret;
-} __attribute__((packed));
+static void backtrace_warning_symbol(void *data, char *msg,
+ unsigned long symbol)
+{
+ /* Ignore warnings */
+}
-static struct frame_head *
-dump_kernel_backtrace(struct frame_head * head)
+static void backtrace_warning(void *data, char *msg)
{
- oprofile_add_trace(head->ret);
+ /* Ignore warnings */
+}
- /* frame pointers should strictly progress back up the stack
- * (towards higher addresses) */
- if (head >= head->ebp)
- return NULL;
+static int backtrace_stack(void *data, char *name)
+{
+ /* Yes, we want all stacks */
+ return 0;
+}
+
+static void backtrace_address(void *data, unsigned long addr)
+{
+ unsigned int *depth = data;
- return head->ebp;
+ if ((*depth)--)
+ oprofile_add_trace(addr);
}
+static struct stacktrace_ops backtrace_ops = {
+ .warning = backtrace_warning,
+ .warning_symbol = backtrace_warning_symbol,
+ .stack = backtrace_stack,
+ .address = backtrace_address,
+};
+
+struct frame_head {
+ struct frame_head *ebp;
+ unsigned long ret;
+} __attribute__((packed));
+
static struct frame_head *
dump_user_backtrace(struct frame_head * head)
{
@@ -53,72 +73,16 @@ dump_user_backtrace(struct frame_head * head)
return bufhead[0].ebp;
}
-/*
- * | | /\ Higher addresses
- * | |
- * --------------- stack base (address of current_thread_info)
- * | thread info |
- * . .
- * | stack |
- * --------------- saved regs->ebp value if valid (frame_head address)
- * . .
- * --------------- saved regs->rsp value if x86_64
- * | |
- * --------------- struct pt_regs * stored on stack if 32-bit
- * | |
- * . .
- * | |
- * --------------- %esp
- * | |
- * | | \/ Lower addresses
- *
- * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the
- * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other
- * exceptions use special stacks, maintained by the interrupt stack table
- * (IST). These stacks are set up in trap_init() in
- * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point
- * to the kernel stack; instead, it points to some location on the NMI
- * stack. On the other hand, regs->rsp is the stack pointer saved when the
- * NMI occurred. (2) For 32-bit, regs->esp is not valid because the
- * processor does not save %esp on the kernel stack when interrupts occur
- * in the kernel mode.
- */
-#ifdef CONFIG_FRAME_POINTER
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
- unsigned long headaddr = (unsigned long)head;
-#ifdef CONFIG_X86_64
- unsigned long stack = (unsigned long)regs->rsp;
-#else
- unsigned long stack = (unsigned long)regs;
-#endif
- unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
-
- return headaddr > stack && headaddr < stack_base;
-}
-#else
-/* without fp, it's just junk */
-static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs)
-{
- return 0;
-}
-#endif
-
-
void
x86_backtrace(struct pt_regs * const regs, unsigned int depth)
{
- struct frame_head *head;
-
-#ifdef CONFIG_X86_64
- head = (struct frame_head *)regs->rbp;
-#else
- head = (struct frame_head *)regs->ebp;
-#endif
+ struct frame_head *head = (struct frame_head *)frame_pointer(regs);
+ unsigned long stack = stack_pointer(regs);
if (!user_mode_vm(regs)) {
- while (depth-- && valid_kernel_stack(head, regs))
- head = dump_kernel_backtrace(head);
+ if (depth)
+ dump_trace(NULL, regs, (unsigned long *)stack,
+ &backtrace_ops, &depth);
return;
}
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index abb1aa95b97..45b605fa71d 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
@@ -29,7 +29,7 @@ struct op_msrs {
struct pt_regs;
/* The model vtable abstracts the differences between
- * various x86 CPU model's perfctr support.
+ * various x86 CPU models' perfctr support.
*/
struct op_x86_model_spec {
unsigned int const num_counters;
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index c52150fdf82..88d8f5c0ecb 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -169,7 +169,7 @@ void eisa_set_level_irq(unsigned int irq)
}
/*
- * Common IRQ routing practice: nybbles in config space,
+ * Common IRQ routing practice: nibbles in config space,
* offset by some magic constant.
*/
static unsigned int read_config_nybble(struct pci_dev *router, unsigned offset, unsigned nr)
@@ -585,7 +585,7 @@ static __init int via_router_probe(struct irq_router *r,
/* FIXME: We should move some of the quirk fixup stuff here */
/*
- * work arounds for some buggy BIOSes
+ * workarounds for some buggy BIOSes
*/
if (device == PCI_DEVICE_ID_VIA_82C586_0) {
switch(router->device) {
diff --git a/arch/x86_64/.gitignore b/arch/x86_64/.gitignore
new file mode 100644
index 00000000000..36ef4c374d2
--- /dev/null
+++ b/arch/x86_64/.gitignore
@@ -0,0 +1 @@
+boot
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 78cb68f2ebb..c2d24991bb2 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -723,7 +723,9 @@ config ARCH_HIBERNATION_HEADER
source "drivers/acpi/Kconfig"
-source "arch/x86/kernel/cpufreq/Kconfig"
+source "arch/x86/kernel/cpu/cpufreq/Kconfig_64"
+
+source "drivers/cpuidle/Kconfig"
endmenu
@@ -748,6 +750,38 @@ config PCI_DOMAINS
depends on PCI
default y
+config DMAR
+ bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
+ depends on PCI_MSI && ACPI && EXPERIMENTAL
+ default y
+ help
+ DMA remapping (DMAR) devices support enables independent address
+ translations for Direct Memory Access (DMA) from devices.
+ These DMA remapping devices are reported via ACPI tables
+ and include PCI device scope covered by these DMA
+ remapping devices.
+
+config DMAR_GFX_WA
+ bool "Support for Graphics workaround"
+ depends on DMAR
+ default y
+ help
+ Current Graphics drivers tend to use physical address
+ for DMA and avoid using DMA APIs. Setting this config
+ option permits the IOMMU driver to set a unity map for
+ all the OS-visible memory. Hence the driver can continue
+ to use physical addresses for DMA.
+
+config DMAR_FLOPPY_WA
+ bool
+ depends on DMAR
+ default y
+ help
+ Floppy disk drivers are know to bypass DMA API calls
+ thereby failing to work when IOMMU is enabled. This
+ workaround will setup a 1:1 mapping for the first
+ 16M to make floppy (an ISA device) work.
+
source "drivers/pci/pcie/Kconfig"
source "drivers/pci/Kconfig"
@@ -766,9 +800,9 @@ source "fs/Kconfig.binfmt"
config IA32_EMULATION
bool "IA32 Emulation"
help
- Include code to run 32-bit programs under a 64-bit kernel. You should likely
- turn this on, unless you're 100% sure that you don't have any 32-bit programs
- left.
+ Include code to run 32-bit programs under a 64-bit kernel. You should
+ likely turn this on, unless you're 100% sure that you don't have any
+ 32-bit programs left.
config IA32_AOUT
tristate "IA32 a.out support"
@@ -799,21 +833,6 @@ source "drivers/firmware/Kconfig"
source fs/Kconfig
-menu "Instrumentation Support"
-
-source "arch/x86/oprofile/Kconfig"
-
-config KPROBES
- bool "Kprobes"
- depends on KALLSYMS && MODULES
- help
- Kprobes allows you to trap at almost any kernel address and
- execute a callback function. register_kprobe() establishes
- a probepoint and specifies the callback. Kprobes is useful
- for kernel debugging, non-intrusive instrumentation and testing.
- If in doubt, say "N".
-endmenu
-
source "arch/x86_64/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 03e1ede27b8..6d89ab762ff 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -74,7 +74,7 @@ KBUILD_CFLAGS += $(cflags-y)
CFLAGS_KERNEL += $(cflags-kernel-y)
KBUILD_AFLAGS += -m64
-head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task_64.o
+head-y := arch/x86/kernel/head_64.o arch/x86/kernel/head64.o arch/x86/kernel/init_task.o
libs-y += arch/x86/lib/
core-y += arch/x86/kernel/ \
@@ -97,9 +97,9 @@ BOOTIMAGE := arch/x86/boot/bzImage
KBUILD_IMAGE := $(BOOTIMAGE)
bzImage: vmlinux
- $(Q)mkdir -p $(objtree)/arch/x86_64/boot
- $(Q)ln -fsn $(objtree)/arch/x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
$(Q)$(MAKE) $(build)=$(boot) $(BOOTIMAGE)
+ $(Q)mkdir -p $(objtree)/arch/x86_64/boot
+ $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/x86_64/boot/bzImage
bzlilo: vmlinux
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) zlilo
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 7fbb44bea37..85ffbb49149 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -251,6 +251,8 @@ config EMBEDDED_RAMDISK_IMAGE
provide one yourself.
endmenu
+source "kernel/Kconfig.instrumentation"
+
source "arch/xtensa/Kconfig.debug"
source "security/Kconfig"
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 9c5185f605b..40aa55b485b 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -8,7 +8,8 @@
#
-EXTRA_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
+# KBUILD_CFLAGS used when building rest of boot (takes effect recursively)
+KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include
HOSTFLAGS += -Iarch/$(ARCH)/boot/include
BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#")
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 8be99c777d9..397bcd6ad08 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -176,7 +176,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause)
printk("Caught unhandled exception in '%s' "
"(pid = %d, pc = %#010lx) - should not happen\n"
"\tEXCCAUSE is %ld\n",
- current->comm, current->pid, regs->pc, exccause);
+ current->comm, task_pid_nr(current), regs->pc, exccause);
force_sig(SIGILL, current);
}
@@ -228,7 +228,7 @@ do_illegal_instruction(struct pt_regs *regs)
/* If in user mode, send SIGILL signal to current process. */
printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n",
- current->comm, current->pid, regs->pc);
+ current->comm, task_pid_nr(current), regs->pc);
force_sig(SIGILL, current);
}
@@ -254,7 +254,7 @@ do_unaligned_user (struct pt_regs *regs)
current->thread.error_code = -3;
printk("Unaligned memory access to %08lx in '%s' "
"(pid = %d, pc = %#010lx)\n",
- regs->excvaddr, current->comm, current->pid, regs->pc);
+ regs->excvaddr, current->comm, task_pid_nr(current), regs->pc);
info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRALN;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 2f842859948..33f366be323 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -145,7 +145,7 @@ bad_area:
*/
out_of_memory:
up_read(&mm->mmap_sem);
- if (is_init(current)) {
+ if (is_global_init(current)) {
yield();
down_read(&mm->mmap_sem);
goto survive;
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c
index f09962fa98c..b61fb36674e 100644
--- a/arch/xtensa/platform-iss/network.c
+++ b/arch/xtensa/platform-iss/network.c
@@ -798,7 +798,7 @@ static int iss_net_setup(char *str)
#undef ERR
-__setup("eth", iss_net_setup);
+__setup("eth=", iss_net_setup);
/*
* Initialize all ISS Ethernet devices previously registered in iss_net_setup.
diff --git a/block/elevator.c b/block/elevator.c
index 952aee04a68..446aea2a3cf 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -390,7 +390,7 @@ EXPORT_SYMBOL(elv_rb_find);
/*
* Insert rq into dispatch queue of q. Queue lock must be held on
- * entry. rq is sort insted into the dispatch queue. To be used by
+ * entry. rq is sort instead into the dispatch queue. To be used by
* specific elevators.
*/
void elv_dispatch_sort(struct request_queue *q, struct request *rq)
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 3935469e366..61c2e396f2f 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1354,8 +1354,9 @@ new_segment:
else
sg = sg_next(sg);
- memset(sg, 0, sizeof(*sg));
- sg->page = bvec->bv_page;
+ sg_dma_len(sg) = 0;
+ sg_dma_address(sg) = 0;
+ sg_set_page(sg, bvec->bv_page);
sg->length = nbytes;
sg->offset = bvec->bv_offset;
nsegs++;
@@ -1363,6 +1364,9 @@ new_segment:
bvprv = bvec;
} /* segments in rq */
+ if (sg)
+ __sg_mark_end(sg);
+
return nsegs;
}
@@ -3367,7 +3371,7 @@ void submit_bio(int rw, struct bio *bio)
if (unlikely(block_dump)) {
char b[BDEVNAME_SIZE];
printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
(rw & WRITE) ? "WRITE" : "READ",
(unsigned long long)bio->bi_sector,
bdevname(bio->bi_bdev,b));
@@ -3739,7 +3743,7 @@ EXPORT_SYMBOL(end_dequeued_request);
/**
* end_request - end I/O on the current segment of the request
- * @rq: the request being processed
+ * @req: the request being processed
* @uptodate: error value or 0/1 uptodate flag
*
* Description:
diff --git a/crypto/api.c b/crypto/api.c
index 4ccc5af6c26..1f5c7247735 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -6,7 +6,7 @@
* Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
*
* Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mller.
+ * and Nettle, by Niels Möller.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/crypto/digest.c b/crypto/digest.c
index e56de6748b1..8871dec8cae 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -41,7 +41,7 @@ static int update2(struct hash_desc *desc,
return 0;
for (;;) {
- struct page *pg = sg->page;
+ struct page *pg = sg_page(sg);
unsigned int offset = sg->offset;
unsigned int l = sg->length;
diff --git a/crypto/fcrypt.c b/crypto/fcrypt.c
index 9c2bb535b09..d161949fdb9 100644
--- a/crypto/fcrypt.c
+++ b/crypto/fcrypt.c
@@ -10,7 +10,7 @@
*
* Based on code:
*
- * Copyright (c) 1995 - 2000 Kungliga Tekniska Hgskolan
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
diff --git a/crypto/hmac.c b/crypto/hmac.c
index 8802fb6dd5a..e4eb6ac53b5 100644
--- a/crypto/hmac.c
+++ b/crypto/hmac.c
@@ -159,7 +159,8 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
sg_set_buf(sg1, ipad, bs);
- sg1[1].page = (void *)sg;
+
+ sg_set_page(&sg[1], (void *) sg);
sg1[1].length = 0;
sg_set_buf(sg2, opad, bs + ds);
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index d6852c33cfb..b9bbda0bb9f 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -54,7 +54,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
if (out) {
struct page *page;
- page = walk->sg->page + ((walk->offset - 1) >> PAGE_SHIFT);
+ page = sg_page(walk->sg) + ((walk->offset - 1) >> PAGE_SHIFT);
flush_dcache_page(page);
}
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 9c73e37a42c..87ed681cceb 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -22,13 +22,13 @@
static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
{
- return (++sg)->length ? sg : (void *)sg->page;
+ return (++sg)->length ? sg : (void *) sg_page(sg);
}
static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
struct scatter_walk *walk_out)
{
- return !(((walk_in->sg->page - walk_out->sg->page) << PAGE_SHIFT) +
+ return !(((sg_page(walk_in->sg) - sg_page(walk_out->sg)) << PAGE_SHIFT) +
(int)(walk_in->offset - walk_out->offset));
}
@@ -60,7 +60,7 @@ static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk,
static inline struct page *scatterwalk_page(struct scatter_walk *walk)
{
- return walk->sg->page + (walk->offset >> PAGE_SHIFT);
+ return sg_page(walk->sg) + (walk->offset >> PAGE_SHIFT);
}
static inline void scatterwalk_unmap(void *vaddr, int out)
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c
index 18d489c8b93..d741c63af42 100644
--- a/crypto/tcrypt.c
+++ b/crypto/tcrypt.c
@@ -317,7 +317,7 @@ static void test_cipher(char *algo, int enc,
goto out;
}
- q = kmap(sg[0].page) + sg[0].offset;
+ q = kmap(sg_page(&sg[0])) + sg[0].offset;
hexdump(q, cipher_tv[i].rlen);
printk("%s\n",
@@ -390,7 +390,7 @@ static void test_cipher(char *algo, int enc,
temp = 0;
for (k = 0; k < cipher_tv[i].np; k++) {
printk("page %u\n", k);
- q = kmap(sg[k].page) + sg[k].offset;
+ q = kmap(sg_page(&sg[k])) + sg[k].offset;
hexdump(q, cipher_tv[i].tap[k]);
printk("%s\n",
memcmp(q, cipher_tv[i].result + temp,
diff --git a/crypto/xcbc.c b/crypto/xcbc.c
index 9f502b86e0e..ac68f3b62fd 100644
--- a/crypto/xcbc.c
+++ b/crypto/xcbc.c
@@ -120,7 +120,7 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc,
do {
- struct page *pg = sg[i].page;
+ struct page *pg = sg_page(&sg[i]);
unsigned int offset = sg[i].offset;
unsigned int slen = sg[i].length;
diff --git a/drivers/Makefile b/drivers/Makefile
index d2dc01cc73e..cfe38ffff28 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_MCA) += mca/
obj-$(CONFIG_EISA) += eisa/
obj-$(CONFIG_LGUEST_GUEST) += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
+obj-$(CONFIG_CPU_IDLE) += cpuidle/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_NEW_LEDS) += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 4875f0149eb..5d0e26a5c34 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -52,7 +52,7 @@ config ACPI_PROCFS
depends on PROC_FS
---help---
For backwards compatibility, this option allows
- depricated /proc/acpi/ files to exist, even when
+ deprecated /proc/acpi/ files to exist, even when
they have been replaced by functions in /sys.
The deprecated files (and their replacements) include:
@@ -88,7 +88,7 @@ config ACPI_PROC_EVENT
config ACPI_AC
tristate "AC Adapter"
- depends on X86
+ depends on X86 && POWER_SUPPLY
default y
help
This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +97,7 @@ config ACPI_AC
config ACPI_BATTERY
tristate "Battery"
- depends on X86
+ depends on X86 && POWER_SUPPLY
default y
help
This driver adds support for battery information through
@@ -117,6 +117,7 @@ config ACPI_BUTTON
config ACPI_VIDEO
tristate "Video"
depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL
+ depends on INPUT
help
This driver implement the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
@@ -349,12 +350,11 @@ config ACPI_HOTPLUG_MEMORY
$>modprobe acpi_memhotplug
config ACPI_SBS
- tristate "Smart Battery System (EXPERIMENTAL)"
+ tristate "Smart Battery System"
depends on X86
- depends on EXPERIMENTAL
+ depends on POWER_SUPPLY
help
- This driver adds support for the Smart Battery System.
- A "Smart Battery" is quite old and quite rare compared
- to today's ACPI "Control Method" battery.
+ This driver adds support for the Smart Battery System, another
+ type of access to battery information, found on some laptops.
endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index d4336f1730e..54e3ab0e5fc 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
obj-y += cm_sbs.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
+obj-$(CONFIG_ACPI_SBS) += sbshc.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 26d70702b31..e03de37a750 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -29,6 +29,7 @@
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/power_supply.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
@@ -72,16 +73,37 @@ static struct acpi_driver acpi_ac_driver = {
};
struct acpi_ac {
+ struct power_supply charger;
struct acpi_device * device;
unsigned long state;
};
+#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger);
+
static const struct file_operations acpi_ac_fops = {
.open = acpi_ac_open_fs,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
+static int get_ac_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct acpi_ac *ac = to_acpi_ac(psy);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = ac->state;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static enum power_supply_property ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
/* --------------------------------------------------------------------------
AC Adapter Management
@@ -208,6 +230,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
acpi_bus_generate_netlink_event(device->pnp.device_class,
device->dev.bus_id, event,
(u32) ac->state);
+ kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
break;
default:
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -244,7 +267,12 @@ static int acpi_ac_add(struct acpi_device *device)
result = acpi_ac_add_fs(device);
if (result)
goto end;
-
+ ac->charger.name = acpi_device_bid(device);
+ ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
+ ac->charger.properties = ac_props;
+ ac->charger.num_properties = ARRAY_SIZE(ac_props);
+ ac->charger.get_property = get_ac_property;
+ power_supply_register(&ac->device->dev, &ac->charger);
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY, acpi_ac_notify,
ac);
@@ -279,7 +307,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY, acpi_ac_notify);
-
+ if (ac->charger.dev)
+ power_supply_unregister(&ac->charger);
acpi_ac_remove_fs(device);
kfree(ac);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 9b2c0f74f86..681e26b56b1 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -1,6 +1,8 @@
/*
- * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $)
+ * battery.c - ACPI Battery Driver (Revision: 2.0)
*
+ * Copyright (C) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ * Copyright (C) 2004-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
*
@@ -27,244 +29,288 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
+#include <linux/jiffies.h>
+
+#ifdef CONFIG_ACPI_PROCFS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
+#endif
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
+#include <linux/power_supply.h>
-#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS"
-#define ACPI_BATTERY_FORMAT_BST "NNNN"
+#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
#define ACPI_BATTERY_COMPONENT 0x00040000
#define ACPI_BATTERY_CLASS "battery"
#define ACPI_BATTERY_DEVICE_NAME "Battery"
#define ACPI_BATTERY_NOTIFY_STATUS 0x80
#define ACPI_BATTERY_NOTIFY_INFO 0x81
-#define ACPI_BATTERY_UNITS_WATTS "mW"
-#define ACPI_BATTERY_UNITS_AMPS "mA"
#define _COMPONENT ACPI_BATTERY_COMPONENT
-#define ACPI_BATTERY_UPDATE_TIME 0
-
-#define ACPI_BATTERY_NONE_UPDATE 0
-#define ACPI_BATTERY_EASY_UPDATE 1
-#define ACPI_BATTERY_INIT_UPDATE 2
-
ACPI_MODULE_NAME("battery");
MODULE_AUTHOR("Paul Diefenbaugh");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
MODULE_DESCRIPTION("ACPI Battery Driver");
MODULE_LICENSE("GPL");
-static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME;
-
-/* 0 - every time, > 0 - by update_time */
-module_param(update_time, uint, 0644);
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
+#ifdef CONFIG_ACPI_PROCFS
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
-static int acpi_battery_add(struct acpi_device *device);
-static int acpi_battery_remove(struct acpi_device *device, int type);
-static int acpi_battery_resume(struct acpi_device *device);
+enum acpi_battery_files {
+ info_tag = 0,
+ state_tag,
+ alarm_tag,
+ ACPI_BATTERY_NUMFILES,
+};
+
+#endif
static const struct acpi_device_id battery_device_ids[] = {
{"PNP0C0A", 0},
{"", 0},
};
-MODULE_DEVICE_TABLE(acpi, battery_device_ids);
-
-static struct acpi_driver acpi_battery_driver = {
- .name = "battery",
- .class = ACPI_BATTERY_CLASS,
- .ids = battery_device_ids,
- .ops = {
- .add = acpi_battery_add,
- .resume = acpi_battery_resume,
- .remove = acpi_battery_remove,
- },
-};
-struct acpi_battery_state {
- acpi_integer state;
- acpi_integer present_rate;
- acpi_integer remaining_capacity;
- acpi_integer present_voltage;
-};
-
-struct acpi_battery_info {
- acpi_integer power_unit;
- acpi_integer design_capacity;
- acpi_integer last_full_capacity;
- acpi_integer battery_technology;
- acpi_integer design_voltage;
- acpi_integer design_capacity_warning;
- acpi_integer design_capacity_low;
- acpi_integer battery_capacity_granularity_1;
- acpi_integer battery_capacity_granularity_2;
- acpi_string model_number;
- acpi_string serial_number;
- acpi_string battery_type;
- acpi_string oem_info;
-};
-
-enum acpi_battery_files{
- ACPI_BATTERY_INFO = 0,
- ACPI_BATTERY_STATE,
- ACPI_BATTERY_ALARM,
- ACPI_BATTERY_NUMFILES,
-};
+MODULE_DEVICE_TABLE(acpi, battery_device_ids);
-struct acpi_battery_flags {
- u8 battery_present_prev;
- u8 alarm_present;
- u8 init_update;
- u8 update[ACPI_BATTERY_NUMFILES];
- u8 power_unit;
-};
struct acpi_battery {
- struct mutex mutex;
+ struct mutex lock;
+ struct power_supply bat;
struct acpi_device *device;
- struct acpi_battery_flags flags;
- struct acpi_buffer bif_data;
- struct acpi_buffer bst_data;
- unsigned long alarm;
- unsigned long update_time[ACPI_BATTERY_NUMFILES];
+ unsigned long update_time;
+ int current_now;
+ int capacity_now;
+ int voltage_now;
+ int design_capacity;
+ int full_charge_capacity;
+ int technology;
+ int design_voltage;
+ int design_capacity_warning;
+ int design_capacity_low;
+ int capacity_granularity_1;
+ int capacity_granularity_2;
+ int alarm;
+ char model_number[32];
+ char serial_number[32];
+ char type[32];
+ char oem_info[32];
+ int state;
+ int power_unit;
+ u8 alarm_present;
};
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
inline int acpi_battery_present(struct acpi_battery *battery)
{
return battery->device->status.battery_present;
}
-inline char *acpi_battery_power_units(struct acpi_battery *battery)
-{
- if (battery->flags.power_unit)
- return ACPI_BATTERY_UNITS_AMPS;
- else
- return ACPI_BATTERY_UNITS_WATTS;
-}
-inline acpi_handle acpi_battery_handle(struct acpi_battery *battery)
+static int acpi_battery_technology(struct acpi_battery *battery)
{
- return battery->device->handle;
+ if (!strcasecmp("NiCd", battery->type))
+ return POWER_SUPPLY_TECHNOLOGY_NiCd;
+ if (!strcasecmp("NiMH", battery->type))
+ return POWER_SUPPLY_TECHNOLOGY_NiMH;
+ if (!strcasecmp("LION", battery->type))
+ return POWER_SUPPLY_TECHNOLOGY_LION;
+ if (!strcasecmp("LiP", battery->type))
+ return POWER_SUPPLY_TECHNOLOGY_LIPO;
+ return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
}
-/* --------------------------------------------------------------------------
- Battery Management
- -------------------------------------------------------------------------- */
-
-static void acpi_battery_check_result(struct acpi_battery *battery, int result)
+static int acpi_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
{
- if (!battery)
- return;
+ struct acpi_battery *battery = to_acpi_battery(psy);
- if (result) {
- battery->flags.init_update = 1;
+ if ((!acpi_battery_present(battery)) &&
+ psp != POWER_SUPPLY_PROP_PRESENT)
+ return -ENODEV;
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (battery->state & 0x01)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else if (battery->state & 0x02)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else if (battery->state == 0)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = acpi_battery_present(battery);
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = acpi_battery_technology(battery);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = battery->design_voltage * 1000;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = battery->voltage_now * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = battery->current_now * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ val->intval = battery->design_capacity * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_ENERGY_FULL:
+ val->intval = battery->full_charge_capacity * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ case POWER_SUPPLY_PROP_ENERGY_NOW:
+ val->intval = battery->capacity_now * 1000;
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = battery->model_number;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = battery->oem_info;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
}
-static int acpi_battery_extract_package(struct acpi_battery *battery,
- union acpi_object *package,
- struct acpi_buffer *format,
- struct acpi_buffer *data,
- char *package_name)
+static enum power_supply_property charge_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static enum power_supply_property energy_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_ENERGY_FULL,
+ POWER_SUPPLY_PROP_ENERGY_NOW,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+#ifdef CONFIG_ACPI_PROCFS
+inline char *acpi_battery_units(struct acpi_battery *battery)
{
- acpi_status status = AE_OK;
- struct acpi_buffer data_null = { 0, NULL };
+ return (battery->power_unit)?"mA":"mW";
+}
+#endif
- status = acpi_extract_package(package, format, &data_null);
- if (status != AE_BUFFER_OVERFLOW) {
- ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s",
- package_name));
- return -ENODEV;
- }
+/* --------------------------------------------------------------------------
+ Battery Management
+ -------------------------------------------------------------------------- */
+struct acpi_offsets {
+ size_t offset; /* offset inside struct acpi_sbs_battery */
+ u8 mode; /* int or string? */
+};
- if (data_null.length != data->length) {
- kfree(data->pointer);
- data->pointer = kzalloc(data_null.length, GFP_KERNEL);
- if (!data->pointer) {
- ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()"));
- return -ENOMEM;
- }
- data->length = data_null.length;
- }
+static struct acpi_offsets state_offsets[] = {
+ {offsetof(struct acpi_battery, state), 0},
+ {offsetof(struct acpi_battery, current_now), 0},
+ {offsetof(struct acpi_battery, capacity_now), 0},
+ {offsetof(struct acpi_battery, voltage_now), 0},
+};
- status = acpi_extract_package(package, format, data);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, status, "Extracting %s",
- package_name));
- return -ENODEV;
- }
+static struct acpi_offsets info_offsets[] = {
+ {offsetof(struct acpi_battery, power_unit), 0},
+ {offsetof(struct acpi_battery, design_capacity), 0},
+ {offsetof(struct acpi_battery, full_charge_capacity), 0},
+ {offsetof(struct acpi_battery, technology), 0},
+ {offsetof(struct acpi_battery, design_voltage), 0},
+ {offsetof(struct acpi_battery, design_capacity_warning), 0},
+ {offsetof(struct acpi_battery, design_capacity_low), 0},
+ {offsetof(struct acpi_battery, capacity_granularity_1), 0},
+ {offsetof(struct acpi_battery, capacity_granularity_2), 0},
+ {offsetof(struct acpi_battery, model_number), 1},
+ {offsetof(struct acpi_battery, serial_number), 1},
+ {offsetof(struct acpi_battery, type), 1},
+ {offsetof(struct acpi_battery, oem_info), 1},
+};
+static int extract_package(struct acpi_battery *battery,
+ union acpi_object *package,
+ struct acpi_offsets *offsets, int num)
+{
+ int i, *x;
+ union acpi_object *element;
+ if (package->type != ACPI_TYPE_PACKAGE)
+ return -EFAULT;
+ for (i = 0; i < num; ++i) {
+ if (package->package.count <= i)
+ return -EFAULT;
+ element = &package->package.elements[i];
+ if (offsets[i].mode) {
+ if (element->type != ACPI_TYPE_STRING &&
+ element->type != ACPI_TYPE_BUFFER)
+ return -EFAULT;
+ strncpy((u8 *)battery + offsets[i].offset,
+ element->string.pointer, 32);
+ } else {
+ if (element->type != ACPI_TYPE_INTEGER)
+ return -EFAULT;
+ x = (int *)((u8 *)battery + offsets[i].offset);
+ *x = element->integer.value;
+ }
+ }
return 0;
}
static int acpi_battery_get_status(struct acpi_battery *battery)
{
- int result = 0;
-
- result = acpi_bus_get_status(battery->device);
- if (result) {
+ if (acpi_bus_get_status(battery->device)) {
ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA"));
return -ENODEV;
}
- return result;
+ return 0;
}
static int acpi_battery_get_info(struct acpi_battery *battery)
{
- int result = 0;
+ int result = -EFAULT;
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF),
- ACPI_BATTERY_FORMAT_BIF
- };
- union acpi_object *package = NULL;
- struct acpi_buffer *data = NULL;
- struct acpi_battery_info *bif = NULL;
-
- battery->update_time[ACPI_BATTERY_INFO] = get_seconds();
if (!acpi_battery_present(battery))
return 0;
+ mutex_lock(&battery->lock);
+ status = acpi_evaluate_object(battery->device->handle, "_BIF",
+ NULL, &buffer);
+ mutex_unlock(&battery->lock);
- /* Evaluate _BIF */
-
- status =
- acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
- &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
return -ENODEV;
}
- package = buffer.pointer;
-
- data = &battery->bif_data;
-
- /* Extract Package Data */
-
- result =
- acpi_battery_extract_package(battery, package, &format, data,
- "_BIF");
- if (result)
- goto end;
-
- end:
-
+ result = extract_package(battery, buffer.pointer,
+ info_offsets, ARRAY_SIZE(info_offsets));
kfree(buffer.pointer);
-
- if (!result) {
- bif = data->pointer;
- battery->flags.power_unit = bif->power_unit;
- }
-
return result;
}
@@ -273,342 +319,203 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
int result = 0;
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
- struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST),
- ACPI_BATTERY_FORMAT_BST
- };
- union acpi_object *package = NULL;
- struct acpi_buffer *data = NULL;
-
- battery->update_time[ACPI_BATTERY_STATE] = get_seconds();
if (!acpi_battery_present(battery))
return 0;
- /* Evaluate _BST */
+ if (battery->update_time &&
+ time_before(jiffies, battery->update_time +
+ msecs_to_jiffies(cache_time)))
+ return 0;
+
+ mutex_lock(&battery->lock);
+ status = acpi_evaluate_object(battery->device->handle, "_BST",
+ NULL, &buffer);
+ mutex_unlock(&battery->lock);
- status =
- acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
- &buffer);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
return -ENODEV;
}
- package = buffer.pointer;
-
- data = &battery->bst_data;
-
- /* Extract Package Data */
-
- result =
- acpi_battery_extract_package(battery, package, &format, data,
- "_BST");
- if (result)
- goto end;
-
- end:
+ result = extract_package(battery, buffer.pointer,
+ state_offsets, ARRAY_SIZE(state_offsets));
+ battery->update_time = jiffies;
kfree(buffer.pointer);
-
return result;
}
-static int acpi_battery_get_alarm(struct acpi_battery *battery)
-{
- battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
- return 0;
-}
-
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
- unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
{
acpi_status status = 0;
- union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER };
struct acpi_object_list arg_list = { 1, &arg0 };
- battery->update_time[ACPI_BATTERY_ALARM] = get_seconds();
-
- if (!acpi_battery_present(battery))
+ if (!acpi_battery_present(battery)|| !battery->alarm_present)
return -ENODEV;
- if (!battery->flags.alarm_present)
- return -ENODEV;
-
- arg0.integer.value = alarm;
+ arg0.integer.value = battery->alarm;
- status =
- acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
+ mutex_lock(&battery->lock);
+ status = acpi_evaluate_object(battery->device->handle, "_BTP",
&arg_list, NULL);
+ mutex_unlock(&battery->lock);
+
if (ACPI_FAILURE(status))
return -ENODEV;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm));
-
- battery->alarm = alarm;
-
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm));
return 0;
}
static int acpi_battery_init_alarm(struct acpi_battery *battery)
{
- int result = 0;
acpi_status status = AE_OK;
acpi_handle handle = NULL;
- struct acpi_battery_info *bif = battery->bif_data.pointer;
- unsigned long alarm = battery->alarm;
/* See if alarms are supported, and if so, set default */
-
- status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle);
- if (ACPI_SUCCESS(status)) {
- battery->flags.alarm_present = 1;
- if (!alarm && bif) {
- alarm = bif->design_capacity_warning;
- }
- result = acpi_battery_set_alarm(battery, alarm);
- if (result)
- goto end;
- } else {
- battery->flags.alarm_present = 0;
+ status = acpi_get_handle(battery->device->handle, "_BTP", &handle);
+ if (ACPI_FAILURE(status)) {
+ battery->alarm_present = 0;
+ return 0;
}
-
- end:
-
- return result;
+ battery->alarm_present = 1;
+ if (!battery->alarm)
+ battery->alarm = battery->design_capacity_warning;
+ return acpi_battery_set_alarm(battery);
}
-static int acpi_battery_init_update(struct acpi_battery *battery)
+static int acpi_battery_update(struct acpi_battery *battery)
{
- int result = 0;
-
- result = acpi_battery_get_status(battery);
- if (result)
+ int saved_present = acpi_battery_present(battery);
+ int result = acpi_battery_get_status(battery);
+ if (result || !acpi_battery_present(battery))
return result;
-
- battery->flags.battery_present_prev = acpi_battery_present(battery);
-
- if (acpi_battery_present(battery)) {
+ if (saved_present != acpi_battery_present(battery) ||
+ !battery->update_time) {
+ battery->update_time = 0;
result = acpi_battery_get_info(battery);
if (result)
return result;
- result = acpi_battery_get_state(battery);
- if (result)
- return result;
-
- acpi_battery_init_alarm(battery);
- }
-
- return result;
-}
-
-static int acpi_battery_update(struct acpi_battery *battery,
- int update, int *update_result_ptr)
-{
- int result = 0;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
-
- if (!acpi_battery_present(battery)) {
- update = 1;
- }
-
- if (battery->flags.init_update) {
- result = acpi_battery_init_update(battery);
- if (result)
- goto end;
- update_result = ACPI_BATTERY_INIT_UPDATE;
- } else if (update) {
- result = acpi_battery_get_status(battery);
- if (result)
- goto end;
- if ((!battery->flags.battery_present_prev & acpi_battery_present(battery))
- || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) {
- result = acpi_battery_init_update(battery);
- if (result)
- goto end;
- update_result = ACPI_BATTERY_INIT_UPDATE;
+ if (battery->power_unit) {
+ battery->bat.properties = charge_battery_props;
+ battery->bat.num_properties =
+ ARRAY_SIZE(charge_battery_props);
} else {
- update_result = ACPI_BATTERY_EASY_UPDATE;
+ battery->bat.properties = energy_battery_props;
+ battery->bat.num_properties =
+ ARRAY_SIZE(energy_battery_props);
}
+ acpi_battery_init_alarm(battery);
}
-
- end:
-
- battery->flags.init_update = (result != 0);
-
- *update_result_ptr = update_result;
-
- return result;
-}
-
-static void acpi_battery_notify_update(struct acpi_battery *battery)
-{
- acpi_battery_get_status(battery);
-
- if (battery->flags.init_update) {
- return;
- }
-
- if ((!battery->flags.battery_present_prev &
- acpi_battery_present(battery)) ||
- (battery->flags.battery_present_prev &
- !acpi_battery_present(battery))) {
- battery->flags.init_update = 1;
- } else {
- battery->flags.update[ACPI_BATTERY_INFO] = 1;
- battery->flags.update[ACPI_BATTERY_STATE] = 1;
- battery->flags.update[ACPI_BATTERY_ALARM] = 1;
- }
+ return acpi_battery_get_state(battery);
}
/* --------------------------------------------------------------------------
FS Interface (/proc)
-------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROCFS
static struct proc_dir_entry *acpi_battery_dir;
static int acpi_battery_print_info(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
- struct acpi_battery_info *bif = NULL;
- char *units = "?";
if (result)
goto end;
- if (acpi_battery_present(battery))
- seq_printf(seq, "present: yes\n");
- else {
- seq_printf(seq, "present: no\n");
- goto end;
- }
-
- bif = battery->bif_data.pointer;
- if (!bif) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL"));
- result = -ENODEV;
+ seq_printf(seq, "present: %s\n",
+ acpi_battery_present(battery)?"yes":"no");
+ if (!acpi_battery_present(battery))
goto end;
- }
-
- /* Battery Units */
-
- units = acpi_battery_power_units(battery);
-
- if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design capacity: unknown\n");
else
seq_printf(seq, "design capacity: %d %sh\n",
- (u32) bif->design_capacity, units);
+ battery->design_capacity,
+ acpi_battery_units(battery));
- if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "last full capacity: unknown\n");
else
seq_printf(seq, "last full capacity: %d %sh\n",
- (u32) bif->last_full_capacity, units);
+ battery->full_charge_capacity,
+ acpi_battery_units(battery));
- switch ((u32) bif->battery_technology) {
- case 0:
- seq_printf(seq, "battery technology: non-rechargeable\n");
- break;
- case 1:
- seq_printf(seq, "battery technology: rechargeable\n");
- break;
- default:
- seq_printf(seq, "battery technology: unknown\n");
- break;
- }
+ seq_printf(seq, "battery technology: %srechargeable\n",
+ (!battery->technology)?"non-":"");
- if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "design voltage: unknown\n");
else
seq_printf(seq, "design voltage: %d mV\n",
- (u32) bif->design_voltage);
+ battery->design_voltage);
seq_printf(seq, "design capacity warning: %d %sh\n",
- (u32) bif->design_capacity_warning, units);
+ battery->design_capacity_warning,
+ acpi_battery_units(battery));
seq_printf(seq, "design capacity low: %d %sh\n",
- (u32) bif->design_capacity_low, units);
+ battery->design_capacity_low,
+ acpi_battery_units(battery));
seq_printf(seq, "capacity granularity 1: %d %sh\n",
- (u32) bif->battery_capacity_granularity_1, units);
+ battery->capacity_granularity_1,
+ acpi_battery_units(battery));
seq_printf(seq, "capacity granularity 2: %d %sh\n",
- (u32) bif->battery_capacity_granularity_2, units);
- seq_printf(seq, "model number: %s\n", bif->model_number);
- seq_printf(seq, "serial number: %s\n", bif->serial_number);
- seq_printf(seq, "battery type: %s\n", bif->battery_type);
- seq_printf(seq, "OEM info: %s\n", bif->oem_info);
-
+ battery->capacity_granularity_2,
+ acpi_battery_units(battery));
+ seq_printf(seq, "model number: %s\n", battery->model_number);
+ seq_printf(seq, "serial number: %s\n", battery->serial_number);
+ seq_printf(seq, "battery type: %s\n", battery->type);
+ seq_printf(seq, "OEM info: %s\n", battery->oem_info);
end:
-
if (result)
seq_printf(seq, "ERROR: Unable to read battery info\n");
-
return result;
}
static int acpi_battery_print_state(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
- struct acpi_battery_state *bst = NULL;
- char *units = "?";
if (result)
goto end;
- if (acpi_battery_present(battery))
- seq_printf(seq, "present: yes\n");
- else {
- seq_printf(seq, "present: no\n");
- goto end;
- }
-
- bst = battery->bst_data.pointer;
- if (!bst) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL"));
- result = -ENODEV;
+ seq_printf(seq, "present: %s\n",
+ acpi_battery_present(battery)?"yes":"no");
+ if (!acpi_battery_present(battery))
goto end;
- }
-
- /* Battery Units */
-
- units = acpi_battery_power_units(battery);
-
- if (!(bst->state & 0x04))
- seq_printf(seq, "capacity state: ok\n");
- else
- seq_printf(seq, "capacity state: critical\n");
- if ((bst->state & 0x01) && (bst->state & 0x02)) {
+ seq_printf(seq, "capacity state: %s\n",
+ (battery->state & 0x04)?"critical":"ok");
+ if ((battery->state & 0x01) && (battery->state & 0x02))
seq_printf(seq,
"charging state: charging/discharging\n");
- } else if (bst->state & 0x01)
+ else if (battery->state & 0x01)
seq_printf(seq, "charging state: discharging\n");
- else if (bst->state & 0x02)
+ else if (battery->state & 0x02)
seq_printf(seq, "charging state: charging\n");
- else {
+ else
seq_printf(seq, "charging state: charged\n");
- }
- if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- (u32) bst->present_rate, units);
+ battery->current_now, acpi_battery_units(battery));
- if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
else
seq_printf(seq, "remaining capacity: %d %sh\n",
- (u32) bst->remaining_capacity, units);
-
- if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN)
+ battery->capacity_now, acpi_battery_units(battery));
+ if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present voltage: unknown\n");
else
seq_printf(seq, "present voltage: %d mV\n",
- (u32) bst->present_voltage);
-
+ battery->voltage_now);
end:
-
- if (result) {
+ if (result)
seq_printf(seq, "ERROR: Unable to read battery state\n");
- }
return result;
}
@@ -616,7 +523,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
static int acpi_battery_print_alarm(struct seq_file *seq, int result)
{
struct acpi_battery *battery = seq->private;
- char *units = "?";
if (result)
goto end;
@@ -625,189 +531,121 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)
seq_printf(seq, "present: no\n");
goto end;
}
-
- /* Battery Units */
-
- units = acpi_battery_power_units(battery);
-
seq_printf(seq, "alarm: ");
if (!battery->alarm)
seq_printf(seq, "unsupported\n");
else
- seq_printf(seq, "%lu %sh\n", battery->alarm, units);
-
+ seq_printf(seq, "%u %sh\n", battery->alarm,
+ acpi_battery_units(battery));
end:
-
if (result)
seq_printf(seq, "ERROR: Unable to read battery alarm\n");
-
return result;
}
-static ssize_t
-acpi_battery_write_alarm(struct file *file,
- const char __user * buffer,
- size_t count, loff_t * ppos)
+static ssize_t acpi_battery_write_alarm(struct file *file,
+ const char __user * buffer,
+ size_t count, loff_t * ppos)
{
int result = 0;
char alarm_string[12] = { '\0' };
struct seq_file *m = file->private_data;
struct acpi_battery *battery = m->private;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
if (!battery || (count > sizeof(alarm_string) - 1))
return -EINVAL;
-
- mutex_lock(&battery->mutex);
-
- result = acpi_battery_update(battery, 1, &update_result);
if (result) {
result = -ENODEV;
goto end;
}
-
if (!acpi_battery_present(battery)) {
result = -ENODEV;
goto end;
}
-
if (copy_from_user(alarm_string, buffer, count)) {
result = -EFAULT;
goto end;
}
-
alarm_string[count] = '\0';
-
- result = acpi_battery_set_alarm(battery,
- simple_strtoul(alarm_string, NULL, 0));
- if (result)
- goto end;
-
+ battery->alarm = simple_strtol(alarm_string, NULL, 0);
+ result = acpi_battery_set_alarm(battery);
end:
-
- acpi_battery_check_result(battery, result);
-
if (!result)
- result = count;
-
- mutex_unlock(&battery->mutex);
-
+ return count;
return result;
}
typedef int(*print_func)(struct seq_file *seq, int result);
-typedef int(*get_func)(struct acpi_battery *battery);
-
-static struct acpi_read_mux {
- print_func print;
- get_func get;
-} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = {
- {.get = acpi_battery_get_info, .print = acpi_battery_print_info},
- {.get = acpi_battery_get_state, .print = acpi_battery_print_state},
- {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm},
+
+static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = {
+ acpi_battery_print_info,
+ acpi_battery_print_state,
+ acpi_battery_print_alarm,
};
static int acpi_battery_read(int fid, struct seq_file *seq)
{
struct acpi_battery *battery = seq->private;
- int result = 0;
- int update_result = ACPI_BATTERY_NONE_UPDATE;
- int update = 0;
-
- mutex_lock(&battery->mutex);
-
- update = (get_seconds() - battery->update_time[fid] >= update_time);
- update = (update | battery->flags.update[fid]);
-
- result = acpi_battery_update(battery, update, &update_result);
- if (result)
- goto end;
-
- if (update_result == ACPI_BATTERY_EASY_UPDATE) {
- result = acpi_read_funcs[fid].get(battery);
- if (result)
- goto end;
+ int result = acpi_battery_update(battery);
+ return acpi_print_funcs[fid](seq, result);
+}
+
+#define DECLARE_FILE_FUNCTIONS(_name) \
+static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \
+{ \
+ return acpi_battery_read(_name##_tag, seq); \
+} \
+static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \
+{ \
+ return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \
+}
+
+DECLARE_FILE_FUNCTIONS(info);
+DECLARE_FILE_FUNCTIONS(state);
+DECLARE_FILE_FUNCTIONS(alarm);
+
+#undef DECLARE_FILE_FUNCTIONS
+
+#define FILE_DESCRIPTION_RO(_name) \
+ { \
+ .name = __stringify(_name), \
+ .mode = S_IRUGO, \
+ .ops = { \
+ .open = acpi_battery_##_name##_open_fs, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .release = single_release, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+#define FILE_DESCRIPTION_RW(_name) \
+ { \
+ .name = __stringify(_name), \
+ .mode = S_IFREG | S_IRUGO | S_IWUSR, \
+ .ops = { \
+ .open = acpi_battery_##_name##_open_fs, \
+ .read = seq_read, \
+ .llseek = seq_lseek, \
+ .write = acpi_battery_write_##_name, \
+ .release = single_release, \
+ .owner = THIS_MODULE, \
+ }, \
}
- end:
- result = acpi_read_funcs[fid].print(seq, result);
- acpi_battery_check_result(battery, result);
- battery->flags.update[fid] = result;
- mutex_unlock(&battery->mutex);
- return result;
-}
-
-static int acpi_battery_read_info(struct seq_file *seq, void *offset)
-{
- return acpi_battery_read(ACPI_BATTERY_INFO, seq);
-}
-
-static int acpi_battery_read_state(struct seq_file *seq, void *offset)
-{
- return acpi_battery_read(ACPI_BATTERY_STATE, seq);
-}
-
-static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
-{
- return acpi_battery_read(ACPI_BATTERY_ALARM, seq);
-}
-
-static int acpi_battery_info_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_battery_read_info, PDE(inode)->data);
-}
-
-static int acpi_battery_state_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_battery_read_state, PDE(inode)->data);
-}
-
-static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
-{
- return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
-}
-
static struct battery_file {
struct file_operations ops;
mode_t mode;
char *name;
} acpi_battery_file[] = {
- {
- .name = "info",
- .mode = S_IRUGO,
- .ops = {
- .open = acpi_battery_info_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
- },
- },
- {
- .name = "state",
- .mode = S_IRUGO,
- .ops = {
- .open = acpi_battery_state_open_fs,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
- },
- },
- {
- .name = "alarm",
- .mode = S_IFREG | S_IRUGO | S_IWUSR,
- .ops = {
- .open = acpi_battery_alarm_open_fs,
- .read = seq_read,
- .write = acpi_battery_write_alarm,
- .llseek = seq_lseek,
- .release = single_release,
- .owner = THIS_MODULE,
- },
- },
+ FILE_DESCRIPTION_RO(info),
+ FILE_DESCRIPTION_RO(state),
+ FILE_DESCRIPTION_RW(alarm),
};
+#undef FILE_DESCRIPTION_RO
+#undef FILE_DESCRIPTION_RW
+
static int acpi_battery_add_fs(struct acpi_device *device)
{
struct proc_dir_entry *entry = NULL;
@@ -832,25 +670,51 @@ static int acpi_battery_add_fs(struct acpi_device *device)
entry->owner = THIS_MODULE;
}
}
-
return 0;
}
-static int acpi_battery_remove_fs(struct acpi_device *device)
+static void acpi_battery_remove_fs(struct acpi_device *device)
{
int i;
- if (acpi_device_dir(device)) {
- for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
- remove_proc_entry(acpi_battery_file[i].name,
+ if (!acpi_device_dir(device))
+ return;
+ for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i)
+ remove_proc_entry(acpi_battery_file[i].name,
acpi_device_dir(device));
- }
- remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
- acpi_device_dir(device) = NULL;
- }
- return 0;
+ remove_proc_entry(acpi_device_bid(device), acpi_battery_dir);
+ acpi_device_dir(device) = NULL;
+}
+
+#endif
+
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+ return sprintf(buf, "%d\n", battery->alarm * 1000);
+}
+
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long x;
+ struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+ if (sscanf(buf, "%ld\n", &x) == 1)
+ battery->alarm = x/1000;
+ if (acpi_battery_present(battery))
+ acpi_battery_set_alarm(battery);
+ return count;
}
+static struct device_attribute alarm_attr = {
+ .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+ .show = acpi_battery_alarm_show,
+ .store = acpi_battery_alarm_store,
+};
+
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
@@ -858,33 +722,17 @@ static int acpi_battery_remove_fs(struct acpi_device *device)
static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
{
struct acpi_battery *battery = data;
- struct acpi_device *device = NULL;
-
+ struct acpi_device *device;
if (!battery)
return;
-
device = battery->device;
-
- switch (event) {
- case ACPI_BATTERY_NOTIFY_STATUS:
- case ACPI_BATTERY_NOTIFY_INFO:
- case ACPI_NOTIFY_BUS_CHECK:
- case ACPI_NOTIFY_DEVICE_CHECK:
- device = battery->device;
- acpi_battery_notify_update(battery);
- acpi_bus_generate_proc_event(device, event,
+ acpi_battery_update(battery);
+ acpi_bus_generate_proc_event(device, event,
+ acpi_battery_present(battery));
+ acpi_bus_generate_netlink_event(device->pnp.device_class,
+ device->dev.bus_id, event,
acpi_battery_present(battery));
- acpi_bus_generate_netlink_event(device->pnp.device_class,
- device->dev.bus_id, event,
- acpi_battery_present(battery));
- break;
- default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Unsupported event [0x%x]\n", event));
- break;
- }
-
- return;
+ kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
}
static int acpi_battery_add(struct acpi_device *device)
@@ -892,33 +740,27 @@ static int acpi_battery_add(struct acpi_device *device)
int result = 0;
acpi_status status = 0;
struct acpi_battery *battery = NULL;
-
if (!device)
return -EINVAL;
-
battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL);
if (!battery)
return -ENOMEM;
-
- mutex_init(&battery->mutex);
-
- mutex_lock(&battery->mutex);
-
battery->device = device;
strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
acpi_driver_data(device) = battery;
-
- result = acpi_battery_get_status(battery);
- if (result)
- goto end;
-
- battery->flags.init_update = 1;
-
+ mutex_init(&battery->lock);
+ acpi_battery_update(battery);
+#ifdef CONFIG_ACPI_PROCFS
result = acpi_battery_add_fs(device);
if (result)
goto end;
-
+#endif
+ battery->bat.name = acpi_device_bid(device);
+ battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ battery->bat.get_property = acpi_battery_get_property;
+ result = power_supply_register(&battery->device->dev, &battery->bat);
+ result = device_create_file(battery->bat.dev, &alarm_attr);
status = acpi_install_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify, battery);
@@ -927,20 +769,16 @@ static int acpi_battery_add(struct acpi_device *device)
result = -ENODEV;
goto end;
}
-
printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",
ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device),
device->status.battery_present ? "present" : "absent");
-
end:
-
if (result) {
+#ifdef CONFIG_ACPI_PROCFS
acpi_battery_remove_fs(device);
+#endif
kfree(battery);
}
-
- mutex_unlock(&battery->mutex);
-
return result;
}
@@ -951,27 +789,19 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
if (!device || !acpi_driver_data(device))
return -EINVAL;
-
battery = acpi_driver_data(device);
-
- mutex_lock(&battery->mutex);
-
status = acpi_remove_notify_handler(device->handle,
ACPI_ALL_NOTIFY,
acpi_battery_notify);
-
+#ifdef CONFIG_ACPI_PROCFS
acpi_battery_remove_fs(device);
-
- kfree(battery->bif_data.pointer);
-
- kfree(battery->bst_data.pointer);
-
- mutex_unlock(&battery->mutex);
-
- mutex_destroy(&battery->mutex);
-
+#endif
+ if (battery->bat.dev) {
+ device_remove_file(battery->bat.dev, &alarm_attr);
+ power_supply_unregister(&battery->bat);
+ }
+ mutex_destroy(&battery->lock);
kfree(battery);
-
return 0;
}
@@ -979,44 +809,48 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
static int acpi_battery_resume(struct acpi_device *device)
{
struct acpi_battery *battery;
-
if (!device)
return -EINVAL;
-
- battery = device->driver_data;
-
- battery->flags.init_update = 1;
-
+ battery = acpi_driver_data(device);
+ battery->update_time = 0;
return 0;
}
+static struct acpi_driver acpi_battery_driver = {
+ .name = "battery",
+ .class = ACPI_BATTERY_CLASS,
+ .ids = battery_device_ids,
+ .ops = {
+ .add = acpi_battery_add,
+ .resume = acpi_battery_resume,
+ .remove = acpi_battery_remove,
+ },
+};
+
static int __init acpi_battery_init(void)
{
- int result;
-
if (acpi_disabled)
return -ENODEV;
-
+#ifdef CONFIG_ACPI_PROCFS
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
return -ENODEV;
-
- result = acpi_bus_register_driver(&acpi_battery_driver);
- if (result < 0) {
+#endif
+ if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
+#ifdef CONFIG_ACPI_PROCFS
acpi_unlock_battery_dir(acpi_battery_dir);
+#endif
return -ENODEV;
}
-
return 0;
}
static void __exit acpi_battery_exit(void)
{
acpi_bus_unregister_driver(&acpi_battery_driver);
-
+#ifdef CONFIG_ACPI_PROCFS
acpi_unlock_battery_dir(acpi_battery_dir);
-
- return;
+#endif
}
module_init(acpi_battery_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index cbfc81579c9..fb2cff9a2d2 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -286,15 +286,11 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
extern int event_is_open;
-int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
{
- struct acpi_bus_event *event = NULL;
+ struct acpi_bus_event *event;
unsigned long flags = 0;
-
- if (!device)
- return -EINVAL;
-
/* drop event on the floor if no one's listening */
if (!event_is_open)
return 0;
@@ -303,8 +299,8 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
if (!event)
return -ENOMEM;
- strcpy(event->device_class, device->pnp.device_class);
- strcpy(event->bus_id, device->pnp.bus_id);
+ strcpy(event->device_class, device_class);
+ strcpy(event->bus_id, bus_id);
event->type = type;
event->data = data;
@@ -315,6 +311,17 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
wake_up_interruptible(&acpi_bus_event_queue);
return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4);
+
+int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
+{
+ if (!device)
+ return -EINVAL;
+ return acpi_bus_generate_proc_event4(device->pnp.device_class,
+ device->pnp.bus_id, type, data);
}
EXPORT_SYMBOL(acpi_bus_generate_proc_event);
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 2e79a3395ec..301e832e696 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -434,18 +434,18 @@ static int acpi_button_add(struct acpi_device *device)
switch (button->type) {
case ACPI_BUTTON_TYPE_POWER:
case ACPI_BUTTON_TYPE_POWERF:
- input->evbit[0] = BIT(EV_KEY);
+ input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_POWER, input->keybit);
break;
case ACPI_BUTTON_TYPE_SLEEP:
case ACPI_BUTTON_TYPE_SLEEPF:
- input->evbit[0] = BIT(EV_KEY);
+ input->evbit[0] = BIT_MASK(EV_KEY);
set_bit(KEY_SLEEP, input->keybit);
break;
case ACPI_BUTTON_TYPE_LID:
- input->evbit[0] = BIT(EV_SW);
+ input->evbit[0] = BIT_MASK(EV_SW);
set_bit(SW_LID, input->swbit);
break;
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3f7935ab0cf..7b4178393e3 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -121,6 +121,7 @@ static struct acpi_ec {
atomic_t event_count;
wait_queue_head_t wait;
struct list_head list;
+ u8 handlers_installed;
} *boot_ec, *first_ec;
/* --------------------------------------------------------------------------
@@ -425,7 +426,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
handler->func = func;
handler->data = data;
mutex_lock(&ec->lock);
- list_add_tail(&handler->node, &ec->list);
+ list_add(&handler->node, &ec->list);
mutex_unlock(&ec->lock);
return 0;
}
@@ -440,7 +441,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
if (query_bit == handler->query_bit) {
list_del(&handler->node);
kfree(handler);
- break;
}
}
mutex_unlock(&ec->lock);
@@ -680,32 +680,50 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
if (ACPI_FAILURE(status))
return status;
-
/* Find and register all query methods */
acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
acpi_ec_register_query_methods, ec, NULL);
-
/* Use the global lock for all EC transactions? */
acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
ec->handle = handle;
-
- printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
- ec->gpe, ec->command_addr, ec->data_addr);
-
return AE_CTRL_TERMINATE;
}
+static void ec_remove_handlers(struct acpi_ec *ec)
+{
+ if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+ ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+ printk(KERN_ERR PREFIX "failed to remove space handler\n");
+ if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+ &acpi_ec_gpe_handler)))
+ printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
+ ec->handlers_installed = 0;
+}
+
static int acpi_ec_add(struct acpi_device *device)
{
struct acpi_ec *ec = NULL;
if (!device)
return -EINVAL;
-
strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_EC_CLASS);
+ /* Check for boot EC */
+ if (boot_ec) {
+ if (boot_ec->handle == device->handle) {
+ /* Pre-loaded EC from DSDT, just move pointer */
+ ec = boot_ec;
+ boot_ec = NULL;
+ goto end;
+ } else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
+ /* ECDT-based EC, time to shut it down */
+ ec_remove_handlers(boot_ec);
+ kfree(boot_ec);
+ first_ec = boot_ec = NULL;
+ }
+ }
+
ec = make_acpi_ec();
if (!ec)
return -ENOMEM;
@@ -715,25 +733,14 @@ static int acpi_ec_add(struct acpi_device *device)
kfree(ec);
return -EINVAL;
}
-
- /* Check if we found the boot EC */
- if (boot_ec) {
- if (boot_ec->gpe == ec->gpe) {
- /* We might have incorrect info for GL at boot time */
- mutex_lock(&boot_ec->lock);
- boot_ec->global_lock = ec->global_lock;
- /* Copy handlers from new ec into boot ec */
- list_splice(&ec->list, &boot_ec->list);
- mutex_unlock(&boot_ec->lock);
- kfree(ec);
- ec = boot_ec;
- }
- } else
- first_ec = ec;
ec->handle = device->handle;
+ end:
+ if (!first_ec)
+ first_ec = ec;
acpi_driver_data(device) = ec;
-
acpi_ec_add_fs(device);
+ printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+ ec->gpe, ec->command_addr, ec->data_addr);
return 0;
}
@@ -756,10 +763,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
acpi_driver_data(device) = NULL;
if (ec == first_ec)
first_ec = NULL;
-
- /* Don't touch boot EC */
- if (boot_ec != ec)
- kfree(ec);
+ kfree(ec);
return 0;
}
@@ -789,6 +793,8 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
static int ec_install_handlers(struct acpi_ec *ec)
{
acpi_status status;
+ if (ec->handlers_installed)
+ return 0;
status = acpi_install_gpe_handler(NULL, ec->gpe,
ACPI_GPE_EDGE_TRIGGERED,
&acpi_ec_gpe_handler, ec);
@@ -807,6 +813,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
return -ENODEV;
}
+ ec->handlers_installed = 1;
return 0;
}
@@ -823,41 +830,22 @@ static int acpi_ec_start(struct acpi_device *device)
if (!ec)
return -EINVAL;
- /* Boot EC is already working */
- if (ec != boot_ec)
- ret = ec_install_handlers(ec);
+ ret = ec_install_handlers(ec);
/* EC is fully operational, allow queries */
atomic_set(&ec->query_pending, 0);
-
return ret;
}
static int acpi_ec_stop(struct acpi_device *device, int type)
{
- acpi_status status;
struct acpi_ec *ec;
-
if (!device)
return -EINVAL;
-
ec = acpi_driver_data(device);
if (!ec)
return -EINVAL;
-
- /* Don't touch boot EC */
- if (ec == boot_ec)
- return 0;
-
- status = acpi_remove_address_space_handler(ec->handle,
- ACPI_ADR_SPACE_EC,
- &acpi_ec_space_handler);
- if (ACPI_FAILURE(status))
- return -ENODEV;
-
- status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
- if (ACPI_FAILURE(status))
- return -ENODEV;
+ ec_remove_handlers(ec);
return 0;
}
@@ -877,7 +865,7 @@ int __init acpi_ec_ecdt_probe(void)
status = acpi_get_table(ACPI_SIG_ECDT, 1,
(struct acpi_table_header **)&ecdt_ptr);
if (ACPI_SUCCESS(status)) {
- printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+ printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
boot_ec->command_addr = ecdt_ptr->control.address;
boot_ec->data_addr = ecdt_ptr->data.address;
boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +887,6 @@ int __init acpi_ec_ecdt_probe(void)
error:
kfree(boot_ec);
boot_ec = NULL;
-
return -ENODEV;
}
diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c
index a1f87b5def2..e41287815ea 100644
--- a/drivers/acpi/events/evevent.c
+++ b/drivers/acpi/events/evevent.c
@@ -239,10 +239,8 @@ u32 acpi_ev_fixed_event_detect(void)
* Read the fixed feature status and enable registers, as all the cases
* depend on their values. Ignore errors here.
*/
- (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS, &fixed_status);
- (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
+ (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status);
+ (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable);
ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS,
"Fixed Event Block: Enable %08X Status %08X\n",
diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c
index 1d371fa663f..73f9c5fb1ba 100644
--- a/drivers/acpi/hardware/hwregs.c
+++ b/drivers/acpi/hardware/hwregs.c
@@ -75,8 +75,7 @@ acpi_status acpi_hw_clear_acpi_status(void)
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -259,7 +258,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
*
******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value)
{
u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
@@ -276,8 +275,7 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
/* Read from the register */
- status = acpi_hw_register_read(ACPI_MTX_LOCK,
- bit_reg_info->parent_register,
+ status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
if (ACPI_SUCCESS(status)) {
@@ -298,6 +296,16 @@ acpi_status acpi_get_register(u32 register_id, u32 * return_value)
return_ACPI_STATUS(status);
}
+acpi_status acpi_get_register(u32 register_id, u32 * return_value)
+{
+ acpi_status status;
+ acpi_cpu_flags flags;
+ flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ status = acpi_get_register_unlocked(register_id, return_value);
+ acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+ return status;
+}
+
ACPI_EXPORT_SYMBOL(acpi_get_register)
/*******************************************************************************
@@ -335,8 +343,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
/* Always do a register read first so we can insert the new bits */
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- bit_reg_info->parent_register,
+ status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -363,8 +370,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->
access_bit_mask);
if (value) {
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
(u16) value);
register_value = 0;
}
@@ -377,8 +383,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask,
value);
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_ENABLE,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
(u16) register_value);
break;
@@ -397,15 +402,13 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
bit_reg_info->access_bit_mask,
value);
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
(u16) register_value);
break;
case ACPI_REGISTER_PM2_CONTROL:
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
&register_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
@@ -430,8 +433,7 @@ acpi_status acpi_set_register(u32 register_id, u32 value)
xpm2_control_block.
address)));
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
(u8) (register_value));
break;
@@ -461,8 +463,7 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
*
* FUNCTION: acpi_hw_register_read
*
- * PARAMETERS: use_lock - Lock hardware? True/False
- * register_id - ACPI Register ID
+ * PARAMETERS: register_id - ACPI Register ID
* return_value - Where the register value is returned
*
* RETURN: Status and the value read.
@@ -471,19 +472,14 @@ ACPI_EXPORT_SYMBOL(acpi_set_register)
*
******************************************************************************/
acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
+acpi_hw_register_read(u32 register_id, u32 * return_value)
{
u32 value1 = 0;
u32 value2 = 0;
acpi_status status;
- acpi_cpu_flags lock_flags = 0;
ACPI_FUNCTION_TRACE(hw_register_read);
- if (ACPI_MTX_LOCK == use_lock) {
- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- }
-
switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
@@ -491,7 +487,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* PM1B is optional */
@@ -507,7 +503,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
status =
acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* PM1B is optional */
@@ -523,7 +519,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
acpi_hw_low_level_read(16, &value1,
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
status =
@@ -558,10 +554,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
break;
}
- unlock_and_exit:
- if (ACPI_MTX_LOCK == use_lock) {
- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
- }
+ exit:
if (ACPI_SUCCESS(status)) {
*return_value = value1;
@@ -574,8 +567,7 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
*
* FUNCTION: acpi_hw_register_write
*
- * PARAMETERS: use_lock - Lock hardware? True/False
- * register_id - ACPI Register ID
+ * PARAMETERS: register_id - ACPI Register ID
* Value - The value to write
*
* RETURN: Status
@@ -597,28 +589,22 @@ acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value)
*
******************************************************************************/
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
+acpi_status acpi_hw_register_write(u32 register_id, u32 value)
{
acpi_status status;
- acpi_cpu_flags lock_flags = 0;
u32 read_value;
ACPI_FUNCTION_TRACE(hw_register_write);
- if (ACPI_MTX_LOCK == use_lock) {
- lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- }
-
switch (register_id) {
case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
/* Perform a read first to preserve certain bits (per ACPI spec) */
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
&read_value);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* Insert the bits to be preserved */
@@ -632,7 +618,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_event_block);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* PM1B is optional */
@@ -647,7 +633,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
status =
acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* PM1B is optional */
@@ -661,11 +647,10 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
/*
* Perform a read first to preserve certain bits (per ACPI spec)
*/
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
&read_value);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
/* Insert the bits to be preserved */
@@ -679,7 +664,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
acpi_hw_low_level_write(16, value,
&acpi_gbl_FADT.xpm1a_control_block);
if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
+ goto exit;
}
status =
@@ -728,11 +713,7 @@ acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value)
break;
}
- unlock_and_exit:
- if (ACPI_MTX_LOCK == use_lock) {
- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
- }
-
+ exit:
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index cf69c0040a3..81b24842970 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -234,15 +234,11 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
"While executing method _SST"));
}
- /*
- * 1) Disable/Clear all GPEs
- */
+ /* Disable/Clear all GPEs */
+
status = acpi_hw_disable_all_gpes();
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
- return_ACPI_STATUS(AE_OK);
+ return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
@@ -313,8 +309,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -341,15 +336,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Write #1: fill in SLP_TYP data */
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -364,15 +357,13 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -392,8 +383,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
*/
acpi_os_stall(10000000);
- status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
sleep_enable_reg_info->
access_bit_mask);
if (ACPI_FAILURE(status)) {
@@ -404,7 +394,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */
do {
- status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+ status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+ &in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -520,8 +511,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_CONTROL,
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
&PM1Acontrol);
if (ACPI_SUCCESS(status)) {
@@ -543,11 +533,9 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
/* Just ignore any errors */
- (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1A_CONTROL,
+ (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
PM1Acontrol);
- (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1B_CONTROL,
+ (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
PM1Bcontrol);
}
}
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 352cf81af58..aabc6ca4a81 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1043,14 +1043,6 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
/*
- * max_cstate is defined in the base kernel so modules can
- * change it w/o depending on the state of the processor module.
- */
-unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER;
-
-EXPORT_SYMBOL(max_cstate);
-
-/*
* Acquire a spinlock.
*
* handle is a pointer to the spinlock_t.
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 9f11dc296cd..235a51e328c 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -44,6 +44,7 @@
#include <linux/seq_file.h>
#include <linux/dmi.h>
#include <linux/moduleparam.h>
+#include <linux/cpuidle.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -421,12 +422,6 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
return 0;
}
-#ifdef CONFIG_IA64
-#define arch_cpu_to_apicid ia64_cpu_to_sapicid
-#else
-#define arch_cpu_to_apicid x86_cpu_to_apicid
-#endif
-
static int map_madt_entry(u32 acpi_id)
{
unsigned long madt_end, entry;
@@ -500,7 +495,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id)
return apic_id;
for (i = 0; i < NR_CPUS; ++i) {
- if (arch_cpu_to_apicid[i] == apic_id)
+ if (cpu_physical_id(i) == apic_id)
return i;
}
return -1;
@@ -1049,11 +1044,13 @@ static int __init acpi_processor_init(void)
return -ENOMEM;
acpi_processor_dir->owner = THIS_MODULE;
+ result = cpuidle_register_driver(&acpi_idle_driver);
+ if (result < 0)
+ goto out_proc;
+
result = acpi_bus_register_driver(&acpi_processor_driver);
- if (result < 0) {
- remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
- return result;
- }
+ if (result < 0)
+ goto out_cpuidle;
acpi_processor_install_hotplug_notify();
@@ -1062,11 +1059,18 @@ static int __init acpi_processor_init(void)
acpi_processor_ppc_init();
return 0;
+
+out_cpuidle:
+ cpuidle_unregister_driver(&acpi_idle_driver);
+
+out_proc:
+ remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
+
+ return result;
}
static void __exit acpi_processor_exit(void)
{
-
acpi_processor_ppc_exit();
acpi_thermal_cpufreq_exit();
@@ -1075,6 +1079,8 @@ static void __exit acpi_processor_exit(void)
acpi_bus_unregister_driver(&acpi_processor_driver);
+ cpuidle_unregister_driver(&acpi_idle_driver);
+
remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir);
return;
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 1f6fb38de01..f996d0e3768 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -40,6 +40,7 @@
#include <linux/sched.h> /* need_resched() */
#include <linux/latency.h>
#include <linux/clockchips.h>
+#include <linux/cpuidle.h>
/*
* Include the apic definitions for x86 to have the APIC timer related defines
@@ -64,14 +65,22 @@ ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
+#ifndef CONFIG_CPU_IDLE
#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
static void (*pm_idle_save) (void) __read_mostly;
-module_param(max_cstate, uint, 0644);
+#else
+#define C2_OVERHEAD 1 /* 1us */
+#define C3_OVERHEAD 1 /* 1us */
+#endif
+#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
+static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
+module_param(max_cstate, uint, 0000);
static unsigned int nocst __read_mostly;
module_param(nocst, uint, 0000);
+#ifndef CONFIG_CPU_IDLE
/*
* bm_history -- bit-mask with a bit per jiffy of bus-master activity
* 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms
@@ -82,9 +91,10 @@ module_param(nocst, uint, 0000);
static unsigned int bm_history __read_mostly =
(HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1));
module_param(bm_history, uint, 0644);
-/* --------------------------------------------------------------------------
- Power Management
- -------------------------------------------------------------------------- */
+
+static int acpi_processor_set_power_policy(struct acpi_processor *pr);
+
+#endif
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
@@ -177,6 +187,18 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2)
return ((0xFFFFFFFF - t1) + t2);
}
+static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
+{
+ if (t2 >= t1)
+ return PM_TIMER_TICKS_TO_US(t2 - t1);
+ else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
+ return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
+ else
+ return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
+}
+
+#ifndef CONFIG_CPU_IDLE
+
static void
acpi_processor_power_activate(struct acpi_processor *pr,
struct acpi_processor_cx *new)
@@ -248,6 +270,7 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate)
unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
}
}
+#endif /* !CONFIG_CPU_IDLE */
#ifdef ARCH_APICTIMER_STOPS_ON_C3
@@ -330,6 +353,7 @@ int acpi_processor_resume(struct acpi_device * device)
return 0;
}
+#ifndef CONFIG_CPU_IDLE
static void acpi_processor_idle(void)
{
struct acpi_processor *pr = NULL;
@@ -427,7 +451,7 @@ static void acpi_processor_idle(void)
* an SMP system. We do it here instead of doing it at _CST/P_LVL
* detection phase, to work cleanly with logical CPU hotplug.
*/
- if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
!pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
cx = &pr->power.states[ACPI_STATE_C1];
#endif
@@ -727,6 +751,7 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr)
return 0;
}
+#endif /* !CONFIG_CPU_IDLE */
static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
{
@@ -744,7 +769,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
#ifndef CONFIG_HOTPLUG_CPU
/*
* Check for P_LVL2_UP flag before entering C2 and above on
- * an SMP system.
+ * an SMP system.
*/
if ((num_online_cpus() > 1) &&
!(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
@@ -945,7 +970,12 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx)
* Normalize the C2 latency to expidite policy
*/
cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+ cx->latency_ticks = cx->latency;
+#endif
return;
}
@@ -1025,7 +1055,12 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* use this in our C3 policy
*/
cx->valid = 1;
+
+#ifndef CONFIG_CPU_IDLE
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
+#else
+ cx->latency_ticks = cx->latency;
+#endif
return;
}
@@ -1090,6 +1125,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
pr->power.count = acpi_processor_power_verify(pr);
+#ifndef CONFIG_CPU_IDLE
/*
* Set Default Policy
* ------------------
@@ -1101,6 +1137,7 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
result = acpi_processor_set_power_policy(pr);
if (result)
return result;
+#endif
/*
* if one state of type C2 or C3 is available, mark this
@@ -1117,35 +1154,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr)
return 0;
}
-int acpi_processor_cst_has_changed(struct acpi_processor *pr)
-{
- int result = 0;
-
-
- if (!pr)
- return -EINVAL;
-
- if (nocst) {
- return -ENODEV;
- }
-
- if (!pr->flags.power_setup_done)
- return -ENODEV;
-
- /* Fall back to the default idle loop */
- pm_idle = pm_idle_save;
- synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
-
- pr->flags.power = 0;
- result = acpi_processor_get_power_info(pr);
- if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
- pm_idle = acpi_processor_idle;
-
- return result;
-}
-
-/* proc interface */
-
static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
{
struct acpi_processor *pr = seq->private;
@@ -1227,6 +1235,35 @@ static const struct file_operations acpi_processor_power_fops = {
.release = single_release,
};
+#ifndef CONFIG_CPU_IDLE
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+ int result = 0;
+
+
+ if (!pr)
+ return -EINVAL;
+
+ if (nocst) {
+ return -ENODEV;
+ }
+
+ if (!pr->flags.power_setup_done)
+ return -ENODEV;
+
+ /* Fall back to the default idle loop */
+ pm_idle = pm_idle_save;
+ synchronize_sched(); /* Relies on interrupts forcing exit from idle. */
+
+ pr->flags.power = 0;
+ result = acpi_processor_get_power_info(pr);
+ if ((pr->flags.power == 1) && (pr->flags.power_setup_done))
+ pm_idle = acpi_processor_idle;
+
+ return result;
+}
+
#ifdef CONFIG_SMP
static void smp_callback(void *v)
{
@@ -1249,7 +1286,366 @@ static int acpi_processor_latency_notify(struct notifier_block *b,
static struct notifier_block acpi_processor_latency_notifier = {
.notifier_call = acpi_processor_latency_notify,
};
+
+#endif
+
+#else /* CONFIG_CPU_IDLE */
+
+/**
+ * acpi_idle_bm_check - checks if bus master activity was detected
+ */
+static int acpi_idle_bm_check(void)
+{
+ u32 bm_status = 0;
+
+ acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ if (bm_status)
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+ /*
+ * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+ * the true state of bus mastering activity; forcing us to
+ * manually check the BMIDEA bit of each IDE channel.
+ */
+ else if (errata.piix4.bmisx) {
+ if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+ || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+ bm_status = 1;
+ }
+ return bm_status;
+}
+
+/**
+ * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state
+ * @pr: the processor
+ * @target: the new target state
+ */
+static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr,
+ struct acpi_processor_cx *target)
+{
+ if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) {
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+ pr->flags.bm_rld_set = 0;
+ }
+
+ if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) {
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+ pr->flags.bm_rld_set = 1;
+ }
+}
+
+/**
+ * acpi_idle_do_entry - a helper function that does C2 and C3 type entry
+ * @cx: cstate data
+ */
+static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
+{
+ if (cx->space_id == ACPI_CSTATE_FFH) {
+ /* Call into architectural FFH based C-state */
+ acpi_processor_ffh_cstate_enter(cx);
+ } else {
+ int unused;
+ /* IO port based C-state */
+ inb(cx->address);
+ /* Dummy wait op - must do something useless after P_LVL2 read
+ because chipsets cannot guarantee that STPCLK# signal
+ gets asserted in time to freeze execution properly. */
+ unused = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ }
+}
+
+/**
+ * acpi_idle_enter_c1 - enters an ACPI C1 state-type
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * This is equivalent to the HALT instruction.
+ */
+static int acpi_idle_enter_c1(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct acpi_processor *pr;
+ struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+ pr = processors[smp_processor_id()];
+
+ if (unlikely(!pr))
+ return 0;
+
+ if (pr->flags.bm_check)
+ acpi_idle_update_bm_rld(pr, cx);
+
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we test
+ * NEED_RESCHED:
+ */
+ smp_mb();
+ if (!need_resched())
+ safe_halt();
+ current_thread_info()->status |= TS_POLLING;
+
+ cx->usage++;
+
+ return 0;
+}
+
+/**
+ * acpi_idle_enter_simple - enters an ACPI state without BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ */
+static int acpi_idle_enter_simple(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct acpi_processor *pr;
+ struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+ u32 t1, t2;
+ pr = processors[smp_processor_id()];
+
+ if (unlikely(!pr))
+ return 0;
+
+ if (acpi_idle_suspend)
+ return(acpi_idle_enter_c1(dev, state));
+
+ if (pr->flags.bm_check)
+ acpi_idle_update_bm_rld(pr, cx);
+
+ local_irq_disable();
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we test
+ * NEED_RESCHED:
+ */
+ smp_mb();
+
+ if (unlikely(need_resched())) {
+ current_thread_info()->status |= TS_POLLING;
+ local_irq_enable();
+ return 0;
+ }
+
+ if (cx->type == ACPI_STATE_C3)
+ ACPI_FLUSH_CPU_CACHE();
+
+ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ acpi_state_timer_broadcast(pr, cx, 1);
+ acpi_idle_do_entry(cx);
+ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+ /* TSC could halt in idle, so notify users */
+ mark_tsc_unstable("TSC halts in idle");;
+#endif
+
+ local_irq_enable();
+ current_thread_info()->status |= TS_POLLING;
+
+ cx->usage++;
+
+ acpi_state_timer_broadcast(pr, cx, 0);
+ cx->time += ticks_elapsed(t1, t2);
+ return ticks_elapsed_in_us(t1, t2);
+}
+
+static int c3_cpu_count;
+static DEFINE_SPINLOCK(c3_lock);
+
+/**
+ * acpi_idle_enter_bm - enters C3 with proper BM handling
+ * @dev: the target CPU
+ * @state: the state data
+ *
+ * If BM is detected, the deepest non-C3 idle state is entered instead.
+ */
+static int acpi_idle_enter_bm(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct acpi_processor *pr;
+ struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
+ u32 t1, t2;
+ pr = processors[smp_processor_id()];
+
+ if (unlikely(!pr))
+ return 0;
+
+ if (acpi_idle_suspend)
+ return(acpi_idle_enter_c1(dev, state));
+
+ local_irq_disable();
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we test
+ * NEED_RESCHED:
+ */
+ smp_mb();
+
+ if (unlikely(need_resched())) {
+ current_thread_info()->status |= TS_POLLING;
+ local_irq_enable();
+ return 0;
+ }
+
+ /*
+ * Must be done before busmaster disable as we might need to
+ * access HPET !
+ */
+ acpi_state_timer_broadcast(pr, cx, 1);
+
+ if (acpi_idle_bm_check()) {
+ cx = pr->power.bm_state;
+
+ acpi_idle_update_bm_rld(pr, cx);
+
+ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ acpi_idle_do_entry(cx);
+ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ } else {
+ acpi_idle_update_bm_rld(pr, cx);
+
+ spin_lock(&c3_lock);
+ c3_cpu_count++;
+ /* Disable bus master arbitration when all CPUs are in C3 */
+ if (c3_cpu_count == num_online_cpus())
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ spin_unlock(&c3_lock);
+
+ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ acpi_idle_do_entry(cx);
+ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+
+ spin_lock(&c3_lock);
+ /* Re-enable bus master arbitration */
+ if (c3_cpu_count == num_online_cpus())
+ acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ c3_cpu_count--;
+ spin_unlock(&c3_lock);
+ }
+
+#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
+ /* TSC could halt in idle, so notify users */
+ mark_tsc_unstable("TSC halts in idle");
+#endif
+
+ local_irq_enable();
+ current_thread_info()->status |= TS_POLLING;
+
+ cx->usage++;
+
+ acpi_state_timer_broadcast(pr, cx, 0);
+ cx->time += ticks_elapsed(t1, t2);
+ return ticks_elapsed_in_us(t1, t2);
+}
+
+struct cpuidle_driver acpi_idle_driver = {
+ .name = "acpi_idle",
+ .owner = THIS_MODULE,
+};
+
+/**
+ * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE
+ * @pr: the ACPI processor
+ */
+static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
+{
+ int i, count = 0;
+ struct acpi_processor_cx *cx;
+ struct cpuidle_state *state;
+ struct cpuidle_device *dev = &pr->power.dev;
+
+ if (!pr->flags.power_setup_done)
+ return -EINVAL;
+
+ if (pr->flags.power == 0) {
+ return -EINVAL;
+ }
+
+ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
+ cx = &pr->power.states[i];
+ state = &dev->states[count];
+
+ if (!cx->valid)
+ continue;
+
+#ifdef CONFIG_HOTPLUG_CPU
+ if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) &&
+ !pr->flags.has_cst &&
+ !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
+ continue;
#endif
+ cpuidle_set_statedata(state, cx);
+
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
+ state->exit_latency = cx->latency;
+ state->target_residency = cx->latency * 6;
+ state->power_usage = cx->power;
+
+ state->flags = 0;
+ switch (cx->type) {
+ case ACPI_STATE_C1:
+ state->flags |= CPUIDLE_FLAG_SHALLOW;
+ state->enter = acpi_idle_enter_c1;
+ break;
+
+ case ACPI_STATE_C2:
+ state->flags |= CPUIDLE_FLAG_BALANCED;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ state->enter = acpi_idle_enter_simple;
+ break;
+
+ case ACPI_STATE_C3:
+ state->flags |= CPUIDLE_FLAG_DEEP;
+ state->flags |= CPUIDLE_FLAG_TIME_VALID;
+ state->flags |= CPUIDLE_FLAG_CHECK_BM;
+ state->enter = pr->flags.bm_check ?
+ acpi_idle_enter_bm :
+ acpi_idle_enter_simple;
+ break;
+ }
+
+ count++;
+ }
+
+ dev->state_count = count;
+
+ if (!count)
+ return -EINVAL;
+
+ /* find the deepest state that can handle active BM */
+ if (pr->flags.bm_check) {
+ for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++)
+ if (pr->power.states[i].type == ACPI_STATE_C3)
+ break;
+ pr->power.bm_state = &pr->power.states[i-1];
+ }
+
+ return 0;
+}
+
+int acpi_processor_cst_has_changed(struct acpi_processor *pr)
+{
+ int ret;
+
+ if (!pr)
+ return -EINVAL;
+
+ if (nocst) {
+ return -ENODEV;
+ }
+
+ if (!pr->flags.power_setup_done)
+ return -ENODEV;
+
+ cpuidle_pause_and_lock();
+ cpuidle_disable_device(&pr->power.dev);
+ acpi_processor_get_power_info(pr);
+ acpi_processor_setup_cpuidle(pr);
+ ret = cpuidle_enable_device(&pr->power.dev);
+ cpuidle_resume_and_unlock();
+
+ return ret;
+}
+
+#endif /* CONFIG_CPU_IDLE */
int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
struct acpi_device *device)
@@ -1267,7 +1663,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
"ACPI: processor limited to max C-state %d\n",
max_cstate);
first_run++;
-#ifdef CONFIG_SMP
+#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP)
register_latency_notifier(&acpi_processor_latency_notifier);
#endif
}
@@ -1285,6 +1681,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
}
acpi_processor_get_power_info(pr);
+ pr->flags.power_setup_done = 1;
/*
* Install the idle handler if processor power management is supported.
@@ -1292,6 +1689,13 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
* platforms that only support C1.
*/
if ((pr->flags.power) && (!boot_option_idle_override)) {
+#ifdef CONFIG_CPU_IDLE
+ acpi_processor_setup_cpuidle(pr);
+ pr->power.dev.cpu = pr->id;
+ if (cpuidle_register_device(&pr->power.dev))
+ return -EIO;
+#endif
+
printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id);
for (i = 1; i <= pr->power.count; i++)
if (pr->power.states[i].valid)
@@ -1299,10 +1703,12 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
pr->power.states[i].type);
printk(")\n");
+#ifndef CONFIG_CPU_IDLE
if (pr->id == 0) {
pm_idle_save = pm_idle;
pm_idle = acpi_processor_idle;
}
+#endif
}
/* 'power' [R] */
@@ -1316,21 +1722,24 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
entry->owner = THIS_MODULE;
}
- pr->flags.power_setup_done = 1;
-
return 0;
}
int acpi_processor_power_exit(struct acpi_processor *pr,
struct acpi_device *device)
{
-
+#ifdef CONFIG_CPU_IDLE
+ if ((pr->flags.power) && (!boot_option_idle_override))
+ cpuidle_unregister_device(&pr->power.dev);
+#endif
pr->flags.power_setup_done = 0;
if (acpi_device_dir(device))
remove_proc_entry(ACPI_PROCESSOR_FILE_POWER,
acpi_device_dir(device));
+#ifndef CONFIG_CPU_IDLE
+
/* Unregister the idle handler when processor #0 is removed. */
if (pr->id == 0) {
pm_idle = pm_idle_save;
@@ -1345,6 +1754,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
unregister_latency_notifier(&acpi_processor_latency_notifier);
#endif
}
+#endif
return 0;
}
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index a578986e321..90fd09c65f9 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -1,6 +1,8 @@
/*
- * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $)
+ * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $)
*
+ * Copyright (c) 2007 Alexey Starikovskiy <astarikovskiy@suse.de>
+ * Copyright (c) 2005-2007 Vladimir Lebedev <vladimir.p.lebedev@intel.com>
* Copyright (c) 2005 Rich Townsend <rhdt@bartol.udel.edu>
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -26,15 +28,22 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
+
+#ifdef CONFIG_ACPI_PROCFS
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
+#endif
+
#include <linux/acpi.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
-#define ACPI_SBS_COMPONENT 0x00080000
+#include <linux/power_supply.h>
+
+#include "sbshc.h"
+
#define ACPI_SBS_CLASS "sbs"
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_BATTERY_CLASS "battery"
@@ -44,836 +53,436 @@
#define ACPI_SBS_FILE_ALARM "alarm"
#define ACPI_BATTERY_DIR_NAME "BAT%i"
#define ACPI_AC_DIR_NAME "AC0"
-#define ACPI_SBC_SMBUS_ADDR 0x9
-#define ACPI_SBSM_SMBUS_ADDR 0xa
-#define ACPI_SB_SMBUS_ADDR 0xb
-#define ACPI_SBS_AC_NOTIFY_STATUS 0x80
-#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80
-#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81
-#define _COMPONENT ACPI_SBS_COMPONENT
+enum acpi_sbs_device_addr {
+ ACPI_SBS_CHARGER = 0x9,
+ ACPI_SBS_MANAGER = 0xa,
+ ACPI_SBS_BATTERY = 0xb,
+};
-ACPI_MODULE_NAME("sbs");
+#define ACPI_SBS_NOTIFY_STATUS 0x80
+#define ACPI_SBS_NOTIFY_INFO 0x81
-MODULE_AUTHOR("Rich Townsend");
+MODULE_AUTHOR("Alexey Starikovskiy <astarikovskiy@suse.de>");
MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
MODULE_LICENSE("GPL");
-#define xmsleep(t) msleep(t)
-
-#define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */
-
-#define ACPI_EC_SMB_STS 0x01 /* status */
-#define ACPI_EC_SMB_ADDR 0x02 /* address */
-#define ACPI_EC_SMB_CMD 0x03 /* command */
-#define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */
-#define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */
-
-#define ACPI_EC_SMB_STS_DONE 0x80
-#define ACPI_EC_SMB_STS_STATUS 0x1f
-
-#define ACPI_EC_SMB_PRTCL_WRITE 0x00
-#define ACPI_EC_SMB_PRTCL_READ 0x01
-#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08
-#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a
-
-#define ACPI_EC_SMB_TRANSACTION_SLEEP 1
-#define ACPI_EC_SMB_ACCESS_SLEEP1 1
-#define ACPI_EC_SMB_ACCESS_SLEEP2 10
-
-#define DEF_CAPACITY_UNIT 3
-#define MAH_CAPACITY_UNIT 1
-#define MWH_CAPACITY_UNIT 2
-#define CAPACITY_UNIT DEF_CAPACITY_UNIT
-
-#define REQUEST_UPDATE_MODE 1
-#define QUEUE_UPDATE_MODE 2
-
-#define DATA_TYPE_COMMON 0
-#define DATA_TYPE_INFO 1
-#define DATA_TYPE_STATE 2
-#define DATA_TYPE_ALARM 3
-#define DATA_TYPE_AC_STATE 4
+static unsigned int cache_time = 1000;
+module_param(cache_time, uint, 0644);
+MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
extern struct proc_dir_entry *acpi_lock_ac_dir(void);
extern struct proc_dir_entry *acpi_lock_battery_dir(void);
extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
-#define MAX_SBS_BAT 4
+#define MAX_SBS_BAT 4
#define ACPI_SBS_BLOCK_MAX 32
-#define ACPI_SBS_SMBUS_READ 1
-#define ACPI_SBS_SMBUS_WRITE 2
-
-#define ACPI_SBS_WORD_DATA 1
-#define ACPI_SBS_BLOCK_DATA 2
-
-#define UPDATE_DELAY 10
-
-/* 0 - every time, > 0 - by update_time */
-static unsigned int update_time = 120;
-
-static unsigned int capacity_mode = CAPACITY_UNIT;
-
-module_param(update_time, uint, 0644);
-module_param(capacity_mode, uint, 0444);
-
-static int acpi_sbs_add(struct acpi_device *device);
-static int acpi_sbs_remove(struct acpi_device *device, int type);
-static int acpi_sbs_resume(struct acpi_device *device);
-
static const struct acpi_device_id sbs_device_ids[] = {
- {"ACPI0001", 0},
- {"ACPI0005", 0},
+ {"ACPI0002", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
-static struct acpi_driver acpi_sbs_driver = {
- .name = "sbs",
- .class = ACPI_SBS_CLASS,
- .ids = sbs_device_ids,
- .ops = {
- .add = acpi_sbs_add,
- .remove = acpi_sbs_remove,
- .resume = acpi_sbs_resume,
- },
-};
-
-struct acpi_ac {
- int ac_present;
-};
-
-struct acpi_battery_info {
- int capacity_mode;
- s16 full_charge_capacity;
- s16 design_capacity;
- s16 design_voltage;
- int vscale;
- int ipscale;
- s16 serial_number;
- char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3];
- char device_name[ACPI_SBS_BLOCK_MAX + 3];
- char device_chemistry[ACPI_SBS_BLOCK_MAX + 3];
-};
-
-struct acpi_battery_state {
- s16 voltage;
- s16 amperage;
- s16 remaining_capacity;
- s16 battery_state;
-};
-
-struct acpi_battery_alarm {
- s16 remaining_capacity;
-};
-
struct acpi_battery {
- int alive;
- int id;
- int init_state;
- int battery_present;
+ struct power_supply bat;
struct acpi_sbs *sbs;
- struct acpi_battery_info info;
- struct acpi_battery_state state;
- struct acpi_battery_alarm alarm;
- struct proc_dir_entry *battery_entry;
+#ifdef CONFIG_ACPI_PROCFS
+ struct proc_dir_entry *proc_entry;
+#endif
+ unsigned long update_time;
+ char name[8];
+ char manufacturer_name[ACPI_SBS_BLOCK_MAX];
+ char device_name[ACPI_SBS_BLOCK_MAX];
+ char device_chemistry[ACPI_SBS_BLOCK_MAX];
+ u16 alarm_capacity;
+ u16 full_charge_capacity;
+ u16 design_capacity;
+ u16 design_voltage;
+ u16 serial_number;
+ u16 cycle_count;
+ u16 temp_now;
+ u16 voltage_now;
+ s16 current_now;
+ s16 current_avg;
+ u16 capacity_now;
+ u16 state_of_charge;
+ u16 state;
+ u16 mode;
+ u16 spec;
+ u8 id;
+ u8 present:1;
};
+#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
+
struct acpi_sbs {
- int base;
+ struct power_supply charger;
struct acpi_device *device;
- struct mutex mutex;
- int sbsm_present;
- int sbsm_batteries_supported;
- struct proc_dir_entry *ac_entry;
- struct acpi_ac ac;
+ struct acpi_smb_hc *hc;
+ struct mutex lock;
+#ifdef CONFIG_ACPI_PROCFS
+ struct proc_dir_entry *charger_entry;
+#endif
struct acpi_battery battery[MAX_SBS_BAT];
- int zombie;
- struct timer_list update_timer;
- int run_cnt;
- int update_proc_flg;
+ u8 batteries_supported:4;
+ u8 manager_present:1;
+ u8 charger_present:1;
};
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type);
-static void acpi_sbs_update_time(void *data);
+#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger)
-union sbs_rw_data {
- u16 word;
- u8 block[ACPI_SBS_BLOCK_MAX + 2];
-};
-
-static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
- char read_write, u8 command, int size,
- union sbs_rw_data *data);
-
-/* --------------------------------------------------------------------------
- SMBus Communication
- -------------------------------------------------------------------------- */
-
-static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data)
+static inline int battery_scale(int log)
{
- u8 val;
- int err;
-
- err = ec_read(sbs->base + address, &val);
- if (!err) {
- *data = val;
- }
- xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP);
- return (err);
-}
-
-static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data)
-{
- int err;
-
- err = ec_write(sbs->base + address, data);
- return (err);
-}
-
-static int
-acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr,
- char read_write, u8 command, int size,
- union sbs_rw_data *data)
-{
- unsigned char protocol, len = 0, temp[2] = { 0, 0 };
- int i;
-
- if (read_write == ACPI_SBS_SMBUS_READ) {
- protocol = ACPI_EC_SMB_PRTCL_READ;
- } else {
- protocol = ACPI_EC_SMB_PRTCL_WRITE;
- }
-
- switch (size) {
-
- case ACPI_SBS_WORD_DATA:
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
- if (read_write == ACPI_SBS_SMBUS_WRITE) {
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word);
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1,
- data->word >> 8);
- }
- protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA;
- break;
- case ACPI_SBS_BLOCK_DATA:
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command);
- if (read_write == ACPI_SBS_SMBUS_WRITE) {
- len = min_t(u8, data->block[0], 32);
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len);
- for (i = 0; i < len; i++)
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i,
- data->block[i + 1]);
- }
- protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA;
- break;
- default:
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "unsupported transaction %d", size));
- return (-1);
- }
-
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1);
- acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol);
-
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
-
- if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
- xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1);
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
- }
- if (~temp[0] & ACPI_EC_SMB_STS_DONE) {
- xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2);
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp);
- }
- if ((~temp[0] & ACPI_EC_SMB_STS_DONE)
- || (temp[0] & ACPI_EC_SMB_STS_STATUS)) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "transaction %d error", size));
- return (-1);
- }
-
- if (read_write == ACPI_SBS_SMBUS_WRITE) {
- return (0);
- }
-
- switch (size) {
-
- case ACPI_SBS_WORD_DATA:
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp);
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1);
- data->word = (temp[1] << 8) | temp[0];
- break;
-
- case ACPI_SBS_BLOCK_DATA:
- len = 0;
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len);
- len = min_t(u8, len, 32);
- for (i = 0; i < len; i++)
- acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i,
- data->block + i + 1);
- data->block[0] = len;
- break;
- default:
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "unsupported transaction %d", size));
- return (-1);
- }
-
- return (0);
+ int scale = 1;
+ while (log--)
+ scale *= 10;
+ return scale;
}
-static int
-acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word)
+static inline int acpi_battery_vscale(struct acpi_battery *battery)
{
- union sbs_rw_data data;
- int result = 0;
-
- result = acpi_ec_sbs_access(sbs, addr,
- ACPI_SBS_SMBUS_READ, func,
- ACPI_SBS_WORD_DATA, &data);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_ec_sbs_access() failed"));
- } else {
- *word = data.word;
- }
-
- return result;
+ return battery_scale((battery->spec & 0x0f00) >> 8);
}
-static int
-acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str)
+static inline int acpi_battery_ipscale(struct acpi_battery *battery)
{
- union sbs_rw_data data;
- int result = 0;
-
- result = acpi_ec_sbs_access(sbs, addr,
- ACPI_SBS_SMBUS_READ, func,
- ACPI_SBS_BLOCK_DATA, &data);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_ec_sbs_access() failed"));
- } else {
- strncpy(str, (const char *)data.block + 1, data.block[0]);
- str[data.block[0]] = 0;
- }
-
- return result;
+ return battery_scale((battery->spec & 0xf000) >> 12);
}
-static int
-acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word)
+static inline int acpi_battery_mode(struct acpi_battery *battery)
{
- union sbs_rw_data data;
- int result = 0;
-
- data.word = word;
-
- result = acpi_ec_sbs_access(sbs, addr,
- ACPI_SBS_SMBUS_WRITE, func,
- ACPI_SBS_WORD_DATA, &data);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_ec_sbs_access() failed"));
- }
-
- return result;
+ return (battery->mode & 0x8000);
}
-static int sbs_zombie(struct acpi_sbs *sbs)
+static inline int acpi_battery_scale(struct acpi_battery *battery)
{
- return (sbs->zombie);
+ return (acpi_battery_mode(battery) ? 10 : 1) *
+ acpi_battery_ipscale(battery);
}
-static int sbs_mutex_lock(struct acpi_sbs *sbs)
+static int sbs_get_ac_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
{
- if (sbs_zombie(sbs)) {
- return -ENODEV;
+ struct acpi_sbs *sbs = to_acpi_sbs(psy);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = sbs->charger_present;
+ break;
+ default:
+ return -EINVAL;
}
- mutex_lock(&sbs->mutex);
return 0;
}
-static void sbs_mutex_unlock(struct acpi_sbs *sbs)
+static int acpi_battery_technology(struct acpi_battery *battery)
{
- mutex_unlock(&sbs->mutex);
+ if (!strcasecmp("NiCd", battery->device_chemistry))
+ return POWER_SUPPLY_TECHNOLOGY_NiCd;
+ if (!strcasecmp("NiMH", battery->device_chemistry))
+ return POWER_SUPPLY_TECHNOLOGY_NiMH;
+ if (!strcasecmp("LION", battery->device_chemistry))
+ return POWER_SUPPLY_TECHNOLOGY_LION;
+ if (!strcasecmp("LiP", battery->device_chemistry))
+ return POWER_SUPPLY_TECHNOLOGY_LIPO;
+ return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
}
-/* --------------------------------------------------------------------------
- Smart Battery System Management
- -------------------------------------------------------------------------- */
-
-static int acpi_check_update_proc(struct acpi_sbs *sbs)
+static int acpi_sbs_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
{
- acpi_status status = AE_OK;
+ struct acpi_battery *battery = to_acpi_battery(psy);
- if (update_time == 0) {
- sbs->update_proc_flg = 0;
- return 0;
- }
- if (sbs->update_proc_flg == 0) {
- status = acpi_os_execute(OSL_GPE_HANDLER,
- acpi_sbs_update_time, sbs);
- if (status != AE_OK) {
- ACPI_EXCEPTION((AE_INFO, status,
- "acpi_os_execute() failed"));
- return 1;
- }
- sbs->update_proc_flg = 1;
+ if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT)
+ return -ENODEV;
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ if (battery->current_now < 0)
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ else if (battery->current_now > 0)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = battery->present;
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = acpi_battery_technology(battery);
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = battery->design_voltage *
+ acpi_battery_vscale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = battery->voltage_now *
+ acpi_battery_vscale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = abs(battery->current_now) *
+ acpi_battery_ipscale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ val->intval = abs(battery->current_avg) *
+ acpi_battery_ipscale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = battery->state_of_charge;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ val->intval = battery->design_capacity *
+ acpi_battery_scale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ case POWER_SUPPLY_PROP_ENERGY_FULL:
+ val->intval = battery->full_charge_capacity *
+ acpi_battery_scale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_NOW:
+ case POWER_SUPPLY_PROP_ENERGY_NOW:
+ val->intval = battery->capacity_now *
+ acpi_battery_scale(battery) * 1000;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = battery->temp_now - 2730; // dK -> dC
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = battery->device_name;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = battery->manufacturer_name;
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
-static int acpi_sbs_generate_event(struct acpi_device *device,
- int event, int state, char *bid, char *class)
-{
- char bid_saved[5];
- char class_saved[20];
- int result = 0;
-
- strcpy(bid_saved, acpi_device_bid(device));
- strcpy(class_saved, acpi_device_class(device));
-
- strcpy(acpi_device_bid(device), bid);
- strcpy(acpi_device_class(device), class);
-
- result = acpi_bus_generate_proc_event(device, event, state);
-
- strcpy(acpi_device_bid(device), bid_saved);
- strcpy(acpi_device_class(device), class_saved);
-
- acpi_bus_generate_netlink_event(class, bid, event, state);
- return result;
-}
-
-static int acpi_battery_get_present(struct acpi_battery *battery)
-{
- s16 state;
- int result = 0;
- int is_present = 0;
-
- result = acpi_sbs_read_word(battery->sbs,
- ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- }
- if (!result) {
- is_present = (state & 0x000f) & (1 << battery->id);
- }
- battery->battery_present = is_present;
-
- return result;
-}
+static enum power_supply_property sbs_ac_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
-static int acpi_battery_select(struct acpi_battery *battery)
-{
- struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
- s16 state;
- int foo;
+static enum power_supply_property sbs_charge_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_CHARGE_NOW,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
- if (sbs->sbsm_present) {
+static enum power_supply_property sbs_energy_battery_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_ENERGY_FULL,
+ POWER_SUPPLY_PROP_ENERGY_NOW,
+ POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
- /* Take special care not to knobble other nibbles of
- * state (aka selector_state), since
- * it causes charging to halt on SBSELs */
+/* --------------------------------------------------------------------------
+ Smart Battery System Management
+ -------------------------------------------------------------------------- */
- result =
- acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
+struct acpi_battery_reader {
+ u8 command; /* command for battery */
+ u8 mode; /* word or block? */
+ size_t offset; /* offset inside struct acpi_sbs_battery */
+};
- foo = (state & 0x0fff) | (1 << (battery->id + 12));
- result =
- acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_write_word() failed"));
- goto end;
- }
- }
+static struct acpi_battery_reader info_readers[] = {
+ {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)},
+ {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)},
+ {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)},
+ {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)},
+ {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)},
+ {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)},
+ {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)},
+ {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)},
+ {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)},
+ {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)},
+ {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)},
+};
- end:
- return result;
-}
+static struct acpi_battery_reader state_readers[] = {
+ {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
+ {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
+ {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
+ {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+ {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
+ {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
+ {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
+};
-static int acpi_sbsm_get_info(struct acpi_sbs *sbs)
+static int acpi_manager_get_info(struct acpi_sbs *sbs)
{
int result = 0;
- s16 battery_system_info;
-
- result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04,
- &battery_system_info);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
- sbs->sbsm_present = 1;
- sbs->sbsm_batteries_supported = battery_system_info & 0x000f;
-
- end:
+ u16 battery_system_info;
+ result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+ 0x04, (u8 *)&battery_system_info);
+ if (!result)
+ sbs->batteries_supported = battery_system_info & 0x000f;
return result;
}
static int acpi_battery_get_info(struct acpi_battery *battery)
{
- struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
- s16 battery_mode;
- s16 specification_info;
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
- &battery_mode);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
- battery->info.capacity_mode = (battery_mode & 0x8000) >> 15;
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10,
- &battery->info.full_charge_capacity);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18,
- &battery->info.design_capacity);
-
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19,
- &battery->info.design_voltage);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
+ int i, result = 0;
+
+ for (i = 0; i < ARRAY_SIZE(info_readers); ++i) {
+ result = acpi_smbus_read(battery->sbs->hc,
+ info_readers[i].mode,
+ ACPI_SBS_BATTERY,
+ info_readers[i].command,
+ (u8 *) battery +
+ info_readers[i].offset);
+ if (result)
+ break;
}
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a,
- &specification_info);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- switch ((specification_info & 0x0f00) >> 8) {
- case 1:
- battery->info.vscale = 10;
- break;
- case 2:
- battery->info.vscale = 100;
- break;
- case 3:
- battery->info.vscale = 1000;
- break;
- default:
- battery->info.vscale = 1;
- }
-
- switch ((specification_info & 0xf000) >> 12) {
- case 1:
- battery->info.ipscale = 10;
- break;
- case 2:
- battery->info.ipscale = 100;
- break;
- case 3:
- battery->info.ipscale = 1000;
- break;
- default:
- battery->info.ipscale = 1;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c,
- &battery->info.serial_number);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20,
- battery->info.manufacturer_name);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_str() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21,
- battery->info.device_name);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_str() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22,
- battery->info.device_chemistry);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_str() failed"));
- goto end;
- }
-
- end:
return result;
}
static int acpi_battery_get_state(struct acpi_battery *battery)
{
- struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
+ int i, result = 0;
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09,
- &battery->state.voltage);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a,
- &battery->state.amperage);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f,
- &battery->state.remaining_capacity);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16,
- &battery->state.battery_state);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
+ if (battery->update_time &&
+ time_before(jiffies, battery->update_time +
+ msecs_to_jiffies(cache_time)))
+ return 0;
+ for (i = 0; i < ARRAY_SIZE(state_readers); ++i) {
+ result = acpi_smbus_read(battery->sbs->hc,
+ state_readers[i].mode,
+ ACPI_SBS_BATTERY,
+ state_readers[i].command,
+ (u8 *)battery +
+ state_readers[i].offset);
+ if (result)
+ goto end;
}
-
end:
+ battery->update_time = jiffies;
return result;
}
static int acpi_battery_get_alarm(struct acpi_battery *battery)
{
- struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
-
- result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
- &battery->alarm.remaining_capacity);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- end:
-
- return result;
+ return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+ ACPI_SBS_BATTERY, 0x01,
+ (u8 *)&battery->alarm_capacity);
}
-static int acpi_battery_set_alarm(struct acpi_battery *battery,
- unsigned long alarm)
+static int acpi_battery_set_alarm(struct acpi_battery *battery)
{
struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
- s16 battery_mode;
- int foo;
+ u16 value, sel = 1 << (battery->id + 12);
- result = acpi_battery_select(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_select() failed"));
- goto end;
- }
+ int ret;
- /* If necessary, enable the alarm */
- if (alarm > 0) {
- result =
- acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03,
- &battery_mode);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
+ if (sbs->manager_present) {
+ ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER,
+ 0x01, (u8 *)&value);
+ if (ret)
goto end;
- }
-
- result =
- acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01,
- battery_mode & 0xbfff);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_write_word() failed"));
+ if ((value & 0xf000) != sel) {
+ value &= 0x0fff;
+ value |= sel;
+ ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD,
+ ACPI_SBS_MANAGER,
+ 0x01, (u8 *)&value, 2);
+ if (ret)
goto end;
}
}
-
- foo = alarm / (battery->info.capacity_mode ? 10 : 1);
- result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_write_word() failed"));
- goto end;
- }
-
+ ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY,
+ 0x01, (u8 *)&battery->alarm_capacity, 2);
end:
-
- return result;
+ return ret;
}
-static int acpi_battery_set_mode(struct acpi_battery *battery)
+static int acpi_ac_get_present(struct acpi_sbs *sbs)
{
- struct acpi_sbs *sbs = battery->sbs;
- int result = 0;
- s16 battery_mode;
-
- if (capacity_mode == DEF_CAPACITY_UNIT) {
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs,
- ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- if (capacity_mode == MAH_CAPACITY_UNIT) {
- battery_mode &= 0x7fff;
- } else {
- battery_mode |= 0x8000;
- }
- result = acpi_sbs_write_word(sbs,
- ACPI_SB_SMBUS_ADDR, 0x03, battery_mode);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_write_word() failed"));
- goto end;
- }
-
- result = acpi_sbs_read_word(sbs,
- ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
+ int result;
+ u16 status;
- end:
+ result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER,
+ 0x13, (u8 *) & status);
+ if (!result)
+ sbs->charger_present = (status >> 15) & 0x1;
return result;
}
-static int acpi_battery_init(struct acpi_battery *battery)
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
- int result = 0;
-
- result = acpi_battery_select(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_select() failed"));
- goto end;
- }
-
- result = acpi_battery_set_mode(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_set_mode() failed"));
- goto end;
- }
-
- result = acpi_battery_get_info(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_info() failed"));
- goto end;
- }
-
- result = acpi_battery_get_state(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_state() failed"));
- goto end;
- }
-
- result = acpi_battery_get_alarm(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_alarm() failed"));
- goto end;
- }
-
- end:
- return result;
+ struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+ acpi_battery_get_alarm(battery);
+ return sprintf(buf, "%d\n", battery->alarm_capacity *
+ acpi_battery_scale(battery) * 1000);
}
-static int acpi_ac_get_present(struct acpi_sbs *sbs)
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
- int result = 0;
- s16 charger_status;
-
- result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13,
- &charger_status);
-
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_read_word() failed"));
- goto end;
- }
-
- sbs->ac.ac_present = (charger_status & 0x8000) >> 15;
-
- end:
-
- return result;
+ unsigned long x;
+ struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+ if (sscanf(buf, "%ld\n", &x) == 1)
+ battery->alarm_capacity = x /
+ (1000 * acpi_battery_scale(battery));
+ if (battery->present)
+ acpi_battery_set_alarm(battery);
+ return count;
}
+static struct device_attribute alarm_attr = {
+ .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+ .show = acpi_battery_alarm_show,
+ .store = acpi_battery_alarm_store,
+};
+
/* --------------------------------------------------------------------------
FS Interface (/proc/acpi)
-------------------------------------------------------------------------- */
+#ifdef CONFIG_ACPI_PROCFS
/* Generic Routines */
-
static int
-acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
- struct proc_dir_entry *parent_dir,
- char *dir_name,
- struct file_operations *info_fops,
- struct file_operations *state_fops,
- struct file_operations *alarm_fops, void *data)
+acpi_sbs_add_fs(struct proc_dir_entry **dir,
+ struct proc_dir_entry *parent_dir,
+ char *dir_name,
+ struct file_operations *info_fops,
+ struct file_operations *state_fops,
+ struct file_operations *alarm_fops, void *data)
{
struct proc_dir_entry *entry = NULL;
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
if (!*dir) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "proc_mkdir() failed"));
return -ENODEV;
}
(*dir)->owner = THIS_MODULE;
@@ -882,10 +491,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
/* 'info' [R] */
if (info_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir);
- if (!entry) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "create_proc_entry() failed"));
- } else {
+ if (entry) {
entry->proc_fops = info_fops;
entry->data = data;
entry->owner = THIS_MODULE;
@@ -895,10 +501,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
/* 'state' [R] */
if (state_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir);
- if (!entry) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "create_proc_entry() failed"));
- } else {
+ if (entry) {
entry->proc_fops = state_fops;
entry->data = data;
entry->owner = THIS_MODULE;
@@ -908,24 +511,19 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir,
/* 'alarm' [R/W] */
if (alarm_fops) {
entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir);
- if (!entry) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "create_proc_entry() failed"));
- } else {
+ if (entry) {
entry->proc_fops = alarm_fops;
entry->data = data;
entry->owner = THIS_MODULE;
}
}
-
return 0;
}
static void
-acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
+acpi_sbs_remove_fs(struct proc_dir_entry **dir,
struct proc_dir_entry *parent_dir)
{
-
if (*dir) {
remove_proc_entry(ACPI_SBS_FILE_INFO, *dir);
remove_proc_entry(ACPI_SBS_FILE_STATE, *dir);
@@ -933,82 +531,52 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,
remove_proc_entry((*dir)->name, parent_dir);
*dir = NULL;
}
-
}
/* Smart Battery Interface */
-
static struct proc_dir_entry *acpi_battery_dir = NULL;
+static inline char *acpi_battery_units(struct acpi_battery *battery)
+{
+ return acpi_battery_mode(battery) ? " mWh" : " mAh";
+}
+
+
static int acpi_battery_read_info(struct seq_file *seq, void *offset)
{
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
- int cscale;
int result = 0;
- if (sbs_mutex_lock(sbs)) {
- return -ENODEV;
- }
-
- result = acpi_check_update_proc(sbs);
- if (result)
- goto end;
-
- if (update_time == 0) {
- result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_update_run() failed"));
- }
- }
+ mutex_lock(&sbs->lock);
- if (battery->battery_present) {
- seq_printf(seq, "present: yes\n");
- } else {
- seq_printf(seq, "present: no\n");
+ seq_printf(seq, "present: %s\n",
+ (battery->present) ? "yes" : "no");
+ if (!battery->present)
goto end;
- }
- if (battery->info.capacity_mode) {
- cscale = battery->info.vscale * battery->info.ipscale;
- } else {
- cscale = battery->info.ipscale;
- }
seq_printf(seq, "design capacity: %i%s\n",
- battery->info.design_capacity * cscale,
- battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+ battery->design_capacity * acpi_battery_scale(battery),
+ acpi_battery_units(battery));
seq_printf(seq, "last full capacity: %i%s\n",
- battery->info.full_charge_capacity * cscale,
- battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+ battery->full_charge_capacity * acpi_battery_scale(battery),
+ acpi_battery_units(battery));
seq_printf(seq, "battery technology: rechargeable\n");
-
seq_printf(seq, "design voltage: %i mV\n",
- battery->info.design_voltage * battery->info.vscale);
-
+ battery->design_voltage * acpi_battery_vscale(battery));
seq_printf(seq, "design capacity warning: unknown\n");
seq_printf(seq, "design capacity low: unknown\n");
seq_printf(seq, "capacity granularity 1: unknown\n");
seq_printf(seq, "capacity granularity 2: unknown\n");
-
- seq_printf(seq, "model number: %s\n",
- battery->info.device_name);
-
+ seq_printf(seq, "model number: %s\n", battery->device_name);
seq_printf(seq, "serial number: %i\n",
- battery->info.serial_number);
-
+ battery->serial_number);
seq_printf(seq, "battery type: %s\n",
- battery->info.device_chemistry);
-
+ battery->device_chemistry);
seq_printf(seq, "OEM info: %s\n",
- battery->info.manufacturer_name);
-
+ battery->manufacturer_name);
end:
-
- sbs_mutex_unlock(sbs);
-
+ mutex_unlock(&sbs->lock);
return result;
}
@@ -1022,73 +590,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
int result = 0;
- int cscale;
- int foo;
-
- if (sbs_mutex_lock(sbs)) {
- return -ENODEV;
- }
- result = acpi_check_update_proc(sbs);
- if (result)
+ mutex_lock(&sbs->lock);
+ seq_printf(seq, "present: %s\n",
+ (battery->present) ? "yes" : "no");
+ if (!battery->present)
goto end;
- if (update_time == 0) {
- result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_update_run() failed"));
- }
- }
-
- if (battery->battery_present) {
- seq_printf(seq, "present: yes\n");
- } else {
- seq_printf(seq, "present: no\n");
- goto end;
- }
-
- if (battery->info.capacity_mode) {
- cscale = battery->info.vscale * battery->info.ipscale;
- } else {
- cscale = battery->info.ipscale;
- }
-
- if (battery->state.battery_state & 0x0010) {
- seq_printf(seq, "capacity state: critical\n");
- } else {
- seq_printf(seq, "capacity state: ok\n");
- }
-
- foo = (s16) battery->state.amperage * battery->info.ipscale;
- if (battery->info.capacity_mode) {
- foo = foo * battery->info.design_voltage / 1000;
- }
- if (battery->state.amperage < 0) {
- seq_printf(seq, "charging state: discharging\n");
- seq_printf(seq, "present rate: %d %s\n",
- -foo, battery->info.capacity_mode ? "mW" : "mA");
- } else if (battery->state.amperage > 0) {
- seq_printf(seq, "charging state: charging\n");
- seq_printf(seq, "present rate: %d %s\n",
- foo, battery->info.capacity_mode ? "mW" : "mA");
- } else {
- seq_printf(seq, "charging state: charged\n");
- seq_printf(seq, "present rate: 0 %s\n",
- battery->info.capacity_mode ? "mW" : "mA");
- }
-
+ acpi_battery_get_state(battery);
+ seq_printf(seq, "capacity state: %s\n",
+ (battery->state & 0x0010) ? "critical" : "ok");
+ seq_printf(seq, "charging state: %s\n",
+ (battery->current_now < 0) ? "discharging" :
+ ((battery->current_now > 0) ? "charging" : "charged"));
+ seq_printf(seq, "present rate: %d mA\n",
+ abs(battery->current_now) * acpi_battery_ipscale(battery));
seq_printf(seq, "remaining capacity: %i%s\n",
- battery->state.remaining_capacity * cscale,
- battery->info.capacity_mode ? "0 mWh" : " mAh");
-
+ battery->capacity_now * acpi_battery_scale(battery),
+ acpi_battery_units(battery));
seq_printf(seq, "present voltage: %i mV\n",
- battery->state.voltage * battery->info.vscale);
+ battery->voltage_now * acpi_battery_vscale(battery));
end:
-
- sbs_mutex_unlock(sbs);
-
+ mutex_unlock(&sbs->lock);
return result;
}
@@ -1102,48 +626,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
int result = 0;
- int cscale;
-
- if (sbs_mutex_lock(sbs)) {
- return -ENODEV;
- }
-
- result = acpi_check_update_proc(sbs);
- if (result)
- goto end;
- if (update_time == 0) {
- result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_update_run() failed"));
- }
- }
+ mutex_lock(&sbs->lock);
- if (!battery->battery_present) {
+ if (!battery->present) {
seq_printf(seq, "present: no\n");
goto end;
}
- if (battery->info.capacity_mode) {
- cscale = battery->info.vscale * battery->info.ipscale;
- } else {
- cscale = battery->info.ipscale;
- }
-
+ acpi_battery_get_alarm(battery);
seq_printf(seq, "alarm: ");
- if (battery->alarm.remaining_capacity) {
+ if (battery->alarm_capacity)
seq_printf(seq, "%i%s\n",
- battery->alarm.remaining_capacity * cscale,
- battery->info.capacity_mode ? "0 mWh" : " mAh");
- } else {
+ battery->alarm_capacity *
+ acpi_battery_scale(battery),
+ acpi_battery_units(battery));
+ else
seq_printf(seq, "disabled\n");
- }
-
end:
-
- sbs_mutex_unlock(sbs);
-
+ mutex_unlock(&sbs->lock);
return result;
}
@@ -1155,59 +656,29 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,
struct acpi_battery *battery = seq->private;
struct acpi_sbs *sbs = battery->sbs;
char alarm_string[12] = { '\0' };
- int result, old_alarm, new_alarm;
-
- if (sbs_mutex_lock(sbs)) {
- return -ENODEV;
- }
-
- result = acpi_check_update_proc(sbs);
- if (result)
- goto end;
-
- if (!battery->battery_present) {
+ int result = 0;
+ mutex_lock(&sbs->lock);
+ if (!battery->present) {
result = -ENODEV;
goto end;
}
-
if (count > sizeof(alarm_string) - 1) {
result = -EINVAL;
goto end;
}
-
if (copy_from_user(alarm_string, buffer, count)) {
result = -EFAULT;
goto end;
}
-
alarm_string[count] = 0;
-
- old_alarm = battery->alarm.remaining_capacity;
- new_alarm = simple_strtoul(alarm_string, NULL, 0);
-
- result = acpi_battery_set_alarm(battery, new_alarm);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_set_alarm() failed"));
- acpi_battery_set_alarm(battery, old_alarm);
- goto end;
- }
- result = acpi_battery_get_alarm(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_alarm() failed"));
- acpi_battery_set_alarm(battery, old_alarm);
- goto end;
- }
-
+ battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) /
+ acpi_battery_scale(battery);
+ acpi_battery_set_alarm(battery);
end:
- sbs_mutex_unlock(sbs);
-
- if (result) {
+ mutex_unlock(&sbs->lock);
+ if (result)
return result;
- } else {
- return count;
- }
+ return count;
}
static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
@@ -1246,26 +717,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;
static int acpi_ac_read_state(struct seq_file *seq, void *offset)
{
- struct acpi_sbs *sbs = seq->private;
- int result;
- if (sbs_mutex_lock(sbs)) {
- return -ENODEV;
- }
+ struct acpi_sbs *sbs = seq->private;
- if (update_time == 0) {
- result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_update_run() failed"));
- }
- }
+ mutex_lock(&sbs->lock);
seq_printf(seq, "state: %s\n",
- sbs->ac.ac_present ? "on-line" : "off-line");
-
- sbs_mutex_unlock(sbs);
+ sbs->charger_present ? "on-line" : "off-line");
+ mutex_unlock(&sbs->lock);
return 0;
}
@@ -1282,429 +742,203 @@ static struct file_operations acpi_ac_state_fops = {
.owner = THIS_MODULE,
};
+#endif
+
/* --------------------------------------------------------------------------
Driver Interface
-------------------------------------------------------------------------- */
+static int acpi_battery_read(struct acpi_battery *battery)
+{
+ int result = 0, saved_present = battery->present;
+ u16 state;
+
+ if (battery->sbs->manager_present) {
+ result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
+ ACPI_SBS_MANAGER, 0x01, (u8 *)&state);
+ if (!result)
+ battery->present = state & (1 << battery->id);
+ state &= 0x0fff;
+ state |= 1 << (battery->id + 12);
+ acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD,
+ ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2);
+ } else if (battery->id == 0)
+ battery->present = 1;
+ if (result || !battery->present)
+ return result;
-/* Smart Battery */
+ if (saved_present != battery->present) {
+ battery->update_time = 0;
+ result = acpi_battery_get_info(battery);
+ if (result)
+ return result;
+ }
+ result = acpi_battery_get_state(battery);
+ return result;
+}
+/* Smart Battery */
static int acpi_battery_add(struct acpi_sbs *sbs, int id)
{
- int is_present;
+ struct acpi_battery *battery = &sbs->battery[id];
int result;
- char dir_name[32];
- struct acpi_battery *battery;
-
- battery = &sbs->battery[id];
-
- battery->alive = 0;
- battery->init_state = 0;
battery->id = id;
battery->sbs = sbs;
+ result = acpi_battery_read(battery);
+ if (result)
+ return result;
- result = acpi_battery_select(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_select() failed"));
- goto end;
- }
-
- result = acpi_battery_get_present(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_present() failed"));
- goto end;
- }
-
- is_present = battery->battery_present;
-
- if (is_present) {
- result = acpi_battery_init(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_init() failed"));
- goto end;
- }
- battery->init_state = 1;
- }
-
- sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
-
- result = acpi_sbs_generic_add_fs(&battery->battery_entry,
- acpi_battery_dir,
- dir_name,
- &acpi_battery_info_fops,
- &acpi_battery_state_fops,
- &acpi_battery_alarm_fops, battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_generic_add_fs() failed"));
- goto end;
+ sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id);
+#ifdef CONFIG_ACPI_PROCFS
+ acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir,
+ battery->name, &acpi_battery_info_fops,
+ &acpi_battery_state_fops, &acpi_battery_alarm_fops,
+ battery);
+#endif
+ battery->bat.name = battery->name;
+ battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ if (!acpi_battery_mode(battery)) {
+ battery->bat.properties = sbs_charge_battery_props;
+ battery->bat.num_properties =
+ ARRAY_SIZE(sbs_charge_battery_props);
+ } else {
+ battery->bat.properties = sbs_energy_battery_props;
+ battery->bat.num_properties =
+ ARRAY_SIZE(sbs_energy_battery_props);
}
- battery->alive = 1;
-
+ battery->bat.get_property = acpi_sbs_battery_get_property;
+ result = power_supply_register(&sbs->device->dev, &battery->bat);
+ device_create_file(battery->bat.dev, &alarm_attr);
printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
- ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name,
- sbs->battery->battery_present ? "present" : "absent");
-
- end:
+ ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
+ battery->name, sbs->battery->present ? "present" : "absent");
return result;
}
static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
{
-
- if (sbs->battery[id].battery_entry) {
- acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry),
- acpi_battery_dir);
- }
+ if (sbs->battery[id].bat.dev)
+ device_remove_file(sbs->battery[id].bat.dev, &alarm_attr);
+ power_supply_unregister(&sbs->battery[id].bat);
+#ifdef CONFIG_ACPI_PROCFS
+ if (sbs->battery[id].proc_entry) {
+ acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry),
+ acpi_battery_dir);
+ }
+#endif
}
-static int acpi_ac_add(struct acpi_sbs *sbs)
+static int acpi_charger_add(struct acpi_sbs *sbs)
{
int result;
result = acpi_ac_get_present(sbs);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_ac_get_present() failed"));
+ if (result)
goto end;
- }
-
- result = acpi_sbs_generic_add_fs(&sbs->ac_entry,
- acpi_ac_dir,
- ACPI_AC_DIR_NAME,
- NULL, &acpi_ac_state_fops, NULL, sbs);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_generic_add_fs() failed"));
+#ifdef CONFIG_ACPI_PROCFS
+ result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir,
+ ACPI_AC_DIR_NAME, NULL,
+ &acpi_ac_state_fops, NULL, sbs);
+ if (result)
goto end;
- }
-
+#endif
+ sbs->charger.name = "sbs-charger";
+ sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
+ sbs->charger.properties = sbs_ac_props;
+ sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
+ sbs->charger.get_property = sbs_get_ac_property;
+ power_supply_register(&sbs->device->dev, &sbs->charger);
printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
- ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line");
-
+ ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
end:
-
return result;
}
-static void acpi_ac_remove(struct acpi_sbs *sbs)
+static void acpi_charger_remove(struct acpi_sbs *sbs)
{
-
- if (sbs->ac_entry) {
- acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir);
- }
+ if (sbs->charger.dev)
+ power_supply_unregister(&sbs->charger);
+#ifdef CONFIG_ACPI_PROCFS
+ if (sbs->charger_entry)
+ acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
+#endif
}
-static void acpi_sbs_update_time_run(unsigned long data)
+void acpi_sbs_callback(void *context)
{
- acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data);
-}
-
-static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)
-{
- struct acpi_battery *battery;
- int result = 0, cnt;
- int old_ac_present = -1;
- int old_battery_present = -1;
- int new_ac_present = -1;
- int new_battery_present = -1;
- int id_min = 0, id_max = MAX_SBS_BAT - 1;
- char dir_name[32];
- int do_battery_init = 0, do_ac_init = 0;
- int old_remaining_capacity = 0;
- int update_battery = 1;
- int up_tm = update_time;
-
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- if (id >= 0) {
- id_min = id_max = id;
- }
-
- if (data_type == DATA_TYPE_COMMON && up_tm > 0) {
- cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
- if (sbs->run_cnt % cnt != 0) {
- update_battery = 0;
- }
- }
-
- sbs->run_cnt++;
-
- old_ac_present = sbs->ac.ac_present;
-
- result = acpi_ac_get_present(sbs);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_ac_get_present() failed"));
- }
-
- new_ac_present = sbs->ac.ac_present;
-
- do_ac_init = (old_ac_present != new_ac_present);
- if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) {
- do_ac_init = 1;
- }
-
- if (do_ac_init) {
- result = acpi_sbs_generate_event(sbs->device,
- ACPI_SBS_AC_NOTIFY_STATUS,
- new_ac_present,
- ACPI_AC_DIR_NAME,
- ACPI_AC_CLASS);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_generate_event() failed"));
- }
- }
-
- if (data_type == DATA_TYPE_COMMON) {
- if (!do_ac_init && !update_battery) {
- goto end;
- }
- }
-
- if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) {
- goto end;
- }
-
- for (id = id_min; id <= id_max; id++) {
- battery = &sbs->battery[id];
- if (battery->alive == 0) {
- continue;
- }
-
- old_remaining_capacity = battery->state.remaining_capacity;
-
- old_battery_present = battery->battery_present;
-
- result = acpi_battery_select(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_select() failed"));
- }
-
- result = acpi_battery_get_present(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_present() failed"));
- }
-
- new_battery_present = battery->battery_present;
-
- do_battery_init = ((old_battery_present != new_battery_present)
- && new_battery_present);
- if (!new_battery_present)
- goto event;
- if (do_ac_init || do_battery_init) {
- result = acpi_battery_init(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_init() "
- "failed"));
- }
- }
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- if ((data_type == DATA_TYPE_COMMON
- || data_type == DATA_TYPE_INFO)
- && new_battery_present) {
- result = acpi_battery_get_info(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_info() failed"));
- }
- }
- if (data_type == DATA_TYPE_INFO) {
- continue;
- }
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- if ((data_type == DATA_TYPE_COMMON
- || data_type == DATA_TYPE_STATE)
- && new_battery_present) {
- result = acpi_battery_get_state(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_state() failed"));
- }
- }
- if (data_type == DATA_TYPE_STATE) {
- goto event;
- }
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- if ((data_type == DATA_TYPE_COMMON
- || data_type == DATA_TYPE_ALARM)
- && new_battery_present) {
- result = acpi_battery_get_alarm(battery);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_get_alarm() "
- "failed"));
- }
- }
- if (data_type == DATA_TYPE_ALARM) {
- continue;
- }
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- event:
-
- if (old_battery_present != new_battery_present || do_ac_init ||
- old_remaining_capacity !=
- battery->state.remaining_capacity) {
- sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id);
- result = acpi_sbs_generate_event(sbs->device,
- ACPI_SBS_BATTERY_NOTIFY_STATUS,
- new_battery_present,
- dir_name,
- ACPI_BATTERY_CLASS);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_generate_event() "
- "failed"));
- }
+ int id;
+ struct acpi_sbs *sbs = context;
+ struct acpi_battery *bat;
+ u8 saved_charger_state = sbs->charger_present;
+ u8 saved_battery_state;
+ acpi_ac_get_present(sbs);
+ if (sbs->charger_present != saved_charger_state) {
+#ifdef CONFIG_ACPI_PROC_EVENT
+ acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME,
+ ACPI_SBS_NOTIFY_STATUS,
+ sbs->charger_present);
+#endif
+ kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
+ }
+ if (sbs->manager_present) {
+ for (id = 0; id < MAX_SBS_BAT; ++id) {
+ if (!(sbs->batteries_supported & (1 << id)))
+ continue;
+ bat = &sbs->battery[id];
+ saved_battery_state = bat->present;
+ acpi_battery_read(bat);
+ if (saved_battery_state == bat->present)
+ continue;
+#ifdef CONFIG_ACPI_PROC_EVENT
+ acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS,
+ bat->name,
+ ACPI_SBS_NOTIFY_STATUS,
+ bat->present);
+#endif
+ kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
}
}
-
- end:
-
- return result;
}
-static void acpi_sbs_update_time(void *data)
-{
- struct acpi_sbs *sbs = data;
- unsigned long delay = -1;
- int result;
- unsigned int up_tm = update_time;
-
- if (sbs_mutex_lock(sbs))
- return;
-
- result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_update_run() failed"));
- }
-
- if (sbs_zombie(sbs)) {
- goto end;
- }
-
- if (!up_tm) {
- if (timer_pending(&sbs->update_timer))
- del_timer(&sbs->update_timer);
- } else {
- delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm);
- delay = jiffies + HZ * delay;
- if (timer_pending(&sbs->update_timer)) {
- mod_timer(&sbs->update_timer, delay);
- } else {
- sbs->update_timer.data = (unsigned long)data;
- sbs->update_timer.function = acpi_sbs_update_time_run;
- sbs->update_timer.expires = delay;
- add_timer(&sbs->update_timer);
- }
- }
-
- end:
-
- sbs_mutex_unlock(sbs);
-}
+static int acpi_sbs_remove(struct acpi_device *device, int type);
static int acpi_sbs_add(struct acpi_device *device)
{
- struct acpi_sbs *sbs = NULL;
- int result = 0, remove_result = 0;
+ struct acpi_sbs *sbs;
+ int result = 0;
int id;
- acpi_status status = AE_OK;
- unsigned long val;
-
- status =
- acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
- if (ACPI_FAILURE(status)) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC"));
- return -EIO;
- }
sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL);
if (!sbs) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed"));
result = -ENOMEM;
goto end;
}
- mutex_init(&sbs->mutex);
-
- sbs_mutex_lock(sbs);
+ mutex_init(&sbs->lock);
- sbs->base = 0xff & (val >> 8);
+ sbs->hc = acpi_driver_data(device->parent);
sbs->device = device;
-
strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_SBS_CLASS);
acpi_driver_data(device) = sbs;
- result = acpi_ac_add(sbs);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed"));
- goto end;
- }
-
- acpi_sbsm_get_info(sbs);
-
- if (!sbs->sbsm_present) {
- result = acpi_battery_add(sbs, 0);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_add() failed"));
- goto end;
- }
- } else {
- for (id = 0; id < MAX_SBS_BAT; id++) {
- if ((sbs->sbsm_batteries_supported & (1 << id))) {
- result = acpi_battery_add(sbs, id);
- if (result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_battery_add() failed"));
- goto end;
- }
- }
- }
- }
-
- init_timer(&sbs->update_timer);
- result = acpi_check_update_proc(sbs);
+ result = acpi_charger_add(sbs);
if (result)
goto end;
+ result = acpi_manager_get_info(sbs);
+ if (!result) {
+ sbs->manager_present = 1;
+ for (id = 0; id < MAX_SBS_BAT; ++id)
+ if ((sbs->batteries_supported & (1 << id)))
+ acpi_battery_add(sbs, id);
+ } else
+ acpi_battery_add(sbs, 0);
+ acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs);
end:
-
- sbs_mutex_unlock(sbs);
-
- if (result) {
- remove_result = acpi_sbs_remove(device, 0);
- if (remove_result) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_sbs_remove() failed"));
- }
- }
-
+ if (result)
+ acpi_sbs_remove(device, 0);
return result;
}
@@ -1713,39 +947,25 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)
struct acpi_sbs *sbs;
int id;
- if (!device) {
+ if (!device)
return -EINVAL;
- }
-
sbs = acpi_driver_data(device);
- if (!sbs) {
+ if (!sbs)
return -EINVAL;
- }
-
- sbs_mutex_lock(sbs);
-
- sbs->zombie = 1;
- del_timer_sync(&sbs->update_timer);
- acpi_os_wait_events_complete(NULL);
- del_timer_sync(&sbs->update_timer);
-
- for (id = 0; id < MAX_SBS_BAT; id++) {
+ mutex_lock(&sbs->lock);
+ acpi_smbus_unregister_callback(sbs->hc);
+ for (id = 0; id < MAX_SBS_BAT; ++id)
acpi_battery_remove(sbs, id);
- }
-
- acpi_ac_remove(sbs);
-
- sbs_mutex_unlock(sbs);
-
- mutex_destroy(&sbs->mutex);
-
+ acpi_charger_remove(sbs);
+ mutex_unlock(&sbs->lock);
+ mutex_destroy(&sbs->lock);
kfree(sbs);
-
return 0;
}
static void acpi_sbs_rmdirs(void)
{
+#ifdef CONFIG_ACPI_PROCFS
if (acpi_ac_dir) {
acpi_unlock_ac_dir(acpi_ac_dir);
acpi_ac_dir = NULL;
@@ -1754,69 +974,58 @@ static void acpi_sbs_rmdirs(void)
acpi_unlock_battery_dir(acpi_battery_dir);
acpi_battery_dir = NULL;
}
+#endif
}
static int acpi_sbs_resume(struct acpi_device *device)
{
struct acpi_sbs *sbs;
-
if (!device)
return -EINVAL;
-
sbs = device->driver_data;
-
- sbs->run_cnt = 0;
-
+ acpi_sbs_callback(sbs);
return 0;
}
+static struct acpi_driver acpi_sbs_driver = {
+ .name = "sbs",
+ .class = ACPI_SBS_CLASS,
+ .ids = sbs_device_ids,
+ .ops = {
+ .add = acpi_sbs_add,
+ .remove = acpi_sbs_remove,
+ .resume = acpi_sbs_resume,
+ },
+};
+
static int __init acpi_sbs_init(void)
{
int result = 0;
if (acpi_disabled)
return -ENODEV;
-
- if (capacity_mode != DEF_CAPACITY_UNIT
- && capacity_mode != MAH_CAPACITY_UNIT
- && capacity_mode != MWH_CAPACITY_UNIT) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "invalid capacity_mode = %d", capacity_mode));
- return -EINVAL;
- }
-
+#ifdef CONFIG_ACPI_PROCFS
acpi_ac_dir = acpi_lock_ac_dir();
- if (!acpi_ac_dir) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_lock_ac_dir() failed"));
+ if (!acpi_ac_dir)
return -ENODEV;
- }
-
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_lock_battery_dir() failed"));
acpi_sbs_rmdirs();
return -ENODEV;
}
-
+#endif
result = acpi_bus_register_driver(&acpi_sbs_driver);
if (result < 0) {
- ACPI_EXCEPTION((AE_INFO, AE_ERROR,
- "acpi_bus_register_driver() failed"));
acpi_sbs_rmdirs();
return -ENODEV;
}
-
return 0;
}
static void __exit acpi_sbs_exit(void)
{
acpi_bus_unregister_driver(&acpi_sbs_driver);
-
acpi_sbs_rmdirs();
-
return;
}
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c
new file mode 100644
index 00000000000..046d7c3ed35
--- /dev/null
+++ b/drivers/acpi/sbshc.c
@@ -0,0 +1,309 @@
+/*
+ * SMBus driver for ACPI Embedded Controller (v0.1)
+ *
+ * Copyright (c) 2007 Alexey Starikovskiy
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ */
+
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/actypes.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include "sbshc.h"
+
+#define ACPI_SMB_HC_CLASS "smbus_host_controller"
+#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC"
+
+struct acpi_smb_hc {
+ struct acpi_ec *ec;
+ struct mutex lock;
+ wait_queue_head_t wait;
+ u8 offset;
+ u8 query_bit;
+ smbus_alarm_callback callback;
+ void *context;
+};
+
+static int acpi_smbus_hc_add(struct acpi_device *device);
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id sbs_device_ids[] = {
+ {"ACPI0001", 0},
+ {"ACPI0005", 0},
+ {"", 0},
+};
+
+MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
+
+static struct acpi_driver acpi_smb_hc_driver = {
+ .name = "smbus_hc",
+ .class = ACPI_SMB_HC_CLASS,
+ .ids = sbs_device_ids,
+ .ops = {
+ .add = acpi_smbus_hc_add,
+ .remove = acpi_smbus_hc_remove,
+ },
+};
+
+union acpi_smb_status {
+ u8 raw;
+ struct {
+ u8 status:5;
+ u8 reserved:1;
+ u8 alarm:1;
+ u8 done:1;
+ } fields;
+};
+
+enum acpi_smb_status_codes {
+ SMBUS_OK = 0,
+ SMBUS_UNKNOWN_FAILURE = 0x07,
+ SMBUS_DEVICE_ADDRESS_NACK = 0x10,
+ SMBUS_DEVICE_ERROR = 0x11,
+ SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12,
+ SMBUS_UNKNOWN_ERROR = 0x13,
+ SMBUS_DEVICE_ACCESS_DENIED = 0x17,
+ SMBUS_TIMEOUT = 0x18,
+ SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19,
+ SMBUS_BUSY = 0x1a,
+ SMBUS_PEC_ERROR = 0x1f,
+};
+
+enum acpi_smb_offset {
+ ACPI_SMB_PROTOCOL = 0, /* protocol, PEC */
+ ACPI_SMB_STATUS = 1, /* status */
+ ACPI_SMB_ADDRESS = 2, /* address */
+ ACPI_SMB_COMMAND = 3, /* command */
+ ACPI_SMB_DATA = 4, /* 32 data registers */
+ ACPI_SMB_BLOCK_COUNT = 0x24, /* number of data bytes */
+ ACPI_SMB_ALARM_ADDRESS = 0x25, /* alarm address */
+ ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
+};
+
+static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
+{
+ return ec_read(hc->offset + address, data);
+}
+
+static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data)
+{
+ return ec_write(hc->offset + address, data);
+}
+
+static inline int smb_check_done(struct acpi_smb_hc *hc)
+{
+ union acpi_smb_status status = {.raw = 0};
+ smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw);
+ return status.fields.done && (status.fields.status == SMBUS_OK);
+}
+
+static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout)
+{
+ if (wait_event_timeout(hc->wait, smb_check_done(hc),
+ msecs_to_jiffies(timeout)))
+ return 0;
+ else
+ return -ETIME;
+}
+
+int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+ u8 command, u8 *data, u8 length)
+{
+ int ret = -EFAULT, i;
+ u8 temp, sz = 0;
+
+ mutex_lock(&hc->lock);
+ if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
+ goto end;
+ if (temp) {
+ ret = -EBUSY;
+ goto end;
+ }
+ smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+ smb_hc_write(hc, ACPI_SMB_COMMAND, command);
+ if (!(protocol & 0x01)) {
+ smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
+ for (i = 0; i < length; ++i)
+ smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]);
+ }
+ smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1);
+ smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol);
+ /*
+ * Wait for completion. Save the status code, data size,
+ * and data into the return package (if required by the protocol).
+ */
+ ret = wait_transaction_complete(hc, 1000);
+ if (ret || !(protocol & 0x01))
+ goto end;
+ switch (protocol) {
+ case SMBUS_RECEIVE_BYTE:
+ case SMBUS_READ_BYTE:
+ sz = 1;
+ break;
+ case SMBUS_READ_WORD:
+ sz = 2;
+ break;
+ case SMBUS_READ_BLOCK:
+ if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) {
+ ret = -EFAULT;
+ goto end;
+ }
+ sz &= 0x1f;
+ break;
+ }
+ for (i = 0; i < sz; ++i)
+ smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]);
+ end:
+ mutex_unlock(&hc->lock);
+ return ret;
+}
+
+int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+ u8 command, u8 *data)
+{
+ return acpi_smbus_transaction(hc, protocol, address, command, data, 0);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_read);
+
+int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+ u8 command, u8 *data, u8 length)
+{
+ return acpi_smbus_transaction(hc, protocol, address, command, data, length);
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_write);
+
+int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+ smbus_alarm_callback callback, void *context)
+{
+ mutex_lock(&hc->lock);
+ hc->callback = callback;
+ hc->context = context;
+ mutex_unlock(&hc->lock);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_register_callback);
+
+int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc)
+{
+ mutex_lock(&hc->lock);
+ hc->callback = NULL;
+ hc->context = NULL;
+ mutex_unlock(&hc->lock);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback);
+
+static void acpi_smbus_callback(void *context)
+{
+ struct acpi_smb_hc *hc = context;
+
+ if (hc->callback)
+ hc->callback(hc->context);
+}
+
+static int smbus_alarm(void *context)
+{
+ struct acpi_smb_hc *hc = context;
+ union acpi_smb_status status;
+ if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw))
+ return 0;
+ /* Check if it is only a completion notify */
+ if (status.fields.done)
+ wake_up(&hc->wait);
+ if (!status.fields.alarm)
+ return 0;
+ mutex_lock(&hc->lock);
+ smb_hc_write(hc, ACPI_SMB_STATUS, status.raw);
+ if (hc->callback)
+ acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc);
+ mutex_unlock(&hc->lock);
+ return 0;
+}
+
+typedef int (*acpi_ec_query_func) (void *data);
+
+extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
+ acpi_handle handle, acpi_ec_query_func func,
+ void *data);
+
+static int acpi_smbus_hc_add(struct acpi_device *device)
+{
+ int status;
+ unsigned long val;
+ struct acpi_smb_hc *hc;
+
+ if (!device)
+ return -EINVAL;
+
+ status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_ERR PREFIX "error obtaining _EC.\n");
+ return -EIO;
+ }
+
+ strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
+ strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);
+
+ hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
+ if (!hc)
+ return -ENOMEM;
+ mutex_init(&hc->lock);
+ init_waitqueue_head(&hc->wait);
+
+ hc->ec = acpi_driver_data(device->parent);
+ hc->offset = (val >> 8) & 0xff;
+ hc->query_bit = val & 0xff;
+ acpi_driver_data(device) = hc;
+
+ acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
+ printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
+ hc->ec, hc->offset, hc->query_bit);
+
+ return 0;
+}
+
+extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+
+static int acpi_smbus_hc_remove(struct acpi_device *device, int type)
+{
+ struct acpi_smb_hc *hc;
+
+ if (!device)
+ return -EINVAL;
+
+ hc = acpi_driver_data(device);
+ acpi_ec_remove_query_handler(hc->ec, hc->query_bit);
+ kfree(hc);
+ return 0;
+}
+
+static int __init acpi_smb_hc_init(void)
+{
+ int result;
+
+ result = acpi_bus_register_driver(&acpi_smb_hc_driver);
+ if (result < 0)
+ return -ENODEV;
+ return 0;
+}
+
+static void __exit acpi_smb_hc_exit(void)
+{
+ acpi_bus_unregister_driver(&acpi_smb_hc_driver);
+}
+
+module_init(acpi_smb_hc_init);
+module_exit(acpi_smb_hc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexey Starikovskiy");
+MODULE_DESCRIPTION("ACPI SMBus HC driver");
diff --git a/drivers/acpi/sbshc.h b/drivers/acpi/sbshc.h
new file mode 100644
index 00000000000..3bda3491a97
--- /dev/null
+++ b/drivers/acpi/sbshc.h
@@ -0,0 +1,27 @@
+struct acpi_smb_hc;
+enum acpi_smb_protocol {
+ SMBUS_WRITE_QUICK = 2,
+ SMBUS_READ_QUICK = 3,
+ SMBUS_SEND_BYTE = 4,
+ SMBUS_RECEIVE_BYTE = 5,
+ SMBUS_WRITE_BYTE = 6,
+ SMBUS_READ_BYTE = 7,
+ SMBUS_WRITE_WORD = 8,
+ SMBUS_READ_WORD = 9,
+ SMBUS_WRITE_BLOCK = 0xa,
+ SMBUS_READ_BLOCK = 0xb,
+ SMBUS_PROCESS_CALL = 0xc,
+ SMBUS_BLOCK_PROCESS_CALL = 0xd,
+};
+
+static const u8 SMBUS_PEC = 0x80;
+
+typedef void (*smbus_alarm_callback)(void *context);
+
+extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address,
+ u8 command, u8 * data);
+extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address,
+ u8 command, u8 * data, u8 length);
+extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc,
+ smbus_alarm_callback callback, void *context);
+extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 048295ec370..f3d3867303e 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -44,7 +44,6 @@ int acpi_sleep_prepare(u32 acpi_state)
ACPI_FLUSH_CPU_CACHE();
acpi_enable_wakeup_device_prep(acpi_state);
#endif
- acpi_gpe_sleep_prepare(acpi_state);
acpi_enter_sleep_state_prep(acpi_state);
return 0;
}
@@ -268,6 +267,11 @@ static void acpi_hibernation_leave(void)
static void acpi_hibernation_finish(void)
{
+ /*
+ * If ACPI is not enabled by the BIOS and the boot kernel, we need to
+ * enable it here.
+ */
+ acpi_enable();
acpi_leave_sleep_state(ACPI_STATE_S4);
acpi_disable_wakeup_device(ACPI_STATE_S4);
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index ff1f8504f49..a2ea125ae2d 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,6 +5,5 @@ extern int acpi_suspend (u32 state);
extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
extern void acpi_enable_wakeup_device(u8 sleep_state);
extern void acpi_disable_wakeup_device(u8 sleep_state);
-extern void acpi_gpe_sleep_prepare(u32 sleep_state);
extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/sleep/wakeup.c b/drivers/acpi/sleep/wakeup.c
index 97c27ddb144..ed8e41becf0 100644
--- a/drivers/acpi/sleep/wakeup.c
+++ b/drivers/acpi/sleep/wakeup.c
@@ -64,36 +64,29 @@ void acpi_enable_wakeup_device(u8 sleep_state)
ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device");
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev = container_of(node,
- struct acpi_device,
- wakeup_list);
-
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, wakeup_list);
+ if (!dev->wakeup.flags.valid)
+ continue;
/* If users want to disable run-wake GPE,
* we only disable it for wake and leave it for runtime
*/
- if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
- spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_RUNTIME);
- /* Re-enable it, since set_gpe_type will disable it */
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_ISR);
- spin_lock(&acpi_device_lock);
+ if (!dev->wakeup.state.enabled ||
+ sleep_state > (u32) dev->wakeup.sleep_state) {
+ if (dev->wakeup.flags.run_wake) {
+ spin_unlock(&acpi_device_lock);
+ /* set_gpe_type will disable GPE, leave it like that */
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_RUNTIME);
+ spin_lock(&acpi_device_lock);
+ }
continue;
}
-
- if (!dev->wakeup.flags.valid ||
- !dev->wakeup.state.enabled ||
- (sleep_state > (u32) dev->wakeup.sleep_state))
- continue;
-
spin_unlock(&acpi_device_lock);
- /* run-wake GPE has been enabled */
if (!dev->wakeup.flags.run_wake)
acpi_enable_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_ISR);
- dev->wakeup.state.active = 1;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -112,26 +105,25 @@ void acpi_disable_wakeup_device(u8 sleep_state)
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev = container_of(node,
- struct acpi_device,
- wakeup_list);
+ struct acpi_device *dev =
+ container_of(node, struct acpi_device, wakeup_list);
- if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
- spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_WAKE_RUN);
- /* Re-enable it, since set_gpe_type will disable it */
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
- spin_lock(&acpi_device_lock);
+ if (!dev->wakeup.flags.valid)
continue;
- }
-
- if (!dev->wakeup.flags.valid ||
- !dev->wakeup.state.active ||
- (sleep_state > (u32) dev->wakeup.sleep_state))
+ if (!dev->wakeup.state.enabled ||
+ sleep_state > (u32) dev->wakeup.sleep_state) {
+ if (dev->wakeup.flags.run_wake) {
+ spin_unlock(&acpi_device_lock);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ /* Re-enable it, since set_gpe_type will disable it */
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ spin_lock(&acpi_device_lock);
+ }
continue;
+ }
spin_unlock(&acpi_device_lock);
acpi_disable_wakeup_device_power(dev);
@@ -142,7 +134,6 @@ void acpi_disable_wakeup_device(u8 sleep_state)
acpi_clear_gpe(dev->wakeup.gpe_device,
dev->wakeup.gpe_number, ACPI_NOT_ISR);
}
- dev->wakeup.state.active = 0;
spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
@@ -160,48 +151,20 @@ static int __init acpi_wakeup_device_init(void)
struct acpi_device *dev = container_of(node,
struct acpi_device,
wakeup_list);
-
/* In case user doesn't load button driver */
- if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) {
- spin_unlock(&acpi_device_lock);
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_WAKE_RUN);
- acpi_enable_gpe(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number, ACPI_NOT_ISR);
- dev->wakeup.state.enabled = 1;
- spin_lock(&acpi_device_lock);
- }
+ if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled)
+ continue;
+ spin_unlock(&acpi_device_lock);
+ acpi_set_gpe_type(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number,
+ ACPI_GPE_TYPE_WAKE_RUN);
+ acpi_enable_gpe(dev->wakeup.gpe_device,
+ dev->wakeup.gpe_number, ACPI_NOT_ISR);
+ dev->wakeup.state.enabled = 1;
+ spin_lock(&acpi_device_lock);
}
spin_unlock(&acpi_device_lock);
-
return 0;
}
late_initcall(acpi_wakeup_device_init);
-
-/*
- * Disable all wakeup GPEs before entering requested sleep state.
- * @sleep_state: ACPI state
- * Since acpi_enter_sleep_state() will disable all
- * RUNTIME GPEs, we simply mark all GPES that
- * are not enabled for wakeup from requested state as RUNTIME.
- */
-void acpi_gpe_sleep_prepare(u32 sleep_state)
-{
- struct list_head *node, *next;
-
- list_for_each_safe(node, next, &acpi_wakeup_device_list) {
- struct acpi_device *dev = container_of(node,
- struct acpi_device,
- wakeup_list);
-
- /* The GPE can wakeup system from this state, don't touch it */
- if ((u32) dev->wakeup.sleep_state >= sleep_state)
- continue;
- /* acpi_set_gpe_type will automatically disable GPE */
- acpi_set_gpe_type(dev->wakeup.gpe_device,
- dev->wakeup.gpe_number,
- ACPI_GPE_TYPE_RUNTIME);
- }
-}
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 8cc9492ffbf..5f1d85f2ffe 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
u32 table_count;
struct acpi_table_header *table;
acpi_physical_address address;
- acpi_physical_address rsdt_address;
+ acpi_physical_address uninitialized_var(rsdt_address);
u32 length;
u8 *table_entry;
acpi_status status;
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index ad898e10c1a..5f79b445121 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -195,6 +195,7 @@ struct acpi_thermal {
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
struct timer_list timer;
+ struct mutex lock;
};
static const struct file_operations acpi_thermal_state_fops = {
@@ -711,6 +712,7 @@ static void acpi_thermal_check(void *data)
int result = 0;
struct acpi_thermal *tz = data;
unsigned long sleep_time = 0;
+ unsigned long timeout_jiffies = 0;
int i = 0;
struct acpi_thermal_state state;
@@ -720,11 +722,15 @@ static void acpi_thermal_check(void *data)
return;
}
+ /* Check if someone else is already running */
+ if (!mutex_trylock(&tz->lock))
+ return;
+
state = tz->state;
result = acpi_thermal_get_temperature(tz);
if (result)
- return;
+ goto unlock;
memset(&tz->state, 0, sizeof(tz->state));
@@ -787,10 +793,13 @@ static void acpi_thermal_check(void *data)
* a thermal event occurs). Note that _TSP and _TZD values are
* given in 1/10th seconds (we must covert to milliseconds).
*/
- if (tz->state.passive)
+ if (tz->state.passive) {
sleep_time = tz->trips.passive.tsp * 100;
- else if (tz->polling_frequency > 0)
+ timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
+ } else if (tz->polling_frequency > 0) {
sleep_time = tz->polling_frequency * 100;
+ timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
+ }
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
tz->name, tz->temperature, sleep_time));
@@ -804,17 +813,16 @@ static void acpi_thermal_check(void *data)
del_timer(&(tz->timer));
} else {
if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer),
- jiffies + (HZ * sleep_time) / 1000);
+ mod_timer(&(tz->timer), timeout_jiffies);
else {
tz->timer.data = (unsigned long)tz;
tz->timer.function = acpi_thermal_run;
- tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
+ tz->timer.expires = timeout_jiffies;
add_timer(&(tz->timer));
}
}
-
- return;
+ unlock:
+ mutex_unlock(&tz->lock);
}
/* --------------------------------------------------------------------------
@@ -1251,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device)
strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
acpi_driver_data(device) = tz;
-
+ mutex_init(&tz->lock);
result = acpi_thermal_get_info(tz);
if (result)
goto end;
@@ -1321,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
}
acpi_thermal_remove_fs(device);
-
+ mutex_destroy(&tz->lock);
kfree(tz);
return 0;
}
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index b8a2095cb5e..bac956b30c5 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -409,14 +409,17 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status;
+ int status = AE_OK;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
arg0.integer.value = level;
- status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
+ if (device->cap._BCM)
+ status = acpi_evaluate_object(device->dev->handle, "_BCM",
+ &args, NULL);
+ device->brightness->curr = level;
return status;
}
@@ -424,11 +427,11 @@ static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long *level)
{
- int status;
-
- status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level);
-
- return status;
+ if (device->cap._BQC)
+ return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
+ level);
+ *level = device->brightness->curr;
+ return AE_OK;
}
static int
@@ -1633,9 +1636,20 @@ static int
acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event)
{
- int min, max, min_above, max_below, i, l;
+ int min, max, min_above, max_below, i, l, delta = 255;
max = max_below = 0;
min = min_above = 255;
+ /* Find closest level to level_current */
+ for (i = 0; i < device->brightness->count; i++) {
+ l = device->brightness->levels[i];
+ if (abs(l - level_current) < abs(delta)) {
+ delta = l - level_current;
+ if (!delta)
+ break;
+ }
+ }
+ /* Ajust level_current to closest available level */
+ level_current += delta;
for (i = 0; i < device->brightness->count; i++) {
l = device->brightness->levels[i];
if (l < min)
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 10bc3f64c45..47c80604052 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1479,7 +1479,7 @@ static void ahci_port_intr(struct ata_port *ap)
return;
}
- /* hmmm... a spurious interupt */
+ /* hmmm... a spurious interrupt */
/* if !NCQ, ignore. No modern ATA device has broken HSM
* implementation for non-NCQ commands.
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545ea99..69092bce1ad 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1392,7 +1392,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
* @tf: Taskfile registers for the command and the result
* @cdb: CDB for packet command
* @dma_dir: Data tranfer direction of the command
- * @sg: sg list for the data buffer of the command
+ * @sgl: sg list for the data buffer of the command
* @n_elem: Number of sg entries
* @timeout: Timeout in msecs (0 for default)
*
@@ -4296,7 +4296,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
if (pad_buf) {
struct scatterlist *psg = &qc->pad_sgent;
- void *addr = kmap_atomic(psg->page, KM_IRQ0);
+ void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
memcpy(addr + psg->offset, pad_buf, qc->pad_len);
kunmap_atomic(addr, KM_IRQ0);
}
@@ -4686,11 +4686,11 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
* data in this function or read data in ata_sg_clean.
*/
offset = lsg->offset + lsg->length - qc->pad_len;
- psg->page = nth_page(lsg->page, offset >> PAGE_SHIFT);
+ sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
psg->offset = offset_in_page(offset);
if (qc->tf.flags & ATA_TFLAG_WRITE) {
- void *addr = kmap_atomic(psg->page, KM_IRQ0);
+ void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
memcpy(pad_buf, addr + psg->offset, qc->pad_len);
kunmap_atomic(addr, KM_IRQ0);
}
@@ -4836,7 +4836,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
if (qc->curbytes == qc->nbytes - qc->sect_size)
ap->hsm_task_state = HSM_ST_LAST;
- page = qc->cursg->page;
+ page = sg_page(qc->cursg);
offset = qc->cursg->offset + qc->cursg_ofs;
/* get the current page and offset */
@@ -4988,7 +4988,7 @@ next_sg:
sg = qc->cursg;
- page = sg->page;
+ page = sg_page(sg);
offset = sg->offset + qc->cursg_ofs;
/* get the current page and offset */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9fbb39cd0f5..5b758b9ad0b 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1544,7 +1544,7 @@ static unsigned int ata_scsi_rbuf_get(struct scsi_cmnd *cmd, u8 **buf_out)
struct scatterlist *sg = scsi_sglist(cmd);
if (sg) {
- buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = NULL;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index f9e4cd52794..8227c45109e 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -856,7 +856,7 @@ err_out:
* @pdev: PCI device
*
* Some PCI ATA devices report simplex mode but in fact can be told to
- * enter non simplex mode. This implements the neccessary logic to
+ * enter non simplex mode. This implements the necessary logic to
* perform the task on such devices. Calling it on other devices will
* have -undefined- behaviour.
*/
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 9e412c26b2a..7acbbd9ee46 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -215,7 +215,7 @@ static void cmd64x_set_dmamode(struct ata_port *ap, struct ata_device *adev)
regU &= ~(0x05 << adev->devno);
if (adev->dma_mode >= XFER_UDMA_0) {
- /* Merge thge timing value */
+ /* Merge the timing value */
regU |= udma_data[adev->dma_mode - XFER_UDMA_0] << shift;
/* Merge the control bits */
regU |= 1 << adev->devno; /* UDMA on */
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 57e827e4109..e1818fdd915 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -138,7 +138,7 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary. Specifically we have a problem that there is only
+ * necessary. Specifically we have a problem that there is only
* one MWDMA/UDMA bit.
*/
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 3578593a882..01324530d05 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -25,7 +25,7 @@
* Documentation:
* Available from AMD web site.
* TODO
- * Review errata to see if serializing is neccessary
+ * Review errata to see if serializing is necessary
*/
#include <linux/kernel.h>
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 53070f6b1fc..d753e568588 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -40,7 +40,7 @@
#include <asm/msr.h>
#define DRV_NAME "pata_cs5536"
-#define DRV_VERSION "0.0.5"
+#define DRV_VERSION "0.0.6"
enum {
CFG = 0,
@@ -214,7 +214,7 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
cs5536_read(pdev, DTC, &dtc);
dtc &= ~(IDE_DRV_MASK << dshift);
- dtc |= mwdma_timings[mode] << dshift;
+ dtc |= mwdma_timings[mode - XFER_MW_DMA_0] << dshift;
cs5536_write(pdev, DTC, dtc);
}
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 988ef736b93..ca9aae09dae 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -105,7 +105,7 @@ struct it821x_dev
/*
* We allow users to force the card into non raid mode without
- * flashing the alternative BIOS. This is also neccessary right now
+ * flashing the alternative BIOS. This is also necessary right now
* for embedded platforms that cannot run a PC BIOS but are using this
* device.
*/
@@ -383,7 +383,7 @@ static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc)
* @ap: ATA port
* @device: Device number (not pointer)
*
- * Device selection hook. If neccessary perform clock switching
+ * Device selection hook. If necessary perform clock switching
*/
static void it821x_passthru_dev_select(struct ata_port *ap,
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index d5483087a3f..c0d9e0cf208 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -129,7 +129,7 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ * necessary. Our logic also clears TIME0/TIME1 for the other device so
* that, even if we get this wrong, cycles to the other device will
* be made PIO0.
*/
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 6e8e55745b7..9fe66fd7501 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -124,7 +124,7 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary.
+ * necessary.
*/
static unsigned int ns87410_qc_issue_prot(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 3cd5eb2b6c9..44da09ace52 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -200,7 +200,7 @@ static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ * necessary. Our logic also clears TIME0/TIME1 for the other device so
* that, even if we get this wrong, cycles to the other device will
* be made PIO0.
*/
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index d5b76497f4a..8109b08fc02 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -161,7 +161,7 @@ static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary. Our logic also clears TIME0/TIME1 for the other device so
+ * necessary. Our logic also clears TIME0/TIME1 for the other device so
* that, even if we get this wrong, cycles to the other device will
* be made PIO0.
*/
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 21ebc485ca4..725a8586cd6 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -156,7 +156,7 @@ static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev)
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings if
- * neccessary. Specifically we have a problem that there is only
+ * necessary. Specifically we have a problem that there is only
* one MWDMA/UDMA bit.
*/
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 4dc2e73298f..5c1e9cb59ec 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -16,7 +16,7 @@
*
* If you have strange problems with nVidia chipset systems please
* see the SI support documentation and update your system BIOS
- * if neccessary
+ * if necessary
*
* TODO
* If we know all our devices are LBA28 (or LBA28 sized) we could use
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 5d41b6612d7..ea7a9a652e6 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -420,7 +420,7 @@ static struct ata_port_operations via_port_ops_noirq = {
* @pdev: PCI device
* @flags: configuration flags
*
- * Set the FIFO properties for this device if neccessary. Used both on
+ * Set the FIFO properties for this device if necessary. Used both on
* set up and on and the resume path
*/
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 8d98a9fb0a4..f147dc7bf46 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -92,7 +92,7 @@ static struct scsi_host_template sis_sht = {
.queuecommand = ata_scsi_queuecmd,
.can_queue = ATA_DEF_QUEUE,
.this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = ATA_MAX_PRD,
+ .sg_tablesize = LIBATA_MAX_PRD,
.cmd_per_lun = ATA_SHT_CMD_PER_LUN,
.emulated = ATA_SHT_EMULATED,
.use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -166,11 +166,11 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
return addr;
}
-static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
- u32 val, val2 = 0;
+ u32 val2 = 0;
u8 pmr;
if (sc_reg == SCR_ERROR) /* doesn't exist in PCI cfg space */
@@ -178,13 +178,16 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
pci_read_config_byte(pdev, SIS_PMR, &pmr);
- pci_read_config_dword(pdev, cfg_addr, &val);
+ pci_read_config_dword(pdev, cfg_addr, val);
if ((pdev->device == 0x0182) || (pdev->device == 0x0183) ||
(pdev->device == 0x1182) || (pmr & SIS_PMR_COMBINED))
pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
- return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
+ *val |= val2;
+ *val &= 0xfffffffb; /* avoid problems with powerdowned ports */
+
+ return 0;
}
static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -214,7 +217,7 @@ static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
return -EINVAL;
if (ap->flags & SIS_FLAG_CFGSCR)
- return sis_scr_cfg_read(ap, sc_reg);
+ return sis_scr_cfg_read(ap, sc_reg, val);
pci_read_config_byte(pdev, SIS_PMR, &pmr);
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c
index 94ebc9dc40f..f8f7139c07c 100644
--- a/drivers/atm/firestream.c
+++ b/drivers/atm/firestream.c
@@ -1596,7 +1596,7 @@ static irqreturn_t fs_irq (int irq, void *dev_id)
/* print the bits in the ISR register. */
if (fs_debug & FS_DEBUG_IRQ) {
- /* The FS_DEBUG things are unneccesary here. But this way it is
+ /* The FS_DEBUG things are unnecessary here. But this way it is
clear for grep that these are debug prints. */
fs_dprintk (FS_DEBUG_IRQ, "IRQ status:");
for (i=0;i<27;i++)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index c41d0728efe..7868707c7ed 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -137,7 +137,7 @@ static ssize_t show_mem_state(struct sys_device *dev, char *buf)
return len;
}
-static inline int memory_notify(unsigned long val, void *v)
+int memory_notify(unsigned long val, void *v)
{
return blocking_notifier_call_chain(&memory_chain, val, v);
}
@@ -183,7 +183,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
break;
case MEM_OFFLINE:
mem->state = MEM_GOING_OFFLINE;
- memory_notify(MEM_GOING_OFFLINE, NULL);
start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
ret = remove_memory(start_paddr,
PAGES_PER_SECTION << PAGE_SHIFT);
@@ -191,7 +190,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
mem->state = old_state;
break;
}
- memory_notify(MEM_MAPPING_INVALID, NULL);
break;
default:
printk(KERN_WARNING "%s(%p, %ld) unknown action: %ld\n",
@@ -199,11 +197,6 @@ memory_block_action(struct memory_block *mem, unsigned long action)
WARN_ON(1);
ret = -EINVAL;
}
- /*
- * For now, only notify on successful memory operations
- */
- if (!ret)
- memory_notify(action, NULL);
return ret;
}
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c
index 84d6aa500e2..53505422867 100644
--- a/drivers/block/DAC960.c
+++ b/drivers/block/DAC960.c
@@ -345,6 +345,7 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
Command->V1.ScatterGatherList =
(DAC960_V1_ScatterGatherSegment_T *)ScatterGatherCPU;
Command->V1.ScatterGatherListDMA = ScatterGatherDMA;
+ sg_init_table(Command->cmd_sglist, DAC960_V1_ScatterGatherLimit);
} else {
Command->cmd_sglist = Command->V2.ScatterList;
Command->V2.ScatterGatherList =
@@ -353,6 +354,7 @@ static bool DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
Command->V2.RequestSense =
(DAC960_SCSI_RequestSense_T *)RequestSenseCPU;
Command->V2.RequestSenseDMA = RequestSenseDMA;
+ sg_init_table(Command->cmd_sglist, DAC960_V2_ScatterGatherLimit);
}
}
return true;
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index ca4d7f0d09b..ce4b1e484e6 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -204,23 +204,6 @@ config BLK_DEV_COW_COMMON
bool
default BLK_DEV_UBD
-config MMAPPER
- tristate "Example IO memory driver (BROKEN)"
- depends on UML && BROKEN
- ---help---
- The User-Mode Linux port can provide support for IO Memory
- emulation with this option. This allows a host file to be
- specified as an I/O region on the kernel command line. That file
- will be mapped into UML's kernel address space where a driver can
- locate it and do whatever it wants with the memory, including
- providing an interface to it for UML processes to use.
-
- For more information, see
- <http://user-mode-linux.sourceforge.net/iomem.html>.
-
- If you'd like to be able to provide a simulated IO port space for
- User-Mode Linux processes, say Y. If unsure, say N.
-
config BLK_DEV_LOOP
tristate "Loopback device support"
---help---
@@ -351,7 +334,7 @@ config BLK_DEV_RAM_COUNT
default "16"
depends on BLK_DEV_RAM
help
- The default value is 16 RAM disks. Change this if you know what
+ The default value is 16 RAM disks. Change this if you know what you
are doing. If you boot from a filesystem that needs to be extracted
in memory, you will need at least one RAM disk (e.g. root on cramfs).
@@ -361,7 +344,7 @@ config BLK_DEV_RAM_SIZE
default "4096"
help
The default value is 4096 kilobytes. Only change this if you know
- what are you doing.
+ what you are doing.
config BLK_DEV_RAM_BLOCKSIZE
int "Default RAM disk block size (bytes)"
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 7c2cfde08f1..5a6fe17fc63 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -2610,7 +2610,7 @@ static void do_cciss_request(struct request_queue *q)
(int)creq->nr_sectors);
#endif /* CCISS_DEBUG */
- memset(tmp_sg, 0, sizeof(tmp_sg));
+ sg_init_table(tmp_sg, MAXSGENTRIES);
seg = blk_rq_map_sg(q, creq, tmp_sg);
/* get the DMA records for the setup */
@@ -2621,7 +2621,7 @@ static void do_cciss_request(struct request_queue *q)
for (i = 0; i < seg; i++) {
c->SG[i].Len = tmp_sg[i].length;
- temp64.val = (__u64) pci_map_page(h->pdev, tmp_sg[i].page,
+ temp64.val = (__u64) pci_map_page(h->pdev, sg_page(&tmp_sg[i]),
tmp_sg[i].offset,
tmp_sg[i].length, dir);
c->SG[i].Addr.lower = temp64.val32.lower;
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 568603d3043..efab27fa108 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -918,6 +918,7 @@ queue_next:
DBGPX(
printk("sector=%d, nr_sectors=%d\n", creq->sector, creq->nr_sectors);
);
+ sg_init_table(tmp_sg, SG_MAX);
seg = blk_rq_map_sg(q, creq, tmp_sg);
/* Now do all the DMA Mappings */
@@ -929,7 +930,7 @@ DBGPX(
{
c->req.sg[i].size = tmp_sg[i].length;
c->req.sg[i].addr = (__u32) pci_map_page(h->pci_dev,
- tmp_sg[i].page,
+ sg_page(&tmp_sg[i]),
tmp_sg[i].offset,
tmp_sg[i].length, dir);
}
diff --git a/drivers/block/cryptoloop.c b/drivers/block/cryptoloop.c
index 40535036e89..1b58b010797 100644
--- a/drivers/block/cryptoloop.c
+++ b/drivers/block/cryptoloop.c
@@ -26,6 +26,7 @@
#include <linux/crypto.h>
#include <linux/blkdev.h>
#include <linux/loop.h>
+#include <linux/scatterlist.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
@@ -119,14 +120,17 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
.tfm = tfm,
.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
};
- struct scatterlist sg_out = { NULL, };
- struct scatterlist sg_in = { NULL, };
+ struct scatterlist sg_out;
+ struct scatterlist sg_in;
encdec_cbc_t encdecfunc;
struct page *in_page, *out_page;
unsigned in_offs, out_offs;
int err;
+ sg_init_table(&sg_out, 1);
+ sg_init_table(&sg_in, 1);
+
if (cmd == READ) {
in_page = raw_page;
in_offs = raw_off;
@@ -146,11 +150,11 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
u32 iv[4] = { 0, };
iv[0] = cpu_to_le32(IV & 0xffffffff);
- sg_in.page = in_page;
+ sg_set_page(&sg_in, in_page);
sg_in.offset = in_offs;
sg_in.length = sz;
- sg_out.page = out_page;
+ sg_set_page(&sg_out, out_page);
sg_out.offset = out_offs;
sg_out.length = sz;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 589cbbd9cd4..56e23042728 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -29,7 +29,7 @@
*
* Maximum number of loop devices when compiled-in now selectable by passing
* max_loop=<1-255> to the kernel on boot.
- * Erik I. Bols, <eriki@himolde.no>, Oct 31, 1999
+ * Erik I. Bolsø, <eriki@himolde.no>, Oct 31, 1999
*
* Completely rewrite request handling to be make_request_fn style and
* non blocking, pushing work to a helper thread. Lots of fixes from
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index cb136a919f2..6332acad078 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -188,7 +188,7 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size,
if (signal_pending(current)) {
siginfo_t info;
printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n",
- current->pid, current->comm,
+ task_pid_nr(current), current->comm,
dequeue_signal_lock(current, &current->blocked, &info));
result = -EINTR;
sock_shutdown(lo, !send);
@@ -508,7 +508,6 @@ error_out:
nbd_end_request(req);
spin_lock(q->queue_lock);
}
- return;
}
static int nbd_ioctl(struct inode *inode, struct file *file,
diff --git a/drivers/block/rd.c b/drivers/block/rd.c
index 08176d23a46..47f8ac6cce5 100644
--- a/drivers/block/rd.c
+++ b/drivers/block/rd.c
@@ -365,7 +365,7 @@ static int rd_open(struct inode *inode, struct file *filp)
/*
* Deep badness. rd_blkdev_pagecache_IO() needs to allocate
* pagecache pages within a request_fn. We cannot recur back
- * into the filesytem which is mounted atop the ramdisk, because
+ * into the filesystem which is mounted atop the ramdisk, because
* that would deadlock on fs locks. And we really don't want
* to reenter rd_blkdev_pagecache_IO when we're already within
* that function.
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 317a790c153..7276f7d207c 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -388,6 +388,7 @@ static int __send_request(struct request *req)
op = VD_OP_BWRITE;
}
+ sg_init_table(sg, port->ring_cookies);
nsg = blk_rq_map_sg(req->q, req, sg);
len = 0;
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index 402209fec59..282a69558e8 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -522,6 +522,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
host->n_msgs++;
assert(host->n_msgs <= CARM_MAX_REQ);
+ sg_init_table(crq->sg, CARM_MAX_REQ_SG);
return crq;
}
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index c57dd2b3a0c..14143f2c484 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -25,6 +25,7 @@
#include <linux/usb_usual.h>
#include <linux/blkdev.h>
#include <linux/timer.h>
+#include <linux/scatterlist.h>
#include <scsi/scsi.h>
#define DRV_NAME "ub"
@@ -656,6 +657,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
if ((cmd = ub_get_cmd(lun)) == NULL)
return -1;
memset(cmd, 0, sizeof(struct ub_scsi_cmd));
+ sg_init_table(cmd->sgv, UB_MAX_REQ_SG);
blkdev_dequeue_request(rq);
@@ -1309,9 +1311,8 @@ static void ub_data_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
else
pipe = sc->send_bulk_pipe;
sc->last_pipe = pipe;
- usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
- page_address(sg->page) + sg->offset, sg->length,
- ub_urb_complete, sc);
+ usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe, sg_virt(sg),
+ sg->length, ub_urb_complete, sc);
sc->work_urb.actual_length = 0;
sc->work_urb.error_count = 0;
sc->work_urb.status = 0;
@@ -1427,7 +1428,7 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
scmd->state = UB_CMDST_INIT;
scmd->nsg = 1;
sg = &scmd->sgv[0];
- sg->page = virt_to_page(sc->top_sense);
+ sg_set_page(sg, virt_to_page(sc->top_sense));
sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
sg->length = UB_SENSE_SIZE;
scmd->len = UB_SENSE_SIZE;
@@ -1863,7 +1864,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
cmd->state = UB_CMDST_INIT;
cmd->nsg = 1;
sg = &cmd->sgv[0];
- sg->page = virt_to_page(p);
+ sg_set_page(sg, virt_to_page(p));
sg->offset = (unsigned long)p & (PAGE_SIZE-1);
sg->length = 8;
cmd->len = 8;
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index e824b672e05..ab5d404faa1 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -41,6 +41,7 @@
#include <linux/dma-mapping.h>
#include <linux/completion.h>
#include <linux/device.h>
+#include <linux/scatterlist.h>
#include <asm/uaccess.h>
#include <asm/vio.h>
@@ -270,6 +271,7 @@ static int send_request(struct request *req)
d = req->rq_disk->private_data;
/* Now build the scatter-gather list */
+ sg_init_table(sg, VIOMAXBLOCKDMA);
nsg = blk_rq_map_sg(req->q, req, sg);
nsg = dma_map_sg(d->dev, sg, nsg, direction);
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index b9fbe6e7f9a..075598e1c50 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -22,6 +22,30 @@ config BT_HCIUSB_SCO
Say Y here to compile support for SCO over HCI USB.
+config BT_HCIBTUSB
+ tristate "HCI USB driver (alternate version)"
+ depends on USB && EXPERIMENTAL && BT_HCIUSB=n
+ help
+ Bluetooth HCI USB driver.
+ This driver is required if you want to use Bluetooth devices with
+ USB interface.
+
+ This driver is still experimental and has no SCO support.
+
+ Say Y here to compile support for Bluetooth USB devices into the
+ kernel or say M to compile it as module (btusb).
+
+config BT_HCIBTSDIO
+ tristate "HCI SDIO driver"
+ depends on MMC
+ help
+ Bluetooth HCI SDIO driver.
+ This driver is required if you want to use Bluetooth device with
+ SDIO interface.
+
+ Say Y here to compile support for Bluetooth SDIO devices into the
+ kernel or say M to compile it as module (btsdio).
+
config BT_HCIUART
tristate "HCI UART driver"
help
@@ -55,6 +79,17 @@ config BT_HCIUART_BCSP
Say Y here to compile support for HCI BCSP protocol.
+config BT_HCIUART_LL
+ bool "HCILL protocol support"
+ depends on BT_HCIUART
+ help
+ HCILL (HCI Low Level) is a serial protocol for communication
+ between Bluetooth device and host. This protocol is required for
+ serial Bluetooth devices that are based on Texas Instruments'
+ BRF chips.
+
+ Say Y here to compile support for HCILL protocol.
+
config BT_HCIBCM203X
tristate "HCI BCM203x USB driver"
depends on USB
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 08c10e178e0..77444afbf10 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -13,7 +13,11 @@ obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
+obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
+obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
+
hci_uart-y := hci_ldisc.o
hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o
+hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
hci_uart-objs := $(hci_uart-y)
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c
index 851de4d5b7d..bcf57927b7a 100644
--- a/drivers/bluetooth/bluecard_cs.c
+++ b/drivers/bluetooth/bluecard_cs.c
@@ -503,10 +503,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst)
unsigned int iobase;
unsigned char reg;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
- return IRQ_NONE;
- }
+ BUG_ON(!info->hdev);
if (!test_bit(CARD_READY, &(info->hw_state)))
return IRQ_HANDLED;
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c
index e8ebd5d3de8..1375b5345a0 100644
--- a/drivers/bluetooth/bpa10x.c
+++ b/drivers/bluetooth/bpa10x.c
@@ -2,7 +2,7 @@
*
* Digianswer Bluetooth USB driver
*
- * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org>
*
*
* This program is free software; you can redistribute it and/or modify
@@ -21,13 +21,14 @@
*
*/
-#include <linux/module.h>
-
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <linux/sched.h>
#include <linux/errno.h>
+#include <linux/skbuff.h>
#include <linux/usb.h>
@@ -39,7 +40,7 @@
#define BT_DBG(D...)
#endif
-#define VERSION "0.8"
+#define VERSION "0.9"
static int ignore = 0;
@@ -52,393 +53,285 @@ static struct usb_device_id bpa10x_table[] = {
MODULE_DEVICE_TABLE(usb, bpa10x_table);
-#define BPA10X_CMD_EP 0x00
-#define BPA10X_EVT_EP 0x81
-#define BPA10X_TX_EP 0x02
-#define BPA10X_RX_EP 0x82
-
-#define BPA10X_CMD_BUF_SIZE 252
-#define BPA10X_EVT_BUF_SIZE 16
-#define BPA10X_TX_BUF_SIZE 384
-#define BPA10X_RX_BUF_SIZE 384
-
struct bpa10x_data {
- struct hci_dev *hdev;
- struct usb_device *udev;
+ struct hci_dev *hdev;
+ struct usb_device *udev;
- rwlock_t lock;
+ struct usb_anchor tx_anchor;
+ struct usb_anchor rx_anchor;
- struct sk_buff_head cmd_queue;
- struct urb *cmd_urb;
- struct urb *evt_urb;
- struct sk_buff *evt_skb;
- unsigned int evt_len;
-
- struct sk_buff_head tx_queue;
- struct urb *tx_urb;
- struct urb *rx_urb;
+ struct sk_buff *rx_skb[2];
};
-#define HCI_VENDOR_HDR_SIZE 5
+#define HCI_VENDOR_HDR_SIZE 5
struct hci_vendor_hdr {
- __u8 type;
- __le16 snum;
- __le16 dlen;
+ __u8 type;
+ __le16 snum;
+ __le16 dlen;
} __attribute__ ((packed));
-static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
+static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
{
- struct hci_acl_hdr *ah;
- struct hci_sco_hdr *sh;
- struct hci_vendor_hdr *vh;
- struct sk_buff *skb;
- int len;
+ struct bpa10x_data *data = hdev->driver_data;
+
+ BT_DBG("%s queue %d buffer %p count %d", hdev->name,
+ queue, buf, count);
+
+ if (queue < 0 || queue > 1)
+ return -EILSEQ;
+
+ hdev->stat.byte_rx += count;
while (count) {
- switch (*buf++) {
- case HCI_ACLDATA_PKT:
- ah = (struct hci_acl_hdr *) buf;
- len = HCI_ACL_HDR_SIZE + __le16_to_cpu(ah->dlen);
- skb = bt_skb_alloc(len, GFP_ATOMIC);
- if (skb) {
- memcpy(skb_put(skb, len), buf, len);
- skb->dev = (void *) data->hdev;
- bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
- hci_recv_frame(skb);
- }
- break;
+ struct sk_buff *skb = data->rx_skb[queue];
+ struct { __u8 type; int expect; } *scb;
+ int type, len = 0;
- case HCI_SCODATA_PKT:
- sh = (struct hci_sco_hdr *) buf;
- len = HCI_SCO_HDR_SIZE + sh->dlen;
- skb = bt_skb_alloc(len, GFP_ATOMIC);
- if (skb) {
- memcpy(skb_put(skb, len), buf, len);
- skb->dev = (void *) data->hdev;
- bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
- hci_recv_frame(skb);
+ if (!skb) {
+ /* Start of the frame */
+
+ type = *((__u8 *) buf);
+ count--; buf++;
+
+ switch (type) {
+ case HCI_EVENT_PKT:
+ if (count >= HCI_EVENT_HDR_SIZE) {
+ struct hci_event_hdr *h = buf;
+ len = HCI_EVENT_HDR_SIZE + h->plen;
+ } else
+ return -EILSEQ;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ if (count >= HCI_ACL_HDR_SIZE) {
+ struct hci_acl_hdr *h = buf;
+ len = HCI_ACL_HDR_SIZE +
+ __le16_to_cpu(h->dlen);
+ } else
+ return -EILSEQ;
+ break;
+
+ case HCI_SCODATA_PKT:
+ if (count >= HCI_SCO_HDR_SIZE) {
+ struct hci_sco_hdr *h = buf;
+ len = HCI_SCO_HDR_SIZE + h->dlen;
+ } else
+ return -EILSEQ;
+ break;
+
+ case HCI_VENDOR_PKT:
+ if (count >= HCI_VENDOR_HDR_SIZE) {
+ struct hci_vendor_hdr *h = buf;
+ len = HCI_VENDOR_HDR_SIZE +
+ __le16_to_cpu(h->dlen);
+ } else
+ return -EILSEQ;
+ break;
}
- break;
- case HCI_VENDOR_PKT:
- vh = (struct hci_vendor_hdr *) buf;
- len = HCI_VENDOR_HDR_SIZE + __le16_to_cpu(vh->dlen);
skb = bt_skb_alloc(len, GFP_ATOMIC);
- if (skb) {
- memcpy(skb_put(skb, len), buf, len);
- skb->dev = (void *) data->hdev;
- bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
- hci_recv_frame(skb);
+ if (!skb) {
+ BT_ERR("%s no memory for packet", hdev->name);
+ return -ENOMEM;
}
- break;
-
- default:
- len = count - 1;
- break;
- }
- buf += len;
- count -= (len + 1);
- }
-}
-
-static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int size)
-{
- BT_DBG("data %p buf %p size %d", data, buf, size);
+ skb->dev = (void *) hdev;
- if (data->evt_skb) {
- struct sk_buff *skb = data->evt_skb;
+ data->rx_skb[queue] = skb;
- memcpy(skb_put(skb, size), buf, size);
+ scb = (void *) skb->cb;
+ scb->type = type;
+ scb->expect = len;
+ } else {
+ /* Continuation */
- if (skb->len == data->evt_len) {
- data->evt_skb = NULL;
- data->evt_len = 0;
- hci_recv_frame(skb);
- }
- } else {
- struct sk_buff *skb;
- struct hci_event_hdr *hdr;
- unsigned char pkt_type;
- int pkt_len = 0;
-
- if (size < HCI_EVENT_HDR_SIZE + 1) {
- BT_ERR("%s event packet block with size %d is too short",
- data->hdev->name, size);
- return -EILSEQ;
+ scb = (void *) skb->cb;
+ len = scb->expect;
}
- pkt_type = *buf++;
- size--;
-
- if (pkt_type != HCI_EVENT_PKT) {
- BT_ERR("%s unexpected event packet start byte 0x%02x",
- data->hdev->name, pkt_type);
- return -EPROTO;
- }
+ len = min(len, count);
- hdr = (struct hci_event_hdr *) buf;
- pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
+ memcpy(skb_put(skb, len), buf, len);
- skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
- if (!skb) {
- BT_ERR("%s no memory for new event packet",
- data->hdev->name);
- return -ENOMEM;
- }
+ scb->expect -= len;
- skb->dev = (void *) data->hdev;
- bt_cb(skb)->pkt_type = pkt_type;
+ if (scb->expect == 0) {
+ /* Complete frame */
- memcpy(skb_put(skb, size), buf, size);
+ data->rx_skb[queue] = NULL;
- if (pkt_len == size) {
+ bt_cb(skb)->pkt_type = scb->type;
hci_recv_frame(skb);
- } else {
- data->evt_skb = skb;
- data->evt_len = pkt_len;
}
+
+ count -= len; buf += len;
}
return 0;
}
-static void bpa10x_wakeup(struct bpa10x_data *data)
+static void bpa10x_tx_complete(struct urb *urb)
{
- struct urb *urb;
- struct sk_buff *skb;
- int err;
+ struct sk_buff *skb = urb->context;
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
- BT_DBG("data %p", data);
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
- urb = data->cmd_urb;
- if (urb->status == -EINPROGRESS)
- skb = NULL;
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ goto done;
+
+ if (!urb->status)
+ hdev->stat.byte_tx += urb->transfer_buffer_length;
else
- skb = skb_dequeue(&data->cmd_queue);
+ hdev->stat.err_tx++;
- if (skb) {
- struct usb_ctrlrequest *cr;
+done:
+ kfree(urb->setup_packet);
- if (skb->len > BPA10X_CMD_BUF_SIZE) {
- BT_ERR("%s command packet with size %d is too big",
- data->hdev->name, skb->len);
- kfree_skb(skb);
- return;
- }
+ kfree_skb(skb);
+}
+
+static void bpa10x_rx_complete(struct urb *urb)
+{
+ struct hci_dev *hdev = urb->context;
+ struct bpa10x_data *data = hdev->driver_data;
+ int err;
- cr = (struct usb_ctrlrequest *) urb->setup_packet;
- cr->wLength = __cpu_to_le16(skb->len);
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
- skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
- urb->transfer_buffer_length = skb->len;
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -ENODEV) {
- BT_ERR("%s submit failed for command urb %p with error %d",
- data->hdev->name, urb, err);
- skb_queue_head(&data->cmd_queue, skb);
- } else
- kfree_skb(skb);
+ if (urb->status == 0) {
+ if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
+ urb->transfer_buffer,
+ urb->actual_length) < 0) {
+ BT_ERR("%s corrupted event packet", hdev->name);
+ hdev->stat.err_rx++;
+ }
}
- urb = data->tx_urb;
- if (urb->status == -EINPROGRESS)
- skb = NULL;
- else
- skb = skb_dequeue(&data->tx_queue);
-
- if (skb) {
- skb_copy_from_linear_data(skb, urb->transfer_buffer, skb->len);
- urb->transfer_buffer_length = skb->len;
-
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -ENODEV) {
- BT_ERR("%s submit failed for command urb %p with error %d",
- data->hdev->name, urb, err);
- skb_queue_head(&data->tx_queue, skb);
- } else
- kfree_skb(skb);
+ usb_anchor_urb(urb, &data->rx_anchor);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p failed to resubmit (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
}
}
-static void bpa10x_complete(struct urb *urb)
+static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
{
- struct bpa10x_data *data = urb->context;
- unsigned char *buf = urb->transfer_buffer;
- int err, count = urb->actual_length;
+ struct bpa10x_data *data = hdev->driver_data;
+ struct urb *urb;
+ unsigned char *buf;
+ unsigned int pipe;
+ int err, size = 16;
- BT_DBG("data %p urb %p buf %p count %d", data, urb, buf, count);
+ BT_DBG("%s", hdev->name);
- read_lock(&data->lock);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
- if (!test_bit(HCI_RUNNING, &data->hdev->flags))
- goto unlock;
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
- if (urb->status < 0 || !count)
- goto resubmit;
+ pipe = usb_rcvintpipe(data->udev, 0x81);
- if (usb_pipein(urb->pipe)) {
- data->hdev->stat.byte_rx += count;
+ usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+ bpa10x_rx_complete, hdev, 1);
- if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
- bpa10x_recv_event(data, buf, count);
+ urb->transfer_flags |= URB_FREE_BUFFER;
- if (usb_pipetype(urb->pipe) == PIPE_BULK)
- bpa10x_recv_bulk(data, buf, count);
- } else {
- data->hdev->stat.byte_tx += count;
+ usb_anchor_urb(urb, &data->rx_anchor);
- bpa10x_wakeup(data);
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
+ kfree(buf);
}
-resubmit:
- if (usb_pipein(urb->pipe)) {
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -ENODEV) {
- BT_ERR("%s urb %p type %d resubmit status %d",
- data->hdev->name, urb, usb_pipetype(urb->pipe), err);
- }
- }
+ usb_free_urb(urb);
-unlock:
- read_unlock(&data->lock);
+ return err;
}
-static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
- size_t size, gfp_t flags, void *data)
+static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
{
+ struct bpa10x_data *data = hdev->driver_data;
struct urb *urb;
- struct usb_ctrlrequest *cr;
unsigned char *buf;
+ unsigned int pipe;
+ int err, size = 64;
- BT_DBG("udev %p data %p", udev, data);
+ BT_DBG("%s", hdev->name);
- urb = usb_alloc_urb(0, flags);
+ urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
- return NULL;
+ return -ENOMEM;
- buf = kmalloc(size, flags);
+ buf = kmalloc(size, GFP_KERNEL);
if (!buf) {
usb_free_urb(urb);
- return NULL;
+ return -ENOMEM;
}
- switch (usb_pipetype(pipe)) {
- case PIPE_CONTROL:
- cr = kmalloc(sizeof(*cr), flags);
- if (!cr) {
- kfree(buf);
- usb_free_urb(urb);
- return NULL;
- }
+ pipe = usb_rcvbulkpipe(data->udev, 0x82);
- cr->bRequestType = USB_TYPE_VENDOR;
- cr->bRequest = 0;
- cr->wIndex = 0;
- cr->wValue = 0;
- cr->wLength = __cpu_to_le16(0);
+ usb_fill_bulk_urb(urb, data->udev, pipe,
+ buf, size, bpa10x_rx_complete, hdev);
- usb_fill_control_urb(urb, udev, pipe, (void *) cr, buf, 0, bpa10x_complete, data);
- break;
+ urb->transfer_flags |= URB_FREE_BUFFER;
- case PIPE_INTERRUPT:
- usb_fill_int_urb(urb, udev, pipe, buf, size, bpa10x_complete, data, 1);
- break;
+ usb_anchor_urb(urb, &data->rx_anchor);
- case PIPE_BULK:
- usb_fill_bulk_urb(urb, udev, pipe, buf, size, bpa10x_complete, data);
- break;
-
- default:
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
kfree(buf);
- usb_free_urb(urb);
- return NULL;
}
- return urb;
-}
-
-static inline void bpa10x_free_urb(struct urb *urb)
-{
- BT_DBG("urb %p", urb);
-
- if (!urb)
- return;
-
- kfree(urb->setup_packet);
- kfree(urb->transfer_buffer);
-
usb_free_urb(urb);
+
+ return err;
}
static int bpa10x_open(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
- struct usb_device *udev = data->udev;
- unsigned long flags;
int err;
- BT_DBG("hdev %p data %p", hdev, data);
+ BT_DBG("%s", hdev->name);
if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
return 0;
- data->cmd_urb = bpa10x_alloc_urb(udev, usb_sndctrlpipe(udev, BPA10X_CMD_EP),
- BPA10X_CMD_BUF_SIZE, GFP_KERNEL, data);
- if (!data->cmd_urb) {
- err = -ENOMEM;
- goto done;
- }
-
- data->evt_urb = bpa10x_alloc_urb(udev, usb_rcvintpipe(udev, BPA10X_EVT_EP),
- BPA10X_EVT_BUF_SIZE, GFP_KERNEL, data);
- if (!data->evt_urb) {
- bpa10x_free_urb(data->cmd_urb);
- err = -ENOMEM;
- goto done;
- }
-
- data->rx_urb = bpa10x_alloc_urb(udev, usb_rcvbulkpipe(udev, BPA10X_RX_EP),
- BPA10X_RX_BUF_SIZE, GFP_KERNEL, data);
- if (!data->rx_urb) {
- bpa10x_free_urb(data->evt_urb);
- bpa10x_free_urb(data->cmd_urb);
- err = -ENOMEM;
- goto done;
- }
-
- data->tx_urb = bpa10x_alloc_urb(udev, usb_sndbulkpipe(udev, BPA10X_TX_EP),
- BPA10X_TX_BUF_SIZE, GFP_KERNEL, data);
- if (!data->rx_urb) {
- bpa10x_free_urb(data->rx_urb);
- bpa10x_free_urb(data->evt_urb);
- bpa10x_free_urb(data->cmd_urb);
- err = -ENOMEM;
- goto done;
- }
+ err = bpa10x_submit_intr_urb(hdev);
+ if (err < 0)
+ goto error;
- write_lock_irqsave(&data->lock, flags);
+ err = bpa10x_submit_bulk_urb(hdev);
+ if (err < 0)
+ goto error;
- err = usb_submit_urb(data->evt_urb, GFP_ATOMIC);
- if (err < 0) {
- BT_ERR("%s submit failed for event urb %p with error %d",
- data->hdev->name, data->evt_urb, err);
- } else {
- err = usb_submit_urb(data->rx_urb, GFP_ATOMIC);
- if (err < 0) {
- BT_ERR("%s submit failed for rx urb %p with error %d",
- data->hdev->name, data->evt_urb, err);
- usb_kill_urb(data->evt_urb);
- }
- }
+ return 0;
- write_unlock_irqrestore(&data->lock, flags);
+error:
+ usb_kill_anchored_urbs(&data->rx_anchor);
-done:
- if (err < 0)
- clear_bit(HCI_RUNNING, &hdev->flags);
+ clear_bit(HCI_RUNNING, &hdev->flags);
return err;
}
@@ -446,27 +339,13 @@ done:
static int bpa10x_close(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
- unsigned long flags;
- BT_DBG("hdev %p data %p", hdev, data);
+ BT_DBG("%s", hdev->name);
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
return 0;
- write_lock_irqsave(&data->lock, flags);
-
- skb_queue_purge(&data->cmd_queue);
- usb_kill_urb(data->cmd_urb);
- usb_kill_urb(data->evt_urb);
- usb_kill_urb(data->rx_urb);
- usb_kill_urb(data->tx_urb);
-
- write_unlock_irqrestore(&data->lock, flags);
-
- bpa10x_free_urb(data->cmd_urb);
- bpa10x_free_urb(data->evt_urb);
- bpa10x_free_urb(data->rx_urb);
- bpa10x_free_urb(data->tx_urb);
+ usb_kill_anchored_urbs(&data->rx_anchor);
return 0;
}
@@ -475,9 +354,9 @@ static int bpa10x_flush(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
- BT_DBG("hdev %p data %p", hdev, data);
+ BT_DBG("%s", hdev->name);
- skb_queue_purge(&data->cmd_queue);
+ usb_kill_anchored_urbs(&data->tx_anchor);
return 0;
}
@@ -485,45 +364,78 @@ static int bpa10x_flush(struct hci_dev *hdev)
static int bpa10x_send_frame(struct sk_buff *skb)
{
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
- struct bpa10x_data *data;
-
- BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
+ struct bpa10x_data *data = hdev->driver_data;
+ struct usb_ctrlrequest *dr;
+ struct urb *urb;
+ unsigned int pipe;
+ int err;
- if (!hdev) {
- BT_ERR("Frame for unknown HCI device");
- return -ENODEV;
- }
+ BT_DBG("%s", hdev->name);
if (!test_bit(HCI_RUNNING, &hdev->flags))
return -EBUSY;
- data = hdev->driver_data;
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
/* Prepend skb with frame type */
- memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+ *skb_push(skb, 1) = bt_cb(skb)->pkt_type;
switch (bt_cb(skb)->pkt_type) {
case HCI_COMMAND_PKT:
+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+ if (!dr) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ dr->bRequestType = USB_TYPE_VENDOR;
+ dr->bRequest = 0;
+ dr->wIndex = 0;
+ dr->wValue = 0;
+ dr->wLength = __cpu_to_le16(skb->len);
+
+ pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+ usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+ skb->data, skb->len, bpa10x_tx_complete, skb);
+
hdev->stat.cmd_tx++;
- skb_queue_tail(&data->cmd_queue, skb);
break;
case HCI_ACLDATA_PKT:
+ pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+ usb_fill_bulk_urb(urb, data->udev, pipe,
+ skb->data, skb->len, bpa10x_tx_complete, skb);
+
hdev->stat.acl_tx++;
- skb_queue_tail(&data->tx_queue, skb);
break;
case HCI_SCODATA_PKT:
+ pipe = usb_sndbulkpipe(data->udev, 0x02);
+
+ usb_fill_bulk_urb(urb, data->udev, pipe,
+ skb->data, skb->len, bpa10x_tx_complete, skb);
+
hdev->stat.sco_tx++;
- skb_queue_tail(&data->tx_queue, skb);
break;
- };
- read_lock(&data->lock);
+ default:
+ return -EILSEQ;
+ }
+
+ usb_anchor_urb(urb, &data->tx_anchor);
- bpa10x_wakeup(data);
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed", hdev->name, urb);
+ kfree(urb->setup_packet);
+ usb_unanchor_urb(urb);
+ }
- read_unlock(&data->lock);
+ usb_free_urb(urb);
return 0;
}
@@ -532,16 +444,17 @@ static void bpa10x_destruct(struct hci_dev *hdev)
{
struct bpa10x_data *data = hdev->driver_data;
- BT_DBG("hdev %p data %p", hdev, data);
+ BT_DBG("%s", hdev->name);
+ kfree(data->rx_skb[0]);
+ kfree(data->rx_skb[1]);
kfree(data);
}
static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct hci_dev *hdev;
struct bpa10x_data *data;
+ struct hci_dev *hdev;
int err;
BT_DBG("intf %p id %p", intf, id);
@@ -549,48 +462,43 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
if (ignore)
return -ENODEV;
- if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
return -ENODEV;
data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- BT_ERR("Can't allocate data structure");
+ if (!data)
return -ENOMEM;
- }
-
- data->udev = udev;
- rwlock_init(&data->lock);
+ data->udev = interface_to_usbdev(intf);
- skb_queue_head_init(&data->cmd_queue);
- skb_queue_head_init(&data->tx_queue);
+ init_usb_anchor(&data->tx_anchor);
+ init_usb_anchor(&data->rx_anchor);
hdev = hci_alloc_dev();
if (!hdev) {
- BT_ERR("Can't allocate HCI device");
kfree(data);
return -ENOMEM;
}
- data->hdev = hdev;
-
hdev->type = HCI_USB;
hdev->driver_data = data;
+
+ data->hdev = hdev;
+
SET_HCIDEV_DEV(hdev, &intf->dev);
- hdev->open = bpa10x_open;
- hdev->close = bpa10x_close;
- hdev->flush = bpa10x_flush;
- hdev->send = bpa10x_send_frame;
- hdev->destruct = bpa10x_destruct;
+ hdev->open = bpa10x_open;
+ hdev->close = bpa10x_close;
+ hdev->flush = bpa10x_flush;
+ hdev->send = bpa10x_send_frame;
+ hdev->destruct = bpa10x_destruct;
hdev->owner = THIS_MODULE;
err = hci_register_dev(hdev);
if (err < 0) {
- BT_ERR("Can't register HCI device");
- kfree(data);
hci_free_dev(hdev);
+ kfree(data);
return err;
}
@@ -602,19 +510,17 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *
static void bpa10x_disconnect(struct usb_interface *intf)
{
struct bpa10x_data *data = usb_get_intfdata(intf);
- struct hci_dev *hdev = data->hdev;
BT_DBG("intf %p", intf);
- if (!hdev)
+ if (!data)
return;
usb_set_intfdata(intf, NULL);
- if (hci_unregister_dev(hdev) < 0)
- BT_ERR("Can't unregister HCI device %s", hdev->name);
+ hci_unregister_dev(data->hdev);
- hci_free_dev(hdev);
+ hci_free_dev(data->hdev);
}
static struct usb_driver bpa10x_driver = {
@@ -626,15 +532,9 @@ static struct usb_driver bpa10x_driver = {
static int __init bpa10x_init(void)
{
- int err;
-
BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);
- err = usb_register(&bpa10x_driver);
- if (err < 0)
- BT_ERR("Failed to register USB driver");
-
- return err;
+ return usb_register(&bpa10x_driver);
}
static void __exit bpa10x_exit(void)
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c
index 39516074636..a18f9b8c9e1 100644
--- a/drivers/bluetooth/bt3c_cs.c
+++ b/drivers/bluetooth/bt3c_cs.c
@@ -344,10 +344,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst)
unsigned int iobase;
int iir;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
- return IRQ_NONE;
- }
+ BUG_ON(!info->hdev);
iobase = info->p_dev->io.BasePort1;
diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c
new file mode 100644
index 00000000000..b786f618790
--- /dev/null
+++ b/drivers/bluetooth/btsdio.c
@@ -0,0 +1,406 @@
+/*
+ *
+ * Generic Bluetooth SDIO driver
+ *
+ * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
+ * Copyright (C) 2007 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#ifndef CONFIG_BT_HCIBTSDIO_DEBUG
+#undef BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static const struct sdio_device_id btsdio_table[] = {
+ /* Generic Bluetooth Type-A SDIO device */
+ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_A) },
+
+ /* Generic Bluetooth Type-B SDIO device */
+ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
+
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(sdio, btsdio_table);
+
+struct btsdio_data {
+ struct hci_dev *hdev;
+ struct sdio_func *func;
+
+ struct work_struct work;
+
+ struct sk_buff_head txq;
+};
+
+#define REG_RDAT 0x00 /* Receiver Data */
+#define REG_TDAT 0x00 /* Transmitter Data */
+#define REG_PC_RRT 0x10 /* Read Packet Control */
+#define REG_PC_WRT 0x11 /* Write Packet Control */
+#define REG_RTC_STAT 0x12 /* Retry Control Status */
+#define REG_RTC_SET 0x12 /* Retry Control Set */
+#define REG_INTRD 0x13 /* Interrupt Indication */
+#define REG_CL_INTRD 0x13 /* Interrupt Clear */
+#define REG_EN_INTRD 0x14 /* Interrupt Enable */
+#define REG_MD_STAT 0x20 /* Bluetooth Mode Status */
+
+static int btsdio_tx_packet(struct btsdio_data *data, struct sk_buff *skb)
+{
+ int err;
+
+ BT_DBG("%s", data->hdev->name);
+
+ /* Prepend Type-A header */
+ skb_push(skb, 4);
+ skb->data[0] = (skb->len & 0x0000ff);
+ skb->data[1] = (skb->len & 0x00ff00) >> 8;
+ skb->data[2] = (skb->len & 0xff0000) >> 16;
+ skb->data[3] = bt_cb(skb)->pkt_type;
+
+ err = sdio_writesb(data->func, REG_TDAT, skb->data, skb->len);
+ if (err < 0) {
+ sdio_writeb(data->func, 0x01, REG_PC_WRT, NULL);
+ return err;
+ }
+
+ data->hdev->stat.byte_tx += skb->len;
+
+ kfree_skb(skb);
+
+ return 0;
+}
+
+static void btsdio_work(struct work_struct *work)
+{
+ struct btsdio_data *data = container_of(work, struct btsdio_data, work);
+ struct sk_buff *skb;
+ int err;
+
+ BT_DBG("%s", data->hdev->name);
+
+ sdio_claim_host(data->func);
+
+ while ((skb = skb_dequeue(&data->txq))) {
+ err = btsdio_tx_packet(data, skb);
+ if (err < 0) {
+ data->hdev->stat.err_tx++;
+ skb_queue_head(&data->txq, skb);
+ break;
+ }
+ }
+
+ sdio_release_host(data->func);
+}
+
+static int btsdio_rx_packet(struct btsdio_data *data)
+{
+ u8 hdr[4] __attribute__ ((aligned(4)));
+ struct sk_buff *skb;
+ int err, len;
+
+ BT_DBG("%s", data->hdev->name);
+
+ err = sdio_readsb(data->func, hdr, REG_RDAT, 4);
+ if (err < 0)
+ return err;
+
+ len = hdr[0] | (hdr[1] << 8) | (hdr[2] << 16);
+ if (len < 4 || len > 65543)
+ return -EILSEQ;
+
+ skb = bt_skb_alloc(len - 4, GFP_KERNEL);
+ if (!skb) {
+ /* Out of memory. Prepare a read retry and just
+ * return with the expectation that the next time
+ * we're called we'll have more memory. */
+ return -ENOMEM;
+ }
+
+ skb_put(skb, len - 4);
+
+ err = sdio_readsb(data->func, skb->data, REG_RDAT, len - 4);
+ if (err < 0) {
+ kfree(skb);
+ return err;
+ }
+
+ data->hdev->stat.byte_rx += len;
+
+ skb->dev = (void *) data->hdev;
+ bt_cb(skb)->pkt_type = hdr[3];
+
+ err = hci_recv_frame(skb);
+ if (err < 0) {
+ kfree(skb);
+ return err;
+ }
+
+ sdio_writeb(data->func, 0x00, REG_PC_RRT, NULL);
+
+ return 0;
+}
+
+static void btsdio_interrupt(struct sdio_func *func)
+{
+ struct btsdio_data *data = sdio_get_drvdata(func);
+ int intrd;
+
+ BT_DBG("%s", data->hdev->name);
+
+ intrd = sdio_readb(func, REG_INTRD, NULL);
+ if (intrd & 0x01) {
+ sdio_writeb(func, 0x01, REG_CL_INTRD, NULL);
+
+ if (btsdio_rx_packet(data) < 0) {
+ data->hdev->stat.err_rx++;
+ sdio_writeb(data->func, 0x01, REG_PC_RRT, NULL);
+ }
+ }
+}
+
+static int btsdio_open(struct hci_dev *hdev)
+{
+ struct btsdio_data *data = hdev->driver_data;
+ int err;
+
+ BT_DBG("%s", hdev->name);
+
+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ sdio_claim_host(data->func);
+
+ err = sdio_enable_func(data->func);
+ if (err < 0) {
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ goto release;
+ }
+
+ err = sdio_claim_irq(data->func, btsdio_interrupt);
+ if (err < 0) {
+ sdio_disable_func(data->func);
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ goto release;
+ }
+
+ if (data->func->class == SDIO_CLASS_BT_B)
+ sdio_writeb(data->func, 0x00, REG_MD_STAT, NULL);
+
+ sdio_writeb(data->func, 0x01, REG_EN_INTRD, NULL);
+
+release:
+ sdio_release_host(data->func);
+
+ return err;
+}
+
+static int btsdio_close(struct hci_dev *hdev)
+{
+ struct btsdio_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ sdio_claim_host(data->func);
+
+ sdio_writeb(data->func, 0x00, REG_EN_INTRD, NULL);
+
+ sdio_release_irq(data->func);
+ sdio_disable_func(data->func);
+
+ sdio_release_host(data->func);
+
+ return 0;
+}
+
+static int btsdio_flush(struct hci_dev *hdev)
+{
+ struct btsdio_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ skb_queue_purge(&data->txq);
+
+ return 0;
+}
+
+static int btsdio_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct btsdio_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return -EBUSY;
+
+ switch (bt_cb(skb)->pkt_type) {
+ case HCI_COMMAND_PKT:
+ hdev->stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ hdev->stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ hdev->stat.sco_tx++;
+ break;
+
+ default:
+ return -EILSEQ;
+ }
+
+ skb_queue_tail(&data->txq, skb);
+
+ schedule_work(&data->work);
+
+ return 0;
+}
+
+static void btsdio_destruct(struct hci_dev *hdev)
+{
+ struct btsdio_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ kfree(data);
+}
+
+static int btsdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ struct btsdio_data *data;
+ struct hci_dev *hdev;
+ struct sdio_func_tuple *tuple = func->tuples;
+ int err;
+
+ BT_DBG("func %p id %p class 0x%04x", func, id, func->class);
+
+ while (tuple) {
+ BT_DBG("code 0x%x size %d", tuple->code, tuple->size);
+ tuple = tuple->next;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->func = func;
+
+ INIT_WORK(&data->work, btsdio_work);
+
+ skb_queue_head_init(&data->txq);
+
+ hdev = hci_alloc_dev();
+ if (!hdev) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ hdev->type = HCI_SDIO;
+ hdev->driver_data = data;
+
+ data->hdev = hdev;
+
+ SET_HCIDEV_DEV(hdev, &func->dev);
+
+ hdev->open = btsdio_open;
+ hdev->close = btsdio_close;
+ hdev->flush = btsdio_flush;
+ hdev->send = btsdio_send_frame;
+ hdev->destruct = btsdio_destruct;
+
+ hdev->owner = THIS_MODULE;
+
+ err = hci_register_dev(hdev);
+ if (err < 0) {
+ hci_free_dev(hdev);
+ kfree(data);
+ return err;
+ }
+
+ sdio_set_drvdata(func, data);
+
+ return 0;
+}
+
+static void btsdio_remove(struct sdio_func *func)
+{
+ struct btsdio_data *data = sdio_get_drvdata(func);
+ struct hci_dev *hdev;
+
+ BT_DBG("func %p", func);
+
+ if (!data)
+ return;
+
+ hdev = data->hdev;
+
+ sdio_set_drvdata(func, NULL);
+
+ hci_unregister_dev(hdev);
+
+ hci_free_dev(hdev);
+}
+
+static struct sdio_driver btsdio_driver = {
+ .name = "btsdio",
+ .probe = btsdio_probe,
+ .remove = btsdio_remove,
+ .id_table = btsdio_table,
+};
+
+static int __init btsdio_init(void)
+{
+ BT_INFO("Generic Bluetooth SDIO driver ver %s", VERSION);
+
+ return sdio_register_driver(&btsdio_driver);
+}
+
+static void __exit btsdio_exit(void)
+{
+ sdio_unregister_driver(&btsdio_driver);
+}
+
+module_init(btsdio_init);
+module_exit(btsdio_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth SDIO driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c
index d7d2ea0d86a..08f48d577ab 100644
--- a/drivers/bluetooth/btuart_cs.c
+++ b/drivers/bluetooth/btuart_cs.c
@@ -294,10 +294,7 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst)
int boguscount = 0;
int iir, lsr;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
- return IRQ_NONE;
- }
+ BUG_ON(!info->hdev);
iobase = info->p_dev->io.BasePort1;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
new file mode 100644
index 00000000000..12e108914f1
--- /dev/null
+++ b/drivers/bluetooth/btusb.c
@@ -0,0 +1,564 @@
+/*
+ *
+ * Generic Bluetooth USB driver
+ *
+ * Copyright (C) 2005-2007 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+
+#include <linux/usb.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+//#define CONFIG_BT_HCIBTUSB_DEBUG
+#ifndef CONFIG_BT_HCIBTUSB_DEBUG
+#undef BT_DBG
+#define BT_DBG(D...)
+#endif
+
+#define VERSION "0.1"
+
+static struct usb_device_id btusb_table[] = {
+ /* Generic Bluetooth USB device */
+ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
+
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, btusb_table);
+
+static struct usb_device_id blacklist_table[] = {
+ { } /* Terminating entry */
+};
+
+#define BTUSB_INTR_RUNNING 0
+#define BTUSB_BULK_RUNNING 1
+
+struct btusb_data {
+ struct hci_dev *hdev;
+ struct usb_device *udev;
+
+ spinlock_t lock;
+
+ unsigned long flags;
+
+ struct work_struct work;
+
+ struct usb_anchor tx_anchor;
+ struct usb_anchor intr_anchor;
+ struct usb_anchor bulk_anchor;
+
+ struct usb_endpoint_descriptor *intr_ep;
+ struct usb_endpoint_descriptor *bulk_tx_ep;
+ struct usb_endpoint_descriptor *bulk_rx_ep;
+};
+
+static void btusb_intr_complete(struct urb *urb)
+{
+ struct hci_dev *hdev = urb->context;
+ struct btusb_data *data = hdev->driver_data;
+ int err;
+
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return;
+
+ if (urb->status == 0) {
+ if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
+ urb->transfer_buffer,
+ urb->actual_length) < 0) {
+ BT_ERR("%s corrupted event packet", hdev->name);
+ hdev->stat.err_rx++;
+ }
+ }
+
+ if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
+ return;
+
+ usb_anchor_urb(urb, &data->intr_anchor);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p failed to resubmit (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
+ }
+}
+
+static inline int btusb_submit_intr_urb(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+ struct urb *urb;
+ unsigned char *buf;
+ unsigned int pipe;
+ int err, size;
+
+ BT_DBG("%s", hdev->name);
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+
+ buf = kmalloc(size, GFP_ATOMIC);
+ if (!buf) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
+
+ usb_fill_int_urb(urb, data->udev, pipe, buf, size,
+ btusb_intr_complete, hdev,
+ data->intr_ep->bInterval);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &data->intr_anchor);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
+ kfree(buf);
+ }
+
+ usb_free_urb(urb);
+
+ return err;
+}
+
+static void btusb_bulk_complete(struct urb *urb)
+{
+ struct hci_dev *hdev = urb->context;
+ struct btusb_data *data = hdev->driver_data;
+ int err;
+
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return;
+
+ if (urb->status == 0) {
+ if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
+ urb->transfer_buffer,
+ urb->actual_length) < 0) {
+ BT_ERR("%s corrupted ACL packet", hdev->name);
+ hdev->stat.err_rx++;
+ }
+ }
+
+ if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
+ return;
+
+ usb_anchor_urb(urb, &data->bulk_anchor);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p failed to resubmit (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
+ }
+}
+
+static inline int btusb_submit_bulk_urb(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+ struct urb *urb;
+ unsigned char *buf;
+ unsigned int pipe;
+ int err, size;
+
+ BT_DBG("%s", hdev->name);
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb)
+ return -ENOMEM;
+
+ size = le16_to_cpu(data->bulk_rx_ep->wMaxPacketSize);
+
+ buf = kmalloc(size, GFP_KERNEL);
+ if (!buf) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
+
+ usb_fill_bulk_urb(urb, data->udev, pipe,
+ buf, size, btusb_bulk_complete, hdev);
+
+ urb->transfer_flags |= URB_FREE_BUFFER;
+
+ usb_anchor_urb(urb, &data->bulk_anchor);
+
+ err = usb_submit_urb(urb, GFP_KERNEL);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed (%d)",
+ hdev->name, urb, -err);
+ usb_unanchor_urb(urb);
+ kfree(buf);
+ }
+
+ usb_free_urb(urb);
+
+ return err;
+}
+
+static void btusb_tx_complete(struct urb *urb)
+{
+ struct sk_buff *skb = urb->context;
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+
+ BT_DBG("%s urb %p status %d count %d", hdev->name,
+ urb, urb->status, urb->actual_length);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ goto done;
+
+ if (!urb->status)
+ hdev->stat.byte_tx += urb->transfer_buffer_length;
+ else
+ hdev->stat.err_tx++;
+
+done:
+ kfree(urb->setup_packet);
+
+ kfree_skb(skb);
+}
+
+static int btusb_open(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+ int err;
+
+ BT_DBG("%s", hdev->name);
+
+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
+ return 0;
+
+ err = btusb_submit_intr_urb(hdev);
+ if (err < 0) {
+ clear_bit(BTUSB_INTR_RUNNING, &hdev->flags);
+ clear_bit(HCI_RUNNING, &hdev->flags);
+ }
+
+ return err;
+}
+
+static int btusb_close(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
+ return 0;
+
+ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+ usb_kill_anchored_urbs(&data->bulk_anchor);
+
+ clear_bit(BTUSB_INTR_RUNNING, &data->flags);
+ usb_kill_anchored_urbs(&data->intr_anchor);
+
+ return 0;
+}
+
+static int btusb_flush(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ usb_kill_anchored_urbs(&data->tx_anchor);
+
+ return 0;
+}
+
+static int btusb_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
+ struct btusb_data *data = hdev->driver_data;
+ struct usb_ctrlrequest *dr;
+ struct urb *urb;
+ unsigned int pipe;
+ int err;
+
+ BT_DBG("%s", hdev->name);
+
+ if (!test_bit(HCI_RUNNING, &hdev->flags))
+ return -EBUSY;
+
+ switch (bt_cb(skb)->pkt_type) {
+ case HCI_COMMAND_PKT:
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
+ if (!dr) {
+ usb_free_urb(urb);
+ return -ENOMEM;
+ }
+
+ dr->bRequestType = USB_TYPE_CLASS;
+ dr->bRequest = 0;
+ dr->wIndex = 0;
+ dr->wValue = 0;
+ dr->wLength = __cpu_to_le16(skb->len);
+
+ pipe = usb_sndctrlpipe(data->udev, 0x00);
+
+ usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
+ skb->data, skb->len, btusb_tx_complete, skb);
+
+ hdev->stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ if (!urb)
+ return -ENOMEM;
+
+ pipe = usb_sndbulkpipe(data->udev,
+ data->bulk_tx_ep->bEndpointAddress);
+
+ usb_fill_bulk_urb(urb, data->udev, pipe,
+ skb->data, skb->len, btusb_tx_complete, skb);
+
+ hdev->stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ hdev->stat.sco_tx++;
+ kfree_skb(skb);
+ return 0;
+
+ default:
+ return -EILSEQ;
+ }
+
+ usb_anchor_urb(urb, &data->tx_anchor);
+
+ err = usb_submit_urb(urb, GFP_ATOMIC);
+ if (err < 0) {
+ BT_ERR("%s urb %p submission failed", hdev->name, urb);
+ kfree(urb->setup_packet);
+ usb_unanchor_urb(urb);
+ }
+
+ usb_free_urb(urb);
+
+ return err;
+}
+
+static void btusb_destruct(struct hci_dev *hdev)
+{
+ struct btusb_data *data = hdev->driver_data;
+
+ BT_DBG("%s", hdev->name);
+
+ kfree(data);
+}
+
+static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
+{
+ struct btusb_data *data = hdev->driver_data;
+
+ BT_DBG("%s evt %d", hdev->name, evt);
+
+ if (evt == HCI_NOTIFY_CONN_ADD || evt == HCI_NOTIFY_CONN_DEL)
+ schedule_work(&data->work);
+}
+
+static void btusb_work(struct work_struct *work)
+{
+ struct btusb_data *data = container_of(work, struct btusb_data, work);
+ struct hci_dev *hdev = data->hdev;
+
+ if (hdev->conn_hash.acl_num == 0) {
+ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+ usb_kill_anchored_urbs(&data->bulk_anchor);
+ return;
+ }
+
+ if (!test_and_set_bit(BTUSB_BULK_RUNNING, &data->flags)) {
+ if (btusb_submit_bulk_urb(hdev) < 0)
+ clear_bit(BTUSB_BULK_RUNNING, &data->flags);
+ else
+ btusb_submit_bulk_urb(hdev);
+ }
+}
+
+static int btusb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_endpoint_descriptor *ep_desc;
+ struct btusb_data *data;
+ struct hci_dev *hdev;
+ int i, err;
+
+ BT_DBG("intf %p id %p", intf, id);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ return -ENODEV;
+
+ if (!id->driver_info) {
+ const struct usb_device_id *match;
+ match = usb_match_id(intf, blacklist_table);
+ if (match)
+ id = match;
+ }
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
+ ep_desc = &intf->cur_altsetting->endpoint[i].desc;
+
+ if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
+ data->intr_ep = ep_desc;
+ continue;
+ }
+
+ if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
+ data->bulk_tx_ep = ep_desc;
+ continue;
+ }
+
+ if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
+ data->bulk_rx_ep = ep_desc;
+ continue;
+ }
+ }
+
+ if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
+ kfree(data);
+ return -ENODEV;
+ }
+
+ data->udev = interface_to_usbdev(intf);
+
+ spin_lock_init(&data->lock);
+
+ INIT_WORK(&data->work, btusb_work);
+
+ init_usb_anchor(&data->tx_anchor);
+ init_usb_anchor(&data->intr_anchor);
+ init_usb_anchor(&data->bulk_anchor);
+
+ hdev = hci_alloc_dev();
+ if (!hdev) {
+ kfree(data);
+ return -ENOMEM;
+ }
+
+ hdev->type = HCI_USB;
+ hdev->driver_data = data;
+
+ data->hdev = hdev;
+
+ SET_HCIDEV_DEV(hdev, &intf->dev);
+
+ hdev->open = btusb_open;
+ hdev->close = btusb_close;
+ hdev->flush = btusb_flush;
+ hdev->send = btusb_send_frame;
+ hdev->destruct = btusb_destruct;
+ hdev->notify = btusb_notify;
+
+ hdev->owner = THIS_MODULE;
+
+ set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+
+ err = hci_register_dev(hdev);
+ if (err < 0) {
+ hci_free_dev(hdev);
+ kfree(data);
+ return err;
+ }
+
+ usb_set_intfdata(intf, data);
+
+ return 0;
+}
+
+static void btusb_disconnect(struct usb_interface *intf)
+{
+ struct btusb_data *data = usb_get_intfdata(intf);
+ struct hci_dev *hdev;
+
+ BT_DBG("intf %p", intf);
+
+ if (!data)
+ return;
+
+ hdev = data->hdev;
+
+ usb_set_intfdata(intf, NULL);
+
+ hci_unregister_dev(hdev);
+
+ hci_free_dev(hdev);
+}
+
+static struct usb_driver btusb_driver = {
+ .name = "btusb",
+ .probe = btusb_probe,
+ .disconnect = btusb_disconnect,
+ .id_table = btusb_table,
+};
+
+static int __init btusb_init(void)
+{
+ BT_INFO("Generic Bluetooth USB driver ver %s", VERSION);
+
+ return usb_register(&btusb_driver);
+}
+
+static void __exit btusb_exit(void)
+{
+ usb_deregister(&btusb_driver);
+}
+
+module_init(btusb_init);
+module_exit(btusb_exit);
+
+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
+MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c
index 7f9c54b9964..dae45cdf02b 100644
--- a/drivers/bluetooth/dtl1_cs.c
+++ b/drivers/bluetooth/dtl1_cs.c
@@ -298,10 +298,7 @@ static irqreturn_t dtl1_interrupt(int irq, void *dev_inst)
int boguscount = 0;
int iir, lsr;
- if (!info || !info->hdev) {
- BT_ERR("Call of irq %d for unknown device", irq);
- return IRQ_NONE;
- }
+ BUG_ON(!info->hdev);
iobase = info->p_dev->io.BasePort1;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index d66064ccb31..696f7528f02 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -237,7 +237,8 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
if (hciextn && chan == 5) {
struct hci_command_hdr *hdr = (struct hci_command_hdr *) data;
- if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == OGF_VENDOR_CMD) {
+ /* Vendor specific commands */
+ if (hci_opcode_ogf(__le16_to_cpu(hdr->opcode)) == 0x3f) {
u8 desc = *(data + HCI_COMMAND_HDR_SIZE);
if ((desc & 0xf0) == 0xc0) {
data += HCI_COMMAND_HDR_SIZE + 1;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 6055b9c0ac0..e68821d074b 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -549,7 +549,10 @@ static int __init hci_uart_init(void)
#ifdef CONFIG_BT_HCIUART_BCSP
bcsp_init();
#endif
-
+#ifdef CONFIG_BT_HCIUART_LL
+ ll_init();
+#endif
+
return 0;
}
@@ -563,6 +566,9 @@ static void __exit hci_uart_exit(void)
#ifdef CONFIG_BT_HCIUART_BCSP
bcsp_deinit();
#endif
+#ifdef CONFIG_BT_HCIUART_LL
+ ll_deinit();
+#endif
/* Release tty registration of line discipline */
if ((err = tty_unregister_ldisc(N_HCI)))
diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c
new file mode 100644
index 00000000000..8c3e62a17b4
--- /dev/null
+++ b/drivers/bluetooth/hci_ll.c
@@ -0,0 +1,531 @@
+/*
+ * Texas Instruments' Bluetooth HCILL UART protocol
+ *
+ * HCILL (HCI Low Level) is a Texas Instruments' power management
+ * protocol extension to H4.
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ *
+ * Written by Ohad Ben-Cohen <ohad@bencohen.org>
+ *
+ * Acknowledgements:
+ * This file is based on hci_h4.c, which was written
+ * by Maxim Krasnyansky and Marcel Holtmann.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/poll.h>
+
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/ioctl.h>
+#include <linux/skbuff.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+
+#include "hci_uart.h"
+
+/* HCILL commands */
+#define HCILL_GO_TO_SLEEP_IND 0x30
+#define HCILL_GO_TO_SLEEP_ACK 0x31
+#define HCILL_WAKE_UP_IND 0x32
+#define HCILL_WAKE_UP_ACK 0x33
+
+/* HCILL receiver States */
+#define HCILL_W4_PACKET_TYPE 0
+#define HCILL_W4_EVENT_HDR 1
+#define HCILL_W4_ACL_HDR 2
+#define HCILL_W4_SCO_HDR 3
+#define HCILL_W4_DATA 4
+
+/* HCILL states */
+enum hcill_states_e {
+ HCILL_ASLEEP,
+ HCILL_ASLEEP_TO_AWAKE,
+ HCILL_AWAKE,
+ HCILL_AWAKE_TO_ASLEEP
+};
+
+struct hcill_cmd {
+ u8 cmd;
+} __attribute__((packed));
+
+struct ll_struct {
+ unsigned long rx_state;
+ unsigned long rx_count;
+ struct sk_buff *rx_skb;
+ struct sk_buff_head txq;
+ spinlock_t hcill_lock; /* HCILL state lock */
+ unsigned long hcill_state; /* HCILL power state */
+ struct sk_buff_head tx_wait_q; /* HCILL wait queue */
+};
+
+/*
+ * Builds and sends an HCILL command packet.
+ * These are very simple packets with only 1 cmd byte
+ */
+static int send_hcill_cmd(u8 cmd, struct hci_uart *hu)
+{
+ int err = 0;
+ struct sk_buff *skb = NULL;
+ struct ll_struct *ll = hu->priv;
+ struct hcill_cmd *hcill_packet;
+
+ BT_DBG("hu %p cmd 0x%x", hu, cmd);
+
+ /* allocate packet */
+ skb = bt_skb_alloc(1, GFP_ATOMIC);
+ if (!skb) {
+ BT_ERR("cannot allocate memory for HCILL packet");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /* prepare packet */
+ hcill_packet = (struct hcill_cmd *) skb_put(skb, 1);
+ hcill_packet->cmd = cmd;
+ skb->dev = (void *) hu->hdev;
+
+ /* send packet */
+ skb_queue_tail(&ll->txq, skb);
+out:
+ return err;
+}
+
+/* Initialize protocol */
+static int ll_open(struct hci_uart *hu)
+{
+ struct ll_struct *ll;
+
+ BT_DBG("hu %p", hu);
+
+ ll = kzalloc(sizeof(*ll), GFP_ATOMIC);
+ if (!ll)
+ return -ENOMEM;
+
+ skb_queue_head_init(&ll->txq);
+ skb_queue_head_init(&ll->tx_wait_q);
+ spin_lock_init(&ll->hcill_lock);
+
+ ll->hcill_state = HCILL_AWAKE;
+
+ hu->priv = ll;
+
+ return 0;
+}
+
+/* Flush protocol data */
+static int ll_flush(struct hci_uart *hu)
+{
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p", hu);
+
+ skb_queue_purge(&ll->tx_wait_q);
+ skb_queue_purge(&ll->txq);
+
+ return 0;
+}
+
+/* Close protocol */
+static int ll_close(struct hci_uart *hu)
+{
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p", hu);
+
+ skb_queue_purge(&ll->tx_wait_q);
+ skb_queue_purge(&ll->txq);
+
+ if (ll->rx_skb)
+ kfree_skb(ll->rx_skb);
+
+ hu->priv = NULL;
+
+ kfree(ll);
+
+ return 0;
+}
+
+/*
+ * internal function, which does common work of the device wake up process:
+ * 1. places all pending packets (waiting in tx_wait_q list) in txq list.
+ * 2. changes internal state to HCILL_AWAKE.
+ * Note: assumes that hcill_lock spinlock is taken,
+ * shouldn't be called otherwise!
+ */
+static void __ll_do_awake(struct ll_struct *ll)
+{
+ struct sk_buff *skb = NULL;
+
+ while ((skb = skb_dequeue(&ll->tx_wait_q)))
+ skb_queue_tail(&ll->txq, skb);
+
+ ll->hcill_state = HCILL_AWAKE;
+}
+
+/*
+ * Called upon a wake-up-indication from the device
+ */
+static void ll_device_want_to_wakeup(struct hci_uart *hu)
+{
+ unsigned long flags;
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p", hu);
+
+ /* lock hcill state */
+ spin_lock_irqsave(&ll->hcill_lock, flags);
+
+ switch (ll->hcill_state) {
+ case HCILL_ASLEEP:
+ /* acknowledge device wake up */
+ if (send_hcill_cmd(HCILL_WAKE_UP_ACK, hu) < 0) {
+ BT_ERR("cannot acknowledge device wake up");
+ goto out;
+ }
+ break;
+ case HCILL_ASLEEP_TO_AWAKE:
+ /*
+ * this state means that a wake-up-indication
+ * is already on its way to the device,
+ * and will serve as the required wake-up-ack
+ */
+ BT_DBG("dual wake-up-indication");
+ break;
+ default:
+ /* any other state are illegal */
+ BT_ERR("received HCILL_WAKE_UP_IND in state %ld", ll->hcill_state);
+ break;
+ }
+
+ /* send pending packets and change state to HCILL_AWAKE */
+ __ll_do_awake(ll);
+
+out:
+ spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+ /* actually send the packets */
+ hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon a sleep-indication from the device
+ */
+static void ll_device_want_to_sleep(struct hci_uart *hu)
+{
+ unsigned long flags;
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p", hu);
+
+ /* lock hcill state */
+ spin_lock_irqsave(&ll->hcill_lock, flags);
+
+ /* sanity check */
+ if (ll->hcill_state != HCILL_AWAKE)
+ BT_ERR("ERR: HCILL_GO_TO_SLEEP_IND in state %ld", ll->hcill_state);
+
+ /* acknowledge device sleep */
+ if (send_hcill_cmd(HCILL_GO_TO_SLEEP_ACK, hu) < 0) {
+ BT_ERR("cannot acknowledge device sleep");
+ goto out;
+ }
+
+ /* update state */
+ ll->hcill_state = HCILL_ASLEEP;
+
+out:
+ spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+ /* actually send the sleep ack packet */
+ hci_uart_tx_wakeup(hu);
+}
+
+/*
+ * Called upon wake-up-acknowledgement from the device
+ */
+static void ll_device_woke_up(struct hci_uart *hu)
+{
+ unsigned long flags;
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p", hu);
+
+ /* lock hcill state */
+ spin_lock_irqsave(&ll->hcill_lock, flags);
+
+ /* sanity check */
+ if (ll->hcill_state != HCILL_ASLEEP_TO_AWAKE)
+ BT_ERR("received HCILL_WAKE_UP_ACK in state %ld", ll->hcill_state);
+
+ /* send pending packets and change state to HCILL_AWAKE */
+ __ll_do_awake(ll);
+
+ spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+ /* actually send the packets */
+ hci_uart_tx_wakeup(hu);
+}
+
+/* Enqueue frame for transmittion (padding, crc, etc) */
+/* may be called from two simultaneous tasklets */
+static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb)
+{
+ unsigned long flags = 0;
+ struct ll_struct *ll = hu->priv;
+
+ BT_DBG("hu %p skb %p", hu, skb);
+
+ /* Prepend skb with frame type */
+ memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
+
+ /* lock hcill state */
+ spin_lock_irqsave(&ll->hcill_lock, flags);
+
+ /* act according to current state */
+ switch (ll->hcill_state) {
+ case HCILL_AWAKE:
+ BT_DBG("device awake, sending normally");
+ skb_queue_tail(&ll->txq, skb);
+ break;
+ case HCILL_ASLEEP:
+ BT_DBG("device asleep, waking up and queueing packet");
+ /* save packet for later */
+ skb_queue_tail(&ll->tx_wait_q, skb);
+ /* awake device */
+ if (send_hcill_cmd(HCILL_WAKE_UP_IND, hu) < 0) {
+ BT_ERR("cannot wake up device");
+ break;
+ }
+ ll->hcill_state = HCILL_ASLEEP_TO_AWAKE;
+ break;
+ case HCILL_ASLEEP_TO_AWAKE:
+ BT_DBG("device waking up, queueing packet");
+ /* transient state; just keep packet for later */
+ skb_queue_tail(&ll->tx_wait_q, skb);
+ break;
+ default:
+ BT_ERR("illegal hcill state: %ld (losing packet)", ll->hcill_state);
+ kfree_skb(skb);
+ break;
+ }
+
+ spin_unlock_irqrestore(&ll->hcill_lock, flags);
+
+ return 0;
+}
+
+static inline int ll_check_data_len(struct ll_struct *ll, int len)
+{
+ register int room = skb_tailroom(ll->rx_skb);
+
+ BT_DBG("len %d room %d", len, room);
+
+ if (!len) {
+ hci_recv_frame(ll->rx_skb);
+ } else if (len > room) {
+ BT_ERR("Data length is too large");
+ kfree_skb(ll->rx_skb);
+ } else {
+ ll->rx_state = HCILL_W4_DATA;
+ ll->rx_count = len;
+ return len;
+ }
+
+ ll->rx_state = HCILL_W4_PACKET_TYPE;
+ ll->rx_skb = NULL;
+ ll->rx_count = 0;
+
+ return 0;
+}
+
+/* Recv data */
+static int ll_recv(struct hci_uart *hu, void *data, int count)
+{
+ struct ll_struct *ll = hu->priv;
+ register char *ptr;
+ struct hci_event_hdr *eh;
+ struct hci_acl_hdr *ah;
+ struct hci_sco_hdr *sh;
+ register int len, type, dlen;
+
+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count);
+
+ ptr = data;
+ while (count) {
+ if (ll->rx_count) {
+ len = min_t(unsigned int, ll->rx_count, count);
+ memcpy(skb_put(ll->rx_skb, len), ptr, len);
+ ll->rx_count -= len; count -= len; ptr += len;
+
+ if (ll->rx_count)
+ continue;
+
+ switch (ll->rx_state) {
+ case HCILL_W4_DATA:
+ BT_DBG("Complete data");
+ hci_recv_frame(ll->rx_skb);
+
+ ll->rx_state = HCILL_W4_PACKET_TYPE;
+ ll->rx_skb = NULL;
+ continue;
+
+ case HCILL_W4_EVENT_HDR:
+ eh = (struct hci_event_hdr *) ll->rx_skb->data;
+
+ BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+
+ ll_check_data_len(ll, eh->plen);
+ continue;
+
+ case HCILL_W4_ACL_HDR:
+ ah = (struct hci_acl_hdr *) ll->rx_skb->data;
+ dlen = __le16_to_cpu(ah->dlen);
+
+ BT_DBG("ACL header: dlen %d", dlen);
+
+ ll_check_data_len(ll, dlen);
+ continue;
+
+ case HCILL_W4_SCO_HDR:
+ sh = (struct hci_sco_hdr *) ll->rx_skb->data;
+
+ BT_DBG("SCO header: dlen %d", sh->dlen);
+
+ ll_check_data_len(ll, sh->dlen);
+ continue;
+ }
+ }
+
+ /* HCILL_W4_PACKET_TYPE */
+ switch (*ptr) {
+ case HCI_EVENT_PKT:
+ BT_DBG("Event packet");
+ ll->rx_state = HCILL_W4_EVENT_HDR;
+ ll->rx_count = HCI_EVENT_HDR_SIZE;
+ type = HCI_EVENT_PKT;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ BT_DBG("ACL packet");
+ ll->rx_state = HCILL_W4_ACL_HDR;
+ ll->rx_count = HCI_ACL_HDR_SIZE;
+ type = HCI_ACLDATA_PKT;
+ break;
+
+ case HCI_SCODATA_PKT:
+ BT_DBG("SCO packet");
+ ll->rx_state = HCILL_W4_SCO_HDR;
+ ll->rx_count = HCI_SCO_HDR_SIZE;
+ type = HCI_SCODATA_PKT;
+ break;
+
+ /* HCILL signals */
+ case HCILL_GO_TO_SLEEP_IND:
+ BT_DBG("HCILL_GO_TO_SLEEP_IND packet");
+ ll_device_want_to_sleep(hu);
+ ptr++; count--;
+ continue;
+
+ case HCILL_GO_TO_SLEEP_ACK:
+ /* shouldn't happen */
+ BT_ERR("received HCILL_GO_TO_SLEEP_ACK (in state %ld)", ll->hcill_state);
+ ptr++; count--;
+ continue;
+
+ case HCILL_WAKE_UP_IND:
+ BT_DBG("HCILL_WAKE_UP_IND packet");
+ ll_device_want_to_wakeup(hu);
+ ptr++; count--;
+ continue;
+
+ case HCILL_WAKE_UP_ACK:
+ BT_DBG("HCILL_WAKE_UP_ACK packet");
+ ll_device_woke_up(hu);
+ ptr++; count--;
+ continue;
+
+ default:
+ BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+ hu->hdev->stat.err_rx++;
+ ptr++; count--;
+ continue;
+ };
+
+ ptr++; count--;
+
+ /* Allocate packet */
+ ll->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
+ if (!ll->rx_skb) {
+ BT_ERR("Can't allocate mem for new packet");
+ ll->rx_state = HCILL_W4_PACKET_TYPE;
+ ll->rx_count = 0;
+ return 0;
+ }
+
+ ll->rx_skb->dev = (void *) hu->hdev;
+ bt_cb(ll->rx_skb)->pkt_type = type;
+ }
+
+ return count;
+}
+
+static struct sk_buff *ll_dequeue(struct hci_uart *hu)
+{
+ struct ll_struct *ll = hu->priv;
+ return skb_dequeue(&ll->txq);
+}
+
+static struct hci_uart_proto llp = {
+ .id = HCI_UART_LL,
+ .open = ll_open,
+ .close = ll_close,
+ .recv = ll_recv,
+ .enqueue = ll_enqueue,
+ .dequeue = ll_dequeue,
+ .flush = ll_flush,
+};
+
+int ll_init(void)
+{
+ int err = hci_uart_register_proto(&llp);
+
+ if (!err)
+ BT_INFO("HCILL protocol initialized");
+ else
+ BT_ERR("HCILL protocol registration failed");
+
+ return err;
+}
+
+int ll_deinit(void)
+{
+ return hci_uart_unregister_proto(&llp);
+}
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h
index 1097ce72393..50113db06b9 100644
--- a/drivers/bluetooth/hci_uart.h
+++ b/drivers/bluetooth/hci_uart.h
@@ -33,12 +33,13 @@
#define HCIUARTGETDEVICE _IOR('U', 202, int)
/* UART protocols */
-#define HCI_UART_MAX_PROTO 4
+#define HCI_UART_MAX_PROTO 5
#define HCI_UART_H4 0
#define HCI_UART_BCSP 1
#define HCI_UART_3WIRE 2
#define HCI_UART_H4DS 3
+#define HCI_UART_LL 4
struct hci_uart;
@@ -85,3 +86,8 @@ int h4_deinit(void);
int bcsp_init(void);
int bcsp_deinit(void);
#endif
+
+#ifdef CONFIG_BT_HCIUART_LL
+int ll_init(void);
+int ll_deinit(void);
+#endif
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index d70745c8425..af056105316 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -1107,7 +1107,7 @@ int open_for_data(struct cdrom_device_info * cdi)
is the default case! */
cdinfo(CD_OPEN, "bummer. wrong media type.\n");
cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
- (unsigned int)current->pid);
+ (unsigned int)task_pid_nr(current));
ret=-EMEDIUMTYPE;
goto clean_up_and_return;
}
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index d15234c5965..d1bd0f08a33 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -359,7 +359,7 @@
*
* Revision 1.36.3.8 1996/06/07 16:29:00 bentson
* starting minor number at zero; added missing verify_area
- * as noted by Heiko Eissfeldt <heiko@colossus.escape.de>
+ * as noted by Heiko Eißfeldt <heiko@colossus.escape.de>
*
* Revision 1.36.3.7 1996/04/19 21:06:18 bentson
* remove unneeded boot message & fix CLOCAL hardware flow
@@ -727,8 +727,6 @@ static struct tty_driver *cy_serial_driver;
driver to probe addresses at a different address, add it to
this table. If the driver is probing some other board and
causing problems, remove the offending address from this table.
- The cy_setup function extracts additional addresses from the
- boot options line. The form is "cyclades=address,address..."
*/
static unsigned int cy_isa_addresses[] = {
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 856774fbe02..d24a6c2c2c2 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -1456,7 +1456,7 @@ int drm_freebufs(struct drm_device *dev, void *data,
buf = dma->buflist[idx];
if (buf->file_priv != file_priv) {
DRM_ERROR("Process %d freeing buffer not owned\n",
- current->pid);
+ task_pid_nr(current));
return -EINVAL;
}
drm_free_buffer(dev, buf);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 72668b15e5c..44a46268b02 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -463,7 +463,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
++file_priv->ioctl_count;
DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
- current->pid, cmd, nr,
+ task_pid_nr(current), cmd, nr,
(long)old_encode_dev(file_priv->head->device),
file_priv->authenticated);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index f383fc37190..3992f73299c 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -234,7 +234,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
if (!drm_cpu_valid())
return -EINVAL;
- DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
+ DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor);
priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
if (!priv)
@@ -244,7 +244,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
filp->private_data = priv;
priv->filp = filp;
priv->uid = current->euid;
- priv->pid = current->pid;
+ priv->pid = task_pid_nr(current);
priv->minor = minor;
priv->head = drm_heads[minor];
priv->ioctl_count = 0;
@@ -339,7 +339,8 @@ int drm_release(struct inode *inode, struct file *filp)
*/
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
- current->pid, (long)old_encode_dev(file_priv->head->device),
+ task_pid_nr(current),
+ (long)old_encode_dev(file_priv->head->device),
dev->open_count);
if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c
index 3ad31907070..4b8e7db5a23 100644
--- a/drivers/char/drm/drm_hashtab.c
+++ b/drivers/char/drm/drm_hashtab.c
@@ -29,7 +29,7 @@
* Simple open hash tab implementation.
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drmP.h"
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
index 0f137677416..573e333ac45 100644
--- a/drivers/char/drm/drm_hashtab.h
+++ b/drivers/char/drm/drm_hashtab.h
@@ -29,7 +29,7 @@
* Simple open hash tab implementation.
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#ifndef DRM_HASHTAB_H
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
index c6b73e744d6..bea2a7d5b2b 100644
--- a/drivers/char/drm/drm_lock.c
+++ b/drivers/char/drm/drm_lock.c
@@ -58,12 +58,12 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- current->pid, lock->context);
+ task_pid_nr(current), lock->context);
return -EINVAL;
}
DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
- lock->context, current->pid,
+ lock->context, task_pid_nr(current),
dev->lock.hw_lock->lock, lock->flags);
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
@@ -153,7 +153,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
if (lock->context == DRM_KERNEL_CONTEXT) {
DRM_ERROR("Process %d using kernel context %d\n",
- current->pid, lock->context);
+ task_pid_nr(current), lock->context);
return -EINVAL;
}
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
index 3e6bc14f744..86f4eb61a6a 100644
--- a/drivers/char/drm/drm_mm.c
+++ b/drivers/char/drm/drm_mm.c
@@ -38,7 +38,7 @@
* Aligned allocations can also see improvement.
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drmP.h"
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
index 114e54e0f61..76e44ac94fb 100644
--- a/drivers/char/drm/drm_os_linux.h
+++ b/drivers/char/drm/drm_os_linux.h
@@ -7,7 +7,7 @@
#include <linux/delay.h>
/** Current process ID */
-#define DRM_CURRENTPID current->pid
+#define DRM_CURRENTPID task_pid_nr(current)
#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
#define DRM_UDELAY(d) udelay(d)
/** Read a byte from a MMIO region */
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
index e292bb0eaca..b55d5bc6ea6 100644
--- a/drivers/char/drm/drm_pci.c
+++ b/drivers/char/drm/drm_pci.c
@@ -8,12 +8,12 @@
* \todo Implement the remaining ioctl's for the PCI pools.
* \todo The wrappers here are so thin that they would be better off inlined..
*
- * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
+ * \author José Fonseca <jrfonseca@tungstengraphics.com>
* \author Leif Delgass <ldelgass@retinalburn.net>
*/
/*
- * Copyright 2003 Jos�Fonseca.
+ * Copyright 2003 José Fonseca.
* Copyright 2003 Leif Delgass.
* All Rights Reserved.
*
diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h
index f5466966081..e040f47f369 100644
--- a/drivers/char/drm/drm_sarea.h
+++ b/drivers/char/drm/drm_sarea.h
@@ -2,7 +2,7 @@
* \file drm_sarea.h
* \brief SAREA definitions
*
- * \author Michel Dnzer <michel@daenzer.net>
+ * \author Michel Dänzer <michel@daenzer.net>
*/
/*
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
index 8421a93946d..926f146390c 100644
--- a/drivers/char/drm/drm_sman.c
+++ b/drivers/char/drm/drm_sman.c
@@ -33,7 +33,7 @@
* struct or a context identifier.
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drm_sman.h"
diff --git a/drivers/char/drm/drm_sman.h b/drivers/char/drm/drm_sman.h
index 39a39fefeef..08ecf83ad5d 100644
--- a/drivers/char/drm/drm_sman.h
+++ b/drivers/char/drm/drm_sman.h
@@ -33,7 +33,7 @@
* struct or a context identifier.
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#ifndef DRM_SMAN_H
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 8e841bdee6d..eb381a7c5be 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -1024,7 +1024,7 @@ static int i810_getbuf(struct drm_device *dev, void *data,
retcode = i810_dma_get_buffer(dev, d, file_priv);
DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
- current->pid, retcode, d->granted);
+ task_pid_nr(current), retcode, d->granted);
sarea_priv->last_dispatch = (int)hw_status[5];
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 43a1f78712d..69a363edb0d 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -1409,7 +1409,7 @@ static int i830_getbuf(struct drm_device *dev, void *data,
retcode = i830_dma_get_buffer(dev, d, file_priv);
DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
- current->pid, retcode, d->granted);
+ task_pid_nr(current), retcode, d->granted);
sarea_priv->last_dispatch = (int)hw_status[5];
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 250d2aa4658..5041bd8dbed 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -29,7 +29,7 @@
* Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- * Michel D�zer <daenzerm@student.ethz.ch>
+ * Michel Dänzer <daenzerm@student.ethz.ch>
*/
#ifndef __R128_DRV_H__
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index 2b2407ee490..84f5bc36252 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -27,7 +27,7 @@
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
- * Michel D�zer <michel@daenzer.net>
+ * Michel Dänzer <michel@daenzer.net>
*/
#include "drmP.h"
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 69c9f2febf4..f824f2f5fdc 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -3005,7 +3005,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
/*
* This ioctl() doesn't work on 64-bit platforms because hw_lock is a
* pointer which can't fit into an int-sized variable. According to
- * Michel Dnzer, the ioctl() is only used on embedded platforms, so
+ * Michel Dänzer, the ioctl() is only used on embedded platforms, so
* not supporting it shouldn't be a problem. If the same functionality
* is needed on 64-bit platforms, a new ioctl() would have to be added,
* so backwards-compatibility for the embedded platforms can be
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
index 8c66838ff51..6be1c575758 100644
--- a/drivers/char/drm/sis_mm.c
+++ b/drivers/char/drm/sis_mm.c
@@ -28,7 +28,7 @@
/*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drmP.h"
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 9afc1684348..3ffbf864983 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -22,7 +22,7 @@
* DEALINGS IN THE SOFTWARE.
*/
/*
- * Authors: Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#include "drmP.h"
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
index 28b50296a7b..d6f8214b69f 100644
--- a/drivers/char/drm/via_verifier.h
+++ b/drivers/char/drm/via_verifier.h
@@ -20,7 +20,7 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
- * Author: Thomas Hellstrm 2004.
+ * Author: Thomas Hellström 2004.
*/
#ifndef _VIA_VERIFIER_H_
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 2e7ae42a550..28607763ae6 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -19,7 +19,7 @@
*
* rs_set_termios fixed to look also for changes of the input
* flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
- * Bernd Anh�pl 05/17/96.
+ * Bernd Anhäupl 05/17/96.
*
* --- End of notices from serial.c ---
*
@@ -58,10 +58,10 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/bitops.h>
#include <asm/dma.h>
#include <linux/slab.h>
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index e13dd1892bf..3f35a1c562b 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -10,7 +10,7 @@
* Mostly based on original driver:
*
* Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrj��<juha.yrjola@nokia.com>
+ * Author: Juha Yrjölä <juha.yrjola@nokia.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index cd406416eff..30e56451642 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -371,14 +371,14 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
int fn_key, cpu_temp, ac_power;
int left_fan, right_fan, left_speed, right_speed;
- cpu_temp = i8k_get_temp(0); /* 11100 s */
- left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 s */
- right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 s */
- left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 s */
- right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 s */
- fn_key = i8k_get_fn_status(); /* 750 s */
+ cpu_temp = i8k_get_temp(0); /* 11100 µs */
+ left_fan = i8k_get_fan_status(I8K_FAN_LEFT); /* 580 µs */
+ right_fan = i8k_get_fan_status(I8K_FAN_RIGHT); /* 580 µs */
+ left_speed = i8k_get_fan_speed(I8K_FAN_LEFT); /* 580 µs */
+ right_speed = i8k_get_fan_speed(I8K_FAN_RIGHT); /* 580 µs */
+ fn_key = i8k_get_fn_status(); /* 750 µs */
if (power_status)
- ac_power = i8k_get_power_status(); /* 14700 s */
+ ac_power = i8k_get_power_status(); /* 14700 µs */
else
ac_power = -1;
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 212276affa1..fc54d234507 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -42,6 +42,7 @@
#include <linux/sysrq.h>
#include <linux/input.h>
#include <linux/reboot.h>
+#include <linux/notifier.h>
extern void ctrl_alt_del(void);
@@ -81,7 +82,8 @@ void compute_shiftstate(void);
typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
char up_flag);
static k_handler_fn K_HANDLERS;
-static k_handler_fn *k_handler[16] = { K_HANDLERS };
+k_handler_fn *k_handler[16] = { K_HANDLERS };
+EXPORT_SYMBOL_GPL(k_handler);
#define FN_HANDLERS\
fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
@@ -127,7 +129,7 @@ int shift_state = 0;
*/
static struct input_handler kbd_handler;
-static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */
+static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static int dead_key_next;
static int npadch = -1; /* -1 or number assembled on pad */
@@ -160,6 +162,23 @@ static int sysrq_alt_use;
static int sysrq_alt;
/*
+ * Notifier list for console keyboard events
+ */
+static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
+
+int register_keyboard_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_keyboard_notifier);
+
+int unregister_keyboard_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
+
+/*
* Translation of scancodes to keycodes. We set them on only the first
* keyboard in the list that accepts the scancode and keycode.
* Explanation for not choosing the first attached keyboard anymore:
@@ -1130,6 +1149,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
unsigned char type, raw_mode;
struct tty_struct *tty;
int shift_final;
+ struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
tty = vc->vc_tty;
@@ -1217,10 +1237,11 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return;
}
- shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
+ param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
key_map = key_maps[shift_final];
- if (!key_map) {
+ if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, &param) == NOTIFY_STOP || !key_map) {
+ atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, &param);
compute_shiftstate();
kbd->slockstate = 0;
return;
@@ -1237,6 +1258,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
type = KTYP(keysym);
if (type < 0xf0) {
+ param.value = keysym;
+ if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, &param) == NOTIFY_STOP)
+ return;
if (down && !raw_mode)
to_utf8(vc, keysym);
return;
@@ -1244,9 +1268,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
type -= 0xf0;
- if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
- return;
-
if (type == KT_LETTER) {
type = KT_LATIN;
if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
@@ -1255,9 +1276,18 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
keysym = key_map[keycode];
}
}
+ param.value = keysym;
+
+ if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, &param) == NOTIFY_STOP)
+ return;
+
+ if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
+ return;
(*k_handler[type])(vc, keysym & 0xff, !down);
+ atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
+
if (type != KT_SLOCK)
kbd->slockstate = 0;
}
@@ -1347,12 +1377,12 @@ static void kbd_start(struct input_handle *handle)
static const struct input_device_id kbd_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
- .evbit = { BIT(EV_KEY) },
+ .evbit = { BIT_MASK(EV_KEY) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
- .evbit = { BIT(EV_SND) },
+ .evbit = { BIT_MASK(EV_SND) },
},
{ }, /* Terminating entry */
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 661aca0e155..fd0abef7ee0 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -56,11 +56,11 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include "mxser.h"
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index 854dbf59eb6..081c84c7b54 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -39,11 +39,11 @@
#include <linux/mm.h>
#include <linux/delay.h>
#include <linux/pci.h>
+#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include "mxser_new.h"
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 03805691193..596c7173997 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -437,7 +437,7 @@ static inline void finish_erasing(struct tty_struct *tty)
* @c: character input
* @tty: terminal device
*
- * Perform erase and neccessary output when an erase character is
+ * Perform erase and necessary output when an erase character is
* present in the stream from the driver layer. Handles the complexities
* of UTF-8 multibyte symbols.
*/
@@ -657,7 +657,7 @@ static inline void n_tty_receive_overrun(struct tty_struct *tty)
* @c: character
*
* Process a parity error and queue the right data to indicate
- * the error case if neccessary. Locking as per n_tty_receive_buf.
+ * the error case if necessary. Locking as per n_tty_receive_buf.
*/
static inline void n_tty_receive_parity_error(struct tty_struct *tty,
unsigned char c)
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 7e6a3a413bb..d83419c3857 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -563,7 +563,7 @@ static void rp_do_poll(unsigned long dummy)
/* Get a ptr to the board's control struct */
ctlp = sCtlNumToCtlPtr(ctrl);
- /* Get the interupt status from the board */
+ /* Get the interrupt status from the board */
#ifdef CONFIG_PCI
if (ctlp->BusType == isPCI)
CtlMask = sPCIGetControllerIntStatus(ctlp);
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 859858561ab..877e53dcb99 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -7,7 +7,7 @@
*
* Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
*
- * Copyright (C) 2001-2002 Alcve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
*
* Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
*
@@ -1178,9 +1178,9 @@ static int __devinit sonypi_create_input_devices(void)
jog_dev->id.bustype = BUS_ISA;
jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
- jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
- jog_dev->relbit[0] = BIT(REL_WHEEL);
+ jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+ jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
sonypi_device.input_key_dev = key_dev = input_allocate_device();
if (!key_dev) {
@@ -1193,7 +1193,7 @@ static int __devinit sonypi_create_input_devices(void)
key_dev->id.vendor = PCI_VENDOR_ID_SONY;
/* Initialize the Input Drivers: special keys */
- key_dev->evbit[0] = BIT(EV_KEY);
+ key_dev->evbit[0] = BIT_MASK(EV_KEY);
for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
if (sonypi_inputkeys[i].inputev)
set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 85a23283dff..a6e1c9ba121 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1467,7 +1467,7 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
line = tty->index;
sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, "
- "np=%d)\n", current->pid, line, tty,
+ "np=%d)\n", task_pid_nr(current), line, tty,
current->signal->tty, sx_nports);
if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports))
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 78d14935f2b..de60e1ea4fb 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -251,7 +251,7 @@ static void send_sig_all(int sig)
struct task_struct *p;
for_each_process(p) {
- if (p->mm && !is_init(p))
+ if (p->mm && !is_global_init(p))
/* Not swapper, init nor kernel thread */
force_sig(sig, p);
}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 9c867cf6de6..f36fecd3fd2 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -103,6 +103,7 @@
#include <linux/selection.h>
#include <linux/kmod.h>
+#include <linux/nsproxy.h>
#undef TTY_DEBUG_HANGUP
@@ -942,7 +943,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_deref);
* @tty: terminal to activate ldisc on
*
* Set the TTY_LDISC flag when the line discipline can be called
- * again. Do neccessary wakeups for existing sleepers.
+ * again. Do necessary wakeups for existing sleepers.
*
* Note: nobody should set this bit except via this function. Clearing
* directly is allowed.
@@ -1503,7 +1504,7 @@ EXPORT_SYMBOL(tty_hangup);
*
* The user has asked via system call for the terminal to be hung up.
* We do this synchronously so that when the syscall returns the process
- * is complete. That guarantee is neccessary for security reasons.
+ * is complete. That guarantee is necessary for security reasons.
*/
void tty_vhangup(struct tty_struct * tty)
@@ -1690,7 +1691,7 @@ EXPORT_SYMBOL(stop_tty);
* @tty: tty to start
*
* Start a tty that has been stopped if at all possible. Perform
- * any neccessary wakeups and propagate the TIOCPKT status. If this
+ * any necessary wakeups and propagate the TIOCPKT status. If this
* is the tty was previous stopped and is being started then the
* driver start method is invoked and the line discipline woken.
*
@@ -2876,7 +2877,7 @@ static int tty_fasync(int fd, struct file * filp, int on)
* @tty: tty to fake input into
* @p: pointer to character
*
- * Fake input to a tty device. Does the neccessary locking and
+ * Fake input to a tty device. Does the necessary locking and
* input management.
*
* FIXME: does not honour flow control ??
@@ -3107,7 +3108,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
- return put_user(pid_nr(real_tty->pgrp), p);
+ return put_user(pid_vnr(real_tty->pgrp), p);
}
/**
@@ -3141,7 +3142,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
if (pgrp_nr < 0)
return -EINVAL;
rcu_read_lock();
- pgrp = find_pid(pgrp_nr);
+ pgrp = find_vpid(pgrp_nr);
retval = -ESRCH;
if (!pgrp)
goto out_unlock;
@@ -3178,7 +3179,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
return -ENOTTY;
if (!real_tty->session)
return -ENOTTY;
- return put_user(pid_nr(real_tty->session), p);
+ return put_user(pid_vnr(real_tty->session), p);
}
/**
@@ -3528,8 +3529,8 @@ void __do_SAK(struct tty_struct *tty)
/* Kill the entire session */
do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): process_session(p)==tty->session\n",
- p->pid, p->comm);
+ " (%s): task_session_nr(p)==tty->session\n",
+ task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
} while_each_pid_task(session, PIDTYPE_SID, p);
/* Now kill any processes that happen to have the
@@ -3538,8 +3539,8 @@ void __do_SAK(struct tty_struct *tty)
do_each_thread(g, p) {
if (p->signal->tty == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): process_session(p)==tty->session\n",
- p->pid, p->comm);
+ " (%s): task_session_nr(p)==tty->session\n",
+ task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
continue;
}
@@ -3559,7 +3560,7 @@ void __do_SAK(struct tty_struct *tty)
filp->private_data == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
" (%s): fd#%d opened to the tty\n",
- p->pid, p->comm, i);
+ task_pid_nr(p), p->comm, i);
force_sig(SIGKILL, p);
break;
}
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index 0def089cc1f..7a003504c26 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -444,7 +444,7 @@ static void change_termios(struct tty_struct * tty, struct ktermios * new_termio
* @arg: user data
* @opt: option information
*
- * Helper function to prepare termios data and run neccessary other
+ * Helper function to prepare termios data and run necessary other
* functions before using change_termios to do the actual changes.
*
* Locking:
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1764c67b585..7a5badfb7d8 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -99,6 +99,7 @@
#include <linux/pm.h>
#include <linux/font.h>
#include <linux/bitops.h>
+#include <linux/notifier.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -223,6 +224,35 @@ enum {
};
/*
+ * Notifier list for console events.
+ */
+static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
+
+int register_vt_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(register_vt_notifier);
+
+int unregister_vt_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_vt_notifier);
+
+static void notify_write(struct vc_data *vc, unsigned int unicode)
+{
+ struct vt_notifier_param param = { .vc = vc, unicode = unicode };
+ atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
+}
+
+static void notify_update(struct vc_data *vc)
+{
+ struct vt_notifier_param param = { .vc = vc };
+ atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
+}
+
+/*
* Low-Level Functions
*/
@@ -718,6 +748,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
return -ENXIO;
if (!vc_cons[currcons].d) {
struct vc_data *vc;
+ struct vt_notifier_param param;
/* prevent users from taking too much memory */
if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
@@ -729,7 +760,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
/* although the numbers above are not valid since long ago, the
point is still up-to-date and the comment still has its value
even if only as a historical artifact. --mj, July 1998 */
- vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
+ param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
if (!vc)
return -ENOMEM;
vc_cons[currcons].d = vc;
@@ -746,6 +777,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
}
vc->vc_kmalloced = 1;
vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
+ atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
}
return 0;
}
@@ -907,6 +939,8 @@ void vc_deallocate(unsigned int currcons)
if (vc_cons_allocated(currcons)) {
struct vc_data *vc = vc_cons[currcons].d;
+ struct vt_notifier_param param = { .vc = vc };
+ atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
vc->vc_sw->con_deinit(vc);
put_pid(vc->vt_pid);
module_put(vc->vc_sw->owner);
@@ -1019,6 +1053,7 @@ static void lf(struct vc_data *vc)
vc->vc_pos += vc->vc_size_row;
}
vc->vc_need_wrap = 0;
+ notify_write(vc, '\n');
}
static void ri(struct vc_data *vc)
@@ -1039,6 +1074,7 @@ static inline void cr(struct vc_data *vc)
{
vc->vc_pos -= vc->vc_x << 1;
vc->vc_need_wrap = vc->vc_x = 0;
+ notify_write(vc, '\r');
}
static inline void bs(struct vc_data *vc)
@@ -1047,6 +1083,7 @@ static inline void bs(struct vc_data *vc)
vc->vc_pos -= 2;
vc->vc_x--;
vc->vc_need_wrap = 0;
+ notify_write(vc, '\b');
}
}
@@ -1593,6 +1630,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
break;
}
vc->vc_pos += (vc->vc_x << 1);
+ notify_write(vc, '\t');
return;
case 10: case 11: case 12:
lf(vc);
@@ -2252,6 +2290,7 @@ rescan_last_byte:
tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
if (tc < 0) tc = ' ';
}
+ notify_write(vc, c);
if (inverse) {
FLUSH
@@ -2274,6 +2313,7 @@ rescan_last_byte:
release_console_sem();
out:
+ notify_update(vc);
return n;
#undef FLUSH
}
@@ -2317,6 +2357,7 @@ static void console_callback(struct work_struct *ignored)
do_blank_screen(0);
blank_timer_expired = 0;
}
+ notify_update(vc_cons[fg_console].d);
release_console_sem();
}
@@ -2418,6 +2459,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
continue;
}
scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
+ notify_write(vc, c);
cnt++;
if (myx == vc->vc_cols - 1) {
vc->vc_need_wrap = 1;
@@ -2436,6 +2478,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
}
}
set_cursor(vc);
+ notify_update(vc);
quit:
clear_bit(0, &printing);
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
new file mode 100644
index 00000000000..3bed4127d4a
--- /dev/null
+++ b/drivers/cpuidle/Kconfig
@@ -0,0 +1,20 @@
+
+config CPU_IDLE
+ bool "CPU idle PM support"
+ help
+ CPU idle is a generic framework for supporting software-controlled
+ idle processor power management. It includes modular cross-platform
+ governors that can be swapped during runtime.
+
+ If you're using a mobile platform that supports CPU idle PM (e.g.
+ an ACPI-capable notebook), you should say Y here.
+
+config CPU_IDLE_GOV_LADDER
+ bool
+ depends on CPU_IDLE
+ default y
+
+config CPU_IDLE_GOV_MENU
+ bool
+ depends on CPU_IDLE && NO_HZ
+ default y
diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
new file mode 100644
index 00000000000..5634f88379d
--- /dev/null
+++ b/drivers/cpuidle/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for cpuidle.
+#
+
+obj-y += cpuidle.o driver.o governor.o sysfs.o governors/
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
new file mode 100644
index 00000000000..fdf4106b817
--- /dev/null
+++ b/drivers/cpuidle/cpuidle.c
@@ -0,0 +1,295 @@
+/*
+ * cpuidle.c - core cpuidle infrastructure
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/sched.h>
+#include <linux/notifier.h>
+#include <linux/latency.h>
+#include <linux/cpu.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices);
+
+DEFINE_MUTEX(cpuidle_lock);
+LIST_HEAD(cpuidle_detected_devices);
+static void (*pm_idle_old)(void);
+
+static int enabled_devices;
+
+/**
+ * cpuidle_idle_call - the main idle loop
+ *
+ * NOTE: no locks or semaphores should be used here
+ */
+static void cpuidle_idle_call(void)
+{
+ struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices);
+ struct cpuidle_state *target_state;
+ int next_state;
+
+ /* check if the device is ready */
+ if (!dev || !dev->enabled) {
+ if (pm_idle_old)
+ pm_idle_old();
+ else
+ local_irq_enable();
+ return;
+ }
+
+ /* ask the governor for the next state */
+ next_state = cpuidle_curr_governor->select(dev);
+ if (need_resched())
+ return;
+ target_state = &dev->states[next_state];
+
+ /* enter the state and update stats */
+ dev->last_residency = target_state->enter(dev, target_state);
+ dev->last_state = target_state;
+ target_state->time += dev->last_residency;
+ target_state->usage++;
+
+ /* give the governor an opportunity to reflect on the outcome */
+ if (cpuidle_curr_governor->reflect)
+ cpuidle_curr_governor->reflect(dev);
+}
+
+/**
+ * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
+ */
+void cpuidle_install_idle_handler(void)
+{
+ if (enabled_devices && (pm_idle != cpuidle_idle_call)) {
+ /* Make sure all changes finished before we switch to new idle */
+ smp_wmb();
+ pm_idle = cpuidle_idle_call;
+ }
+}
+
+/**
+ * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
+ */
+void cpuidle_uninstall_idle_handler(void)
+{
+ if (enabled_devices && (pm_idle != pm_idle_old)) {
+ pm_idle = pm_idle_old;
+ cpu_idle_wait();
+ }
+}
+
+/**
+ * cpuidle_pause_and_lock - temporarily disables CPUIDLE
+ */
+void cpuidle_pause_and_lock(void)
+{
+ mutex_lock(&cpuidle_lock);
+ cpuidle_uninstall_idle_handler();
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_pause_and_lock);
+
+/**
+ * cpuidle_resume_and_unlock - resumes CPUIDLE operation
+ */
+void cpuidle_resume_and_unlock(void)
+{
+ cpuidle_install_idle_handler();
+ mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock);
+
+/**
+ * cpuidle_enable_device - enables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+int cpuidle_enable_device(struct cpuidle_device *dev)
+{
+ int ret, i;
+
+ if (dev->enabled)
+ return 0;
+ if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+ return -EIO;
+ if (!dev->state_count)
+ return -EINVAL;
+
+ if ((ret = cpuidle_add_state_sysfs(dev)))
+ return ret;
+
+ if (cpuidle_curr_governor->enable &&
+ (ret = cpuidle_curr_governor->enable(dev)))
+ goto fail_sysfs;
+
+ for (i = 0; i < dev->state_count; i++) {
+ dev->states[i].usage = 0;
+ dev->states[i].time = 0;
+ }
+ dev->last_residency = 0;
+ dev->last_state = NULL;
+
+ smp_wmb();
+
+ dev->enabled = 1;
+
+ enabled_devices++;
+ return 0;
+
+fail_sysfs:
+ cpuidle_remove_state_sysfs(dev);
+
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_enable_device);
+
+/**
+ * cpuidle_disable_device - disables idle PM for a CPU
+ * @dev: the CPU
+ *
+ * This function must be called between cpuidle_pause_and_lock and
+ * cpuidle_resume_and_unlock when used externally.
+ */
+void cpuidle_disable_device(struct cpuidle_device *dev)
+{
+ if (!dev->enabled)
+ return;
+ if (!cpuidle_curr_driver || !cpuidle_curr_governor)
+ return;
+
+ dev->enabled = 0;
+
+ if (cpuidle_curr_governor->disable)
+ cpuidle_curr_governor->disable(dev);
+
+ cpuidle_remove_state_sysfs(dev);
+ enabled_devices--;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_disable_device);
+
+/**
+ * cpuidle_register_device - registers a CPU's idle PM feature
+ * @dev: the cpu
+ */
+int cpuidle_register_device(struct cpuidle_device *dev)
+{
+ int ret;
+ struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+ if (!sys_dev)
+ return -EINVAL;
+ if (!try_module_get(cpuidle_curr_driver->owner))
+ return -EINVAL;
+
+ init_completion(&dev->kobj_unregister);
+
+ mutex_lock(&cpuidle_lock);
+
+ per_cpu(cpuidle_devices, dev->cpu) = dev;
+ list_add(&dev->device_list, &cpuidle_detected_devices);
+ if ((ret = cpuidle_add_sysfs(sys_dev))) {
+ mutex_unlock(&cpuidle_lock);
+ module_put(cpuidle_curr_driver->owner);
+ return ret;
+ }
+
+ cpuidle_enable_device(dev);
+ cpuidle_install_idle_handler();
+
+ mutex_unlock(&cpuidle_lock);
+
+ return 0;
+
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_device);
+
+/**
+ * cpuidle_unregister_device - unregisters a CPU's idle PM feature
+ * @dev: the cpu
+ */
+void cpuidle_unregister_device(struct cpuidle_device *dev)
+{
+ struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);
+
+ cpuidle_pause_and_lock();
+
+ cpuidle_disable_device(dev);
+
+ cpuidle_remove_sysfs(sys_dev);
+ list_del(&dev->device_list);
+ wait_for_completion(&dev->kobj_unregister);
+ per_cpu(cpuidle_devices, dev->cpu) = NULL;
+
+ cpuidle_resume_and_unlock();
+
+ module_put(cpuidle_curr_driver->owner);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_device);
+
+#ifdef CONFIG_SMP
+
+static void smp_callback(void *v)
+{
+ /* we already woke the CPU up, nothing more to do */
+}
+
+/*
+ * This function gets called when a part of the kernel has a new latency
+ * requirement. This means we need to get all processors out of their C-state,
+ * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that
+ * wakes them all right up.
+ */
+static int cpuidle_latency_notify(struct notifier_block *b,
+ unsigned long l, void *v)
+{
+ smp_call_function(smp_callback, NULL, 0, 1);
+ return NOTIFY_OK;
+}
+
+static struct notifier_block cpuidle_latency_notifier = {
+ .notifier_call = cpuidle_latency_notify,
+};
+
+#define latency_notifier_init(x) do { register_latency_notifier(x); } while (0)
+
+#else /* CONFIG_SMP */
+
+#define latency_notifier_init(x) do { } while (0)
+
+#endif /* CONFIG_SMP */
+
+/**
+ * cpuidle_init - core initializer
+ */
+static int __init cpuidle_init(void)
+{
+ int ret;
+
+ pm_idle_old = pm_idle;
+
+ ret = cpuidle_add_class_sysfs(&cpu_sysdev_class);
+ if (ret)
+ return ret;
+
+ latency_notifier_init(&cpuidle_latency_notifier);
+
+ return 0;
+}
+
+core_initcall(cpuidle_init);
diff --git a/drivers/cpuidle/cpuidle.h b/drivers/cpuidle/cpuidle.h
new file mode 100644
index 00000000000..9476ba33ee2
--- /dev/null
+++ b/drivers/cpuidle/cpuidle.h
@@ -0,0 +1,33 @@
+/*
+ * cpuidle.h - The internal header file
+ */
+
+#ifndef __DRIVER_CPUIDLE_H
+#define __DRIVER_CPUIDLE_H
+
+#include <linux/sysdev.h>
+
+/* For internal use only */
+extern struct cpuidle_governor *cpuidle_curr_governor;
+extern struct cpuidle_driver *cpuidle_curr_driver;
+extern struct list_head cpuidle_governors;
+extern struct list_head cpuidle_detected_devices;
+extern struct mutex cpuidle_lock;
+extern spinlock_t cpuidle_driver_lock;
+
+/* idle loop */
+extern void cpuidle_install_idle_handler(void);
+extern void cpuidle_uninstall_idle_handler(void);
+
+/* governors */
+extern int cpuidle_switch_governor(struct cpuidle_governor *gov);
+
+/* sysfs */
+extern int cpuidle_add_class_sysfs(struct sysdev_class *cls);
+extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls);
+extern int cpuidle_add_state_sysfs(struct cpuidle_device *device);
+extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device);
+extern int cpuidle_add_sysfs(struct sys_device *sysdev);
+extern void cpuidle_remove_sysfs(struct sys_device *sysdev);
+
+#endif /* __DRIVER_CPUIDLE_H */
diff --git a/drivers/cpuidle/driver.c b/drivers/cpuidle/driver.c
new file mode 100644
index 00000000000..2257004fe33
--- /dev/null
+++ b/drivers/cpuidle/driver.c
@@ -0,0 +1,56 @@
+/*
+ * driver.c - driver support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+struct cpuidle_driver *cpuidle_curr_driver;
+DEFINE_SPINLOCK(cpuidle_driver_lock);
+
+/**
+ * cpuidle_register_driver - registers a driver
+ * @drv: the driver
+ */
+int cpuidle_register_driver(struct cpuidle_driver *drv)
+{
+ if (!drv)
+ return -EINVAL;
+
+ spin_lock(&cpuidle_driver_lock);
+ if (cpuidle_curr_driver) {
+ spin_unlock(&cpuidle_driver_lock);
+ return -EBUSY;
+ }
+ cpuidle_curr_driver = drv;
+ spin_unlock(&cpuidle_driver_lock);
+
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_driver);
+
+/**
+ * cpuidle_unregister_driver - unregisters a driver
+ * @drv: the driver
+ */
+void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+{
+ if (!drv)
+ return;
+
+ spin_lock(&cpuidle_driver_lock);
+ cpuidle_curr_driver = NULL;
+ spin_unlock(&cpuidle_driver_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
diff --git a/drivers/cpuidle/governor.c b/drivers/cpuidle/governor.c
new file mode 100644
index 00000000000..bb699cb2dc5
--- /dev/null
+++ b/drivers/cpuidle/governor.c
@@ -0,0 +1,141 @@
+/*
+ * governor.c - governor support
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/mutex.h>
+#include <linux/module.h>
+#include <linux/cpuidle.h>
+
+#include "cpuidle.h"
+
+LIST_HEAD(cpuidle_governors);
+struct cpuidle_governor *cpuidle_curr_governor;
+
+/**
+ * __cpuidle_find_governor - finds a governor of the specified name
+ * @str: the name
+ *
+ * Must be called with cpuidle_lock aquired.
+ */
+static struct cpuidle_governor * __cpuidle_find_governor(const char *str)
+{
+ struct cpuidle_governor *gov;
+
+ list_for_each_entry(gov, &cpuidle_governors, governor_list)
+ if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN))
+ return gov;
+
+ return NULL;
+}
+
+/**
+ * cpuidle_switch_governor - changes the governor
+ * @gov: the new target governor
+ *
+ * NOTE: "gov" can be NULL to specify disabled
+ * Must be called with cpuidle_lock aquired.
+ */
+int cpuidle_switch_governor(struct cpuidle_governor *gov)
+{
+ struct cpuidle_device *dev;
+
+ if (gov == cpuidle_curr_governor)
+ return 0;
+
+ cpuidle_uninstall_idle_handler();
+
+ if (cpuidle_curr_governor) {
+ list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+ cpuidle_disable_device(dev);
+ module_put(cpuidle_curr_governor->owner);
+ }
+
+ cpuidle_curr_governor = gov;
+
+ if (gov) {
+ if (!try_module_get(cpuidle_curr_governor->owner))
+ return -EINVAL;
+ list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
+ cpuidle_enable_device(dev);
+ cpuidle_install_idle_handler();
+ printk(KERN_INFO "cpuidle: using governor %s\n", gov->name);
+ }
+
+ return 0;
+}
+
+/**
+ * cpuidle_register_governor - registers a governor
+ * @gov: the governor
+ */
+int cpuidle_register_governor(struct cpuidle_governor *gov)
+{
+ int ret = -EEXIST;
+
+ if (!gov || !gov->select)
+ return -EINVAL;
+
+ mutex_lock(&cpuidle_lock);
+ if (__cpuidle_find_governor(gov->name) == NULL) {
+ ret = 0;
+ list_add_tail(&gov->governor_list, &cpuidle_governors);
+ if (!cpuidle_curr_governor ||
+ cpuidle_curr_governor->rating < gov->rating)
+ cpuidle_switch_governor(gov);
+ }
+ mutex_unlock(&cpuidle_lock);
+
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_register_governor);
+
+/**
+ * cpuidle_replace_governor - find a replacement governor
+ * @exclude_rating: the rating that will be skipped while looking for
+ * new governor.
+ */
+static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating)
+{
+ struct cpuidle_governor *gov;
+ struct cpuidle_governor *ret_gov = NULL;
+ unsigned int max_rating = 0;
+
+ list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+ if (gov->rating == exclude_rating)
+ continue;
+ if (gov->rating > max_rating) {
+ max_rating = gov->rating;
+ ret_gov = gov;
+ }
+ }
+
+ return ret_gov;
+}
+
+/**
+ * cpuidle_unregister_governor - unregisters a governor
+ * @gov: the governor
+ */
+void cpuidle_unregister_governor(struct cpuidle_governor *gov)
+{
+ if (!gov)
+ return;
+
+ mutex_lock(&cpuidle_lock);
+ if (gov == cpuidle_curr_governor) {
+ struct cpuidle_governor *new_gov;
+ new_gov = cpuidle_replace_governor(gov->rating);
+ cpuidle_switch_governor(new_gov);
+ }
+ list_del(&gov->governor_list);
+ mutex_unlock(&cpuidle_lock);
+}
+
+EXPORT_SYMBOL_GPL(cpuidle_unregister_governor);
diff --git a/drivers/cpuidle/governors/Makefile b/drivers/cpuidle/governors/Makefile
new file mode 100644
index 00000000000..1b512722689
--- /dev/null
+++ b/drivers/cpuidle/governors/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for cpuidle governors.
+#
+
+obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o
+obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o
diff --git a/drivers/cpuidle/governors/ladder.c b/drivers/cpuidle/governors/ladder.c
new file mode 100644
index 00000000000..eb666ecae7c
--- /dev/null
+++ b/drivers/cpuidle/governors/ladder.c
@@ -0,0 +1,166 @@
+/*
+ * ladder.c - the residency ladder algorithm
+ *
+ * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ * Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
+ *
+ * (C) 2006-2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/moduleparam.h>
+#include <linux/jiffies.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#define PROMOTION_COUNT 4
+#define DEMOTION_COUNT 1
+
+struct ladder_device_state {
+ struct {
+ u32 promotion_count;
+ u32 demotion_count;
+ u32 promotion_time;
+ u32 demotion_time;
+ } threshold;
+ struct {
+ int promotion_count;
+ int demotion_count;
+ } stats;
+};
+
+struct ladder_device {
+ struct ladder_device_state states[CPUIDLE_STATE_MAX];
+ int last_state_idx;
+};
+
+static DEFINE_PER_CPU(struct ladder_device, ladder_devices);
+
+/**
+ * ladder_do_selection - prepares private data for a state change
+ * @ldev: the ladder device
+ * @old_idx: the current state index
+ * @new_idx: the new target state index
+ */
+static inline void ladder_do_selection(struct ladder_device *ldev,
+ int old_idx, int new_idx)
+{
+ ldev->states[old_idx].stats.promotion_count = 0;
+ ldev->states[old_idx].stats.demotion_count = 0;
+ ldev->last_state_idx = new_idx;
+}
+
+/**
+ * ladder_select_state - selects the next state to enter
+ * @dev: the CPU
+ */
+static int ladder_select_state(struct cpuidle_device *dev)
+{
+ struct ladder_device *ldev = &__get_cpu_var(ladder_devices);
+ struct ladder_device_state *last_state;
+ int last_residency, last_idx = ldev->last_state_idx;
+
+ if (unlikely(!ldev))
+ return 0;
+
+ last_state = &ldev->states[last_idx];
+
+ if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID)
+ last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency;
+ else
+ last_residency = last_state->threshold.promotion_time + 1;
+
+ /* consider promotion */
+ if (last_idx < dev->state_count - 1 &&
+ last_residency > last_state->threshold.promotion_time &&
+ dev->states[last_idx + 1].exit_latency <= system_latency_constraint()) {
+ last_state->stats.promotion_count++;
+ last_state->stats.demotion_count = 0;
+ if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) {
+ ladder_do_selection(ldev, last_idx, last_idx + 1);
+ return last_idx + 1;
+ }
+ }
+
+ /* consider demotion */
+ if (last_idx > 0 &&
+ last_residency < last_state->threshold.demotion_time) {
+ last_state->stats.demotion_count++;
+ last_state->stats.promotion_count = 0;
+ if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) {
+ ladder_do_selection(ldev, last_idx, last_idx - 1);
+ return last_idx - 1;
+ }
+ }
+
+ /* otherwise remain at the current state */
+ return last_idx;
+}
+
+/**
+ * ladder_enable_device - setup for the governor
+ * @dev: the CPU
+ */
+static int ladder_enable_device(struct cpuidle_device *dev)
+{
+ int i;
+ struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu);
+ struct ladder_device_state *lstate;
+ struct cpuidle_state *state;
+
+ ldev->last_state_idx = 0;
+
+ for (i = 0; i < dev->state_count; i++) {
+ state = &dev->states[i];
+ lstate = &ldev->states[i];
+
+ lstate->stats.promotion_count = 0;
+ lstate->stats.demotion_count = 0;
+
+ lstate->threshold.promotion_count = PROMOTION_COUNT;
+ lstate->threshold.demotion_count = DEMOTION_COUNT;
+
+ if (i < dev->state_count - 1)
+ lstate->threshold.promotion_time = state->exit_latency;
+ if (i > 0)
+ lstate->threshold.demotion_time = state->exit_latency;
+ }
+
+ return 0;
+}
+
+static struct cpuidle_governor ladder_governor = {
+ .name = "ladder",
+ .rating = 10,
+ .enable = ladder_enable_device,
+ .select = ladder_select_state,
+ .owner = THIS_MODULE,
+};
+
+/**
+ * init_ladder - initializes the governor
+ */
+static int __init init_ladder(void)
+{
+ return cpuidle_register_governor(&ladder_governor);
+}
+
+/**
+ * exit_ladder - exits the governor
+ */
+static void __exit exit_ladder(void)
+{
+ cpuidle_unregister_governor(&ladder_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_ladder);
+module_exit(exit_ladder);
diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c
new file mode 100644
index 00000000000..299d45c3bdd
--- /dev/null
+++ b/drivers/cpuidle/governors/menu.c
@@ -0,0 +1,137 @@
+/*
+ * menu.c - the menu idle governor
+ *
+ * Copyright (C) 2006-2007 Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/latency.h>
+#include <linux/time.h>
+#include <linux/ktime.h>
+#include <linux/hrtimer.h>
+#include <linux/tick.h>
+
+#define BREAK_FUZZ 4 /* 4 us */
+
+struct menu_device {
+ int last_state_idx;
+
+ unsigned int expected_us;
+ unsigned int predicted_us;
+ unsigned int last_measured_us;
+ unsigned int elapsed_us;
+};
+
+static DEFINE_PER_CPU(struct menu_device, menu_devices);
+
+/**
+ * menu_select - selects the next idle state to enter
+ * @dev: the CPU
+ */
+static int menu_select(struct cpuidle_device *dev)
+{
+ struct menu_device *data = &__get_cpu_var(menu_devices);
+ int i;
+
+ /* determine the expected residency time */
+ data->expected_us =
+ (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000;
+
+ /* find the deepest idle state that satisfies our constraints */
+ for (i = 1; i < dev->state_count; i++) {
+ struct cpuidle_state *s = &dev->states[i];
+
+ if (s->target_residency > data->expected_us)
+ break;
+ if (s->target_residency > data->predicted_us)
+ break;
+ if (s->exit_latency > system_latency_constraint())
+ break;
+ }
+
+ data->last_state_idx = i - 1;
+ return i - 1;
+}
+
+/**
+ * menu_reflect - attempts to guess what happened after entry
+ * @dev: the CPU
+ *
+ * NOTE: it's important to be fast here because this operation will add to
+ * the overall exit latency.
+ */
+static void menu_reflect(struct cpuidle_device *dev)
+{
+ struct menu_device *data = &__get_cpu_var(menu_devices);
+ int last_idx = data->last_state_idx;
+ unsigned int measured_us =
+ cpuidle_get_last_residency(dev) + data->elapsed_us;
+ struct cpuidle_state *target = &dev->states[last_idx];
+
+ /*
+ * Ugh, this idle state doesn't support residency measurements, so we
+ * are basically lost in the dark. As a compromise, assume we slept
+ * for one full standard timer tick. However, be aware that this
+ * could potentially result in a suboptimal state transition.
+ */
+ if (!(target->flags & CPUIDLE_FLAG_TIME_VALID))
+ measured_us = USEC_PER_SEC / HZ;
+
+ /* Predict time remaining until next break event */
+ if (measured_us + BREAK_FUZZ < data->expected_us - target->exit_latency) {
+ data->predicted_us = max(measured_us, data->last_measured_us);
+ data->last_measured_us = measured_us;
+ data->elapsed_us = 0;
+ } else {
+ if (data->elapsed_us < data->elapsed_us + measured_us)
+ data->elapsed_us = measured_us;
+ else
+ data->elapsed_us = -1;
+ data->predicted_us = max(measured_us, data->last_measured_us);
+ }
+}
+
+/**
+ * menu_enable_device - scans a CPU's states and does setup
+ * @dev: the CPU
+ */
+static int menu_enable_device(struct cpuidle_device *dev)
+{
+ struct menu_device *data = &per_cpu(menu_devices, dev->cpu);
+
+ memset(data, 0, sizeof(struct menu_device));
+
+ return 0;
+}
+
+static struct cpuidle_governor menu_governor = {
+ .name = "menu",
+ .rating = 20,
+ .enable = menu_enable_device,
+ .select = menu_select,
+ .reflect = menu_reflect,
+ .owner = THIS_MODULE,
+};
+
+/**
+ * init_menu - initializes the governor
+ */
+static int __init init_menu(void)
+{
+ return cpuidle_register_governor(&menu_governor);
+}
+
+/**
+ * exit_menu - exits the governor
+ */
+static void __exit exit_menu(void)
+{
+ cpuidle_unregister_governor(&menu_governor);
+}
+
+MODULE_LICENSE("GPL");
+module_init(init_menu);
+module_exit(exit_menu);
diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
new file mode 100644
index 00000000000..0f3515e77d4
--- /dev/null
+++ b/drivers/cpuidle/sysfs.c
@@ -0,0 +1,361 @@
+/*
+ * sysfs.c - sysfs support
+ *
+ * (C) 2006-2007 Shaohua Li <shaohua.li@intel.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cpuidle.h>
+#include <linux/sysfs.h>
+#include <linux/cpu.h>
+
+#include "cpuidle.h"
+
+static unsigned int sysfs_switch;
+static int __init cpuidle_sysfs_setup(char *unused)
+{
+ sysfs_switch = 1;
+ return 1;
+}
+__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
+
+static ssize_t show_available_governors(struct sys_device *dev, char *buf)
+{
+ ssize_t i = 0;
+ struct cpuidle_governor *tmp;
+
+ mutex_lock(&cpuidle_lock);
+ list_for_each_entry(tmp, &cpuidle_governors, governor_list) {
+ if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2))
+ goto out;
+ i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name);
+ }
+
+out:
+ i+= sprintf(&buf[i], "\n");
+ mutex_unlock(&cpuidle_lock);
+ return i;
+}
+
+static ssize_t show_current_driver(struct sys_device *dev, char *buf)
+{
+ ssize_t ret;
+
+ spin_lock(&cpuidle_driver_lock);
+ if (cpuidle_curr_driver)
+ ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name);
+ else
+ ret = sprintf(buf, "none\n");
+ spin_unlock(&cpuidle_driver_lock);
+
+ return ret;
+}
+
+static ssize_t show_current_governor(struct sys_device *dev, char *buf)
+{
+ ssize_t ret;
+
+ mutex_lock(&cpuidle_lock);
+ if (cpuidle_curr_governor)
+ ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name);
+ else
+ ret = sprintf(buf, "none\n");
+ mutex_unlock(&cpuidle_lock);
+
+ return ret;
+}
+
+static ssize_t store_current_governor(struct sys_device *dev,
+ const char *buf, size_t count)
+{
+ char gov_name[CPUIDLE_NAME_LEN];
+ int ret = -EINVAL;
+ size_t len = count;
+ struct cpuidle_governor *gov;
+
+ if (!len || len >= sizeof(gov_name))
+ return -EINVAL;
+
+ memcpy(gov_name, buf, len);
+ gov_name[len] = '\0';
+ if (gov_name[len - 1] == '\n')
+ gov_name[--len] = '\0';
+
+ mutex_lock(&cpuidle_lock);
+
+ list_for_each_entry(gov, &cpuidle_governors, governor_list) {
+ if (strlen(gov->name) == len && !strcmp(gov->name, gov_name)) {
+ ret = cpuidle_switch_governor(gov);
+ break;
+ }
+ }
+
+ mutex_unlock(&cpuidle_lock);
+
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static SYSDEV_ATTR(current_driver, 0444, show_current_driver, NULL);
+static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL);
+
+static struct attribute *cpuclass_default_attrs[] = {
+ &attr_current_driver.attr,
+ &attr_current_governor_ro.attr,
+ NULL
+};
+
+static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL);
+static SYSDEV_ATTR(current_governor, 0644, show_current_governor,
+ store_current_governor);
+
+static struct attribute *cpuclass_switch_attrs[] = {
+ &attr_available_governors.attr,
+ &attr_current_driver.attr,
+ &attr_current_governor.attr,
+ NULL
+};
+
+static struct attribute_group cpuclass_attr_group = {
+ .attrs = cpuclass_default_attrs,
+ .name = "cpuidle",
+};
+
+/**
+ * cpuidle_add_class_sysfs - add CPU global sysfs attributes
+ */
+int cpuidle_add_class_sysfs(struct sysdev_class *cls)
+{
+ if (sysfs_switch)
+ cpuclass_attr_group.attrs = cpuclass_switch_attrs;
+
+ return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+/**
+ * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes
+ */
+void cpuidle_remove_class_sysfs(struct sysdev_class *cls)
+{
+ sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group);
+}
+
+struct cpuidle_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct cpuidle_device *, char *);
+ ssize_t (*store)(struct cpuidle_device *, const char *, size_t count);
+};
+
+#define define_one_ro(_name, show) \
+ static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+#define define_one_rw(_name, show, store) \
+ static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store)
+
+#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj)
+#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr)
+static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf)
+{
+ int ret = -EIO;
+ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+ struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+ if (cattr->show) {
+ mutex_lock(&cpuidle_lock);
+ ret = cattr->show(dev, buf);
+ mutex_unlock(&cpuidle_lock);
+ }
+ return ret;
+}
+
+static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr,
+ const char * buf, size_t count)
+{
+ int ret = -EIO;
+ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+ struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr);
+
+ if (cattr->store) {
+ mutex_lock(&cpuidle_lock);
+ ret = cattr->store(dev, buf, count);
+ mutex_unlock(&cpuidle_lock);
+ }
+ return ret;
+}
+
+static struct sysfs_ops cpuidle_sysfs_ops = {
+ .show = cpuidle_show,
+ .store = cpuidle_store,
+};
+
+static void cpuidle_sysfs_release(struct kobject *kobj)
+{
+ struct cpuidle_device *dev = kobj_to_cpuidledev(kobj);
+
+ complete(&dev->kobj_unregister);
+}
+
+static struct kobj_type ktype_cpuidle = {
+ .sysfs_ops = &cpuidle_sysfs_ops,
+ .release = cpuidle_sysfs_release,
+};
+
+struct cpuidle_state_attr {
+ struct attribute attr;
+ ssize_t (*show)(struct cpuidle_state *, char *);
+ ssize_t (*store)(struct cpuidle_state *, const char *, size_t);
+};
+
+#define define_one_state_ro(_name, show) \
+static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL)
+
+#define define_show_state_function(_name) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+{ \
+ return sprintf(buf, "%u\n", state->_name);\
+}
+
+static ssize_t show_state_name(struct cpuidle_state *state, char *buf)
+{
+ return sprintf(buf, "%s\n", state->name);
+}
+
+define_show_state_function(exit_latency)
+define_show_state_function(power_usage)
+define_show_state_function(usage)
+define_show_state_function(time)
+define_one_state_ro(name, show_state_name);
+define_one_state_ro(latency, show_state_exit_latency);
+define_one_state_ro(power, show_state_power_usage);
+define_one_state_ro(usage, show_state_usage);
+define_one_state_ro(time, show_state_time);
+
+static struct attribute *cpuidle_state_default_attrs[] = {
+ &attr_name.attr,
+ &attr_latency.attr,
+ &attr_power.attr,
+ &attr_usage.attr,
+ &attr_time.attr,
+ NULL
+};
+
+#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj)
+#define kobj_to_state(k) (kobj_to_state_obj(k)->state)
+#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr)
+static ssize_t cpuidle_state_show(struct kobject * kobj,
+ struct attribute * attr ,char * buf)
+{
+ int ret = -EIO;
+ struct cpuidle_state *state = kobj_to_state(kobj);
+ struct cpuidle_state_attr * cattr = attr_to_stateattr(attr);
+
+ if (cattr->show)
+ ret = cattr->show(state, buf);
+
+ return ret;
+}
+
+static struct sysfs_ops cpuidle_state_sysfs_ops = {
+ .show = cpuidle_state_show,
+};
+
+static void cpuidle_state_sysfs_release(struct kobject *kobj)
+{
+ struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj);
+
+ complete(&state_obj->kobj_unregister);
+}
+
+static struct kobj_type ktype_state_cpuidle = {
+ .sysfs_ops = &cpuidle_state_sysfs_ops,
+ .default_attrs = cpuidle_state_default_attrs,
+ .release = cpuidle_state_sysfs_release,
+};
+
+static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i)
+{
+ kobject_unregister(&device->kobjs[i]->kobj);
+ wait_for_completion(&device->kobjs[i]->kobj_unregister);
+ kfree(device->kobjs[i]);
+ device->kobjs[i] = NULL;
+}
+
+/**
+ * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes
+ * @device: the target device
+ */
+int cpuidle_add_state_sysfs(struct cpuidle_device *device)
+{
+ int i, ret = -ENOMEM;
+ struct cpuidle_state_kobj *kobj;
+
+ /* state statistics */
+ for (i = 0; i < device->state_count; i++) {
+ kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL);
+ if (!kobj)
+ goto error_state;
+ kobj->state = &device->states[i];
+ init_completion(&kobj->kobj_unregister);
+
+ kobj->kobj.parent = &device->kobj;
+ kobj->kobj.ktype = &ktype_state_cpuidle;
+ kobject_set_name(&kobj->kobj, "state%d", i);
+ ret = kobject_register(&kobj->kobj);
+ if (ret) {
+ kfree(kobj);
+ goto error_state;
+ }
+ device->kobjs[i] = kobj;
+ }
+
+ return 0;
+
+error_state:
+ for (i = i - 1; i >= 0; i--)
+ cpuidle_free_state_kobj(device, i);
+ return ret;
+}
+
+/**
+ * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes
+ * @device: the target device
+ */
+void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
+{
+ int i;
+
+ for (i = 0; i < device->state_count; i++)
+ cpuidle_free_state_kobj(device, i);
+}
+
+/**
+ * cpuidle_add_sysfs - creates a sysfs instance for the target device
+ * @sysdev: the target device
+ */
+int cpuidle_add_sysfs(struct sys_device *sysdev)
+{
+ int cpu = sysdev->id;
+ struct cpuidle_device *dev;
+
+ dev = per_cpu(cpuidle_devices, cpu);
+ dev->kobj.parent = &sysdev->kobj;
+ dev->kobj.ktype = &ktype_cpuidle;
+ kobject_set_name(&dev->kobj, "%s", "cpuidle");
+ return kobject_register(&dev->kobj);
+}
+
+/**
+ * cpuidle_remove_sysfs - deletes a sysfs instance on the target device
+ * @sysdev: the target device
+ */
+void cpuidle_remove_sysfs(struct sys_device *sysdev)
+{
+ int cpu = sysdev->id;
+ struct cpuidle_device *dev;
+
+ dev = per_cpu(cpuidle_devices, cpu);
+ kobject_unregister(&dev->kobj);
+}
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index e80af67664c..2d23e304f5e 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -94,8 +94,6 @@ extern int edac_debug_level;
#endif /* !CONFIG_EDAC_DEBUG */
-#define BIT(x) (1 << (x))
-
#define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \
PCI_DEVICE_ID_ ## vend ## _ ## dev
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index e66cdd42a39..9007d067722 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -270,6 +270,7 @@ static void __devexit pasemi_edac_remove(struct pci_dev *pdev)
static const struct pci_device_id pasemi_edac_pci_tbl[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa00a) },
+ { }
};
MODULE_DEVICE_TABLE(pci, pasemi_edac_pci_tbl);
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index 2f307c4df33..67588326ae5 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -606,7 +606,7 @@ static int
at_context_queue_packet(struct context *ctx, struct fw_packet *packet)
{
struct fw_ohci *ohci = ctx->ohci;
- dma_addr_t d_bus, payload_bus;
+ dma_addr_t d_bus, uninitialized_var(payload_bus);
struct driver_data *driver_data;
struct descriptor *d, *last;
__le32 *header;
@@ -1459,7 +1459,7 @@ ohci_allocate_iso_context(struct fw_card *card, int type, size_t header_size)
/* FIXME: We need a fallback for pre 1.1 OHCI. */
if (callback == handle_ir_dualbuffer_packet &&
ohci->version < OHCI_VERSION_1_1)
- return ERR_PTR(-EINVAL);
+ return ERR_PTR(-ENOSYS);
spin_lock_irqsave(&ohci->lock, flags);
index = ffs(*mask) - 1;
@@ -1778,7 +1778,7 @@ ohci_queue_iso(struct fw_iso_context *base,
buffer, payload);
else
/* FIXME: Implement fallback for OHCI 1.0 controllers. */
- return -EINVAL;
+ return -ENOSYS;
}
static const struct fw_card_driver ohci_driver = {
@@ -1898,7 +1898,12 @@ pci_probe(struct pci_dev *dev, const struct pci_device_id *ent)
ohci->version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n",
dev->dev.bus_id, ohci->version >> 16, ohci->version & 0xff);
-
+ if (ohci->version < OHCI_VERSION_1_1) {
+ fw_notify(" Isochronous I/O is not yet implemented for "
+ "OHCI 1.0 chips.\n");
+ fw_notify(" Cameras, audio devices etc. won't work on "
+ "this controller with this driver version.\n");
+ }
return 0;
fail_self_id:
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 9959b799dbe..c00d4a9b39e 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -228,7 +228,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
*
* @param card the card from which to send the request
* @param tcode the tcode for this transaction. Do not use
- * TCODE_LOCK_REQUEST directly, insted use TCODE_LOCK_MASK_SWAP
+ * TCODE_LOCK_REQUEST directly, instead use TCODE_LOCK_MASK_SWAP
* etc. to specify tcode and ext_tcode.
* @param node_id the destination node ID (bus ID and PHY ID concatenated)
* @param generation the generation for which node_id is valid
diff --git a/drivers/firmware/dcdbas.h b/drivers/firmware/dcdbas.h
index dcdba0f1b32..87bc3417de2 100644
--- a/drivers/firmware/dcdbas.h
+++ b/drivers/firmware/dcdbas.h
@@ -17,7 +17,6 @@
#define _DCDBAS_H_
#include <linux/device.h>
-#include <linux/input.h>
#include <linux/sysfs.h>
#include <linux/types.h>
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index a702e2f6da7..1ca6f4635ee 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -113,13 +113,13 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
if (count > HID_MIN_BUFFER_SIZE) {
printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
- current->pid);
+ task_pid_nr(current));
return -EINVAL;
}
if (count < 2) {
printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
- current->pid);
+ task_pid_nr(current));
return -EINVAL;
}
diff --git a/drivers/hid/usbhid/hid-ff.c b/drivers/hid/usbhid/hid-ff.c
index 22329feb3b5..4c210e16b1b 100644
--- a/drivers/hid/usbhid/hid-ff.c
+++ b/drivers/hid/usbhid/hid-ff.c
@@ -1,6 +1,4 @@
/*
- * $Id: hid-ff.c,v 1.2 2002/04/18 22:02:47 jdeneux Exp $
- *
* Force feedback support for hid devices.
* Not all hid devices use the same protocol. For example, some use PID,
* other use their own proprietary procotol.
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c
index b76b02f7b52..775a1ef28a2 100644
--- a/drivers/hid/usbhid/usbkbd.c
+++ b/drivers/hid/usbhid/usbkbd.c
@@ -274,8 +274,11 @@ static int usb_kbd_probe(struct usb_interface *iface,
input_set_drvdata(input_dev, kbd);
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+ BIT_MASK(EV_REP);
+ input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+ BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) |
+ BIT_MASK(LED_KANA);
for (i = 0; i < 255; i++)
set_bit(usb_kbd_keycode[i], input_dev->keybit);
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 5345c73bcf6..f8ad6910d3d 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -173,11 +173,13 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
usb_to_input_id(dev, &input_dev->id);
input_dev->dev.parent = &intf->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+ BIT_MASK(BTN_EXTRA);
+ input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
input_set_drvdata(input_dev, mouse);
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 4879125b4cd..1001d2e122a 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1099,7 +1099,7 @@ static int applesmc_create_accelerometer(void)
idev->name = "applesmc";
idev->id.bustype = BUS_HOST;
idev->dev.parent = &pdev->dev;
- idev->evbit[0] = BIT(EV_ABS);
+ idev->evbit[0] = BIT_MASK(EV_ABS);
input_set_abs_params(idev, ABS_X,
-256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
input_set_abs_params(idev, ABS_Y,
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 6f66551d9e5..5c82ec7f8bb 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -150,7 +150,7 @@ static struct coretemp_data *coretemp_update_device(struct device *dev)
static int __devinit coretemp_probe(struct platform_device *pdev)
{
struct coretemp_data *data;
- struct cpuinfo_x86 *c = &(cpu_data)[pdev->id];
+ struct cpuinfo_x86 *c = &cpu_data(pdev->id);
int err;
u32 eax, edx;
@@ -359,7 +359,7 @@ static int __init coretemp_init(void)
struct pdev_entry *p, *n;
/* quick check if we run Intel */
- if (cpu_data[0].x86_vendor != X86_VENDOR_INTEL)
+ if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
goto exit;
err = platform_driver_register(&coretemp_driver);
@@ -367,7 +367,7 @@ static int __init coretemp_init(void)
goto exit;
for_each_online_cpu(i) {
- struct cpuinfo_x86 *c = &(cpu_data)[i];
+ struct cpuinfo_x86 *c = &cpu_data(i);
/* check if family 6, models e, f, 16 */
if ((c->cpuid_level < 0) || (c->x86 != 0x6) ||
diff --git a/drivers/hwmon/gl520sm.c b/drivers/hwmon/gl520sm.c
index a3b56c816e1..2d39d8fc238 100644
--- a/drivers/hwmon/gl520sm.c
+++ b/drivers/hwmon/gl520sm.c
@@ -2,7 +2,7 @@
gl520sm.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>,
- Kysti Mlkki <kmalkki@cc.hut.fi>
+ Kyösti Mälkki <kmalkki@cc.hut.fi>
Copyright (c) 2005 Maarten Deprez <maartendeprez@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
@@ -805,7 +805,7 @@ static void __exit sensors_gl520sm_exit(void)
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>, "
- "Kysti Mlkki <kmalkki@cc.hut.fi>, "
+ "Kyösti Mälkki <kmalkki@cc.hut.fi>, "
"Maarten Deprez <maartendeprez@users.sourceforge.net>");
MODULE_DESCRIPTION("GL520SM driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 8a7ae03aeee..bab5fd2e4df 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -574,7 +574,7 @@ static int __init hdaps_init(void)
idev = hdaps_idev->input;
idev->name = "hdaps";
idev->dev.parent = &pdev->dev;
- idev->evbit[0] = BIT(EV_ABS);
+ idev->evbit[0] = BIT_MASK(EV_ABS);
input_set_abs_params(idev, ABS_X,
-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
input_set_abs_params(idev, ABS_Y,
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index f17e771e42f..3330667280b 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -200,7 +200,7 @@ static u8 find_vrm(u8 eff_family, u8 eff_model, u8 eff_stepping, u8 vendor)
u8 vid_which_vrm(void)
{
- struct cpuinfo_x86 *c = cpu_data;
+ struct cpuinfo_x86 *c = &cpu_data(0);
u32 eax;
u8 eff_family, eff_model, eff_stepping, vrm_ret;
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index 860b71ccbb8..7e2d9787bab 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -3,7 +3,7 @@
for hardware monitoring
Copyright (C) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
- Kysti Mlkki <kmalkki@cc.hut.fi>, and
+ Kyösti Mälkki <kmalkki@cc.hut.fi>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
the help of Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index 8f63dada601..2635bba1e3f 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -3,7 +3,7 @@
for hardware monitoring
Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
- Kysti Mlkki <kmalkki@cc.hut.fi>,
+ Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark Studebaker <mdsxyz123@yahoo.com>,
and Bob Dougherty <bobd@stanford.edu>
(Some conversion-factor data were contributed by Jonathan Teh Soon Yew
@@ -866,7 +866,7 @@ static void __exit sm_via686a_exit(void)
}
}
-MODULE_AUTHOR("Kysti Mlkki <kmalkki@cc.hut.fi>, "
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>, "
"Mark Studebaker <mdsxyz123@yahoo.com> "
"and Bob Dougherty <bobd@stanford.edu>");
MODULE_DESCRIPTION("VIA 686A Sensor device");
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index 7f0a0a62cf6..a37cb6b8593 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -18,7 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------------------------------------------------- */
-/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kysti Mlkki
+/* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki
<kmalkki@cc.hut.fi> and Jean Delvare <khali@linux-fr.org> */
#include <linux/kernel.h>
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c
index 36fdf971f08..2a16211f12e 100644
--- a/drivers/i2c/algos/i2c-algo-pca.c
+++ b/drivers/i2c/algos/i2c-algo-pca.c
@@ -350,7 +350,7 @@ static int pca_init(struct i2c_algo_pca_data *adap)
pca_outw(adap, I2C_PCA_ADR, own << 1);
pca_set_con(adap, I2C_PCA_CON_ENSIO | clock);
- udelay(500); /* 500 s for oscilator to stabilise */
+ udelay(500); /* 500 µs for oscilator to stabilise */
return 0;
}
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c
index ecb2c2d7d54..ab2e6f3498b 100644
--- a/drivers/i2c/algos/i2c-algo-pcf.c
+++ b/drivers/i2c/algos/i2c-algo-pcf.c
@@ -19,7 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------------------------------------------------- */
-/* With some changes from Kysti Mlkki <kmalkki@cc.hut.fi> and
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
<mbailey@littlefeet-inc.com> */
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index de95c75efb4..c466c6cfc2e 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -278,7 +278,7 @@ config I2C_IXP2000
depends on ARCH_IXP2000
select I2C_ALGOBIT
help
- Say Y here if you have an Intel IXP2000(2400, 2800, 2850) based
+ Say Y here if you have an Intel IXP2000 (2400, 2800, 2850) based
system and are using GPIO lines for an I2C bus.
This support is also available as a module. If so, the module
@@ -293,8 +293,8 @@ config I2C_POWERMAC
default y
help
This exposes the various PowerMac i2c interfaces to the linux i2c
- layer and to userland. It is used by various drivers on the powemac
- platform, thus should generally be enabled.
+ layer and to userland. It is used by various drivers on the PowerMac
+ platform, and should generally be enabled.
This support is also available as a module. If so, the module
will be called i2c-powermac.
@@ -438,12 +438,12 @@ config I2C_SIMTEC
tristate "Simtec Generic I2C interface"
select I2C_ALGOBIT
help
- If you say yes to this option, support will be inclyded for
+ If you say yes to this option, support will be included for
the Simtec Generic I2C interface. This driver is for the
simple I2C bus used on newer Simtec products for general
I2C, such as DDC on the Simtec BBD2016A.
- This driver can also be build as a module. If so, the module
+ This driver can also be built as a module. If so, the module
will be called i2c-simtec.
config SCx200_I2C
diff --git a/drivers/i2c/busses/i2c-elektor.c b/drivers/i2c/busses/i2c-elektor.c
index 804f0a551c0..b7a9977b025 100644
--- a/drivers/i2c/busses/i2c-elektor.c
+++ b/drivers/i2c/busses/i2c-elektor.c
@@ -19,7 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------------------------------------------------- */
-/* With some changes from Kysti Mlkki <kmalkki@cc.hut.fi> and even
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
Frodo Looijaard <frodol@dds.nl> */
/* Partialy rewriten by Oleg I. Vdovikin for mmapped support of
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 9832f773651..f9972f9651e 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -7,7 +7,7 @@
Copyright (c) 1999-2004 Geert Uytterhoeven <geert@linux-m68k.org>
Based on i2c Support for Via Technologies 82C586B South Bridge
- Copyright (c) 1998, 1999 Kysti Mlkki <kmalkki@cc.hut.fi>
+ Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index e08bacadd6b..9b43ff7270d 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -18,7 +18,7 @@
* Copyright 1995-97 Simon G. Vogl
* 1998-99 Hans Berglund
*
- * With some changes from Kysti Mlkki <kmalkki@cc.hut.fi>
+ * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>
* and even Frodo Looijaard <frodol@dds.nl>
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e471e3bfdc1..89a30028ddb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -8,7 +8,7 @@
* Tony Lindgren <tony@atomide.com> and Imre Deak <imre.deak@nokia.com>
* Copyright (C) 2005 Nokia Corporation
*
- * Cleaned up by Juha Yrjl <juha.yrjola@nokia.com>
+ * Cleaned up by Juha Yrjölä <juha.yrjola@nokia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
index 49a95e2887b..c6faf9bdad1 100644
--- a/drivers/i2c/busses/i2c-parport-light.c
+++ b/drivers/i2c/busses/i2c-parport-light.c
@@ -7,7 +7,7 @@
Copyright (C) 1995-2000 Simon G. Vogl
With some changes from:
Frodo Looijaard <frodol@dds.nl>
- Kysti Mlkki <kmalkki@cc.hut.fi>
+ Kyösti Mälkki <kmalkki@cc.hut.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 039a07fde90..59ba2086d2f 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -7,7 +7,7 @@
Copyright (C) 1995-2000 Simon G. Vogl
With some changes from:
Frodo Looijaard <frodol@dds.nl>
- Kysti Mlkki <kmalkki@cc.hut.fi>
+ Kyösti Mälkki <kmalkki@cc.hut.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index 00fad11733a..6426a61f8d4 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -85,7 +85,7 @@ struct bits {
const char *set;
const char *unset;
};
-#define BIT(m, s, u) { .mask = m, .set = s, .unset = u }
+#define PXA_BIT(m, s, u) { .mask = m, .set = s, .unset = u }
static inline void
decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
@@ -100,17 +100,17 @@ decode_bits(const char *prefix, const struct bits *bits, int num, u32 val)
}
static const struct bits isr_bits[] = {
- BIT(ISR_RWM, "RX", "TX"),
- BIT(ISR_ACKNAK, "NAK", "ACK"),
- BIT(ISR_UB, "Bsy", "Rdy"),
- BIT(ISR_IBB, "BusBsy", "BusRdy"),
- BIT(ISR_SSD, "SlaveStop", NULL),
- BIT(ISR_ALD, "ALD", NULL),
- BIT(ISR_ITE, "TxEmpty", NULL),
- BIT(ISR_IRF, "RxFull", NULL),
- BIT(ISR_GCAD, "GenCall", NULL),
- BIT(ISR_SAD, "SlaveAddr", NULL),
- BIT(ISR_BED, "BusErr", NULL),
+ PXA_BIT(ISR_RWM, "RX", "TX"),
+ PXA_BIT(ISR_ACKNAK, "NAK", "ACK"),
+ PXA_BIT(ISR_UB, "Bsy", "Rdy"),
+ PXA_BIT(ISR_IBB, "BusBsy", "BusRdy"),
+ PXA_BIT(ISR_SSD, "SlaveStop", NULL),
+ PXA_BIT(ISR_ALD, "ALD", NULL),
+ PXA_BIT(ISR_ITE, "TxEmpty", NULL),
+ PXA_BIT(ISR_IRF, "RxFull", NULL),
+ PXA_BIT(ISR_GCAD, "GenCall", NULL),
+ PXA_BIT(ISR_SAD, "SlaveAddr", NULL),
+ PXA_BIT(ISR_BED, "BusErr", NULL),
};
static void decode_ISR(unsigned int val)
@@ -120,21 +120,21 @@ static void decode_ISR(unsigned int val)
}
static const struct bits icr_bits[] = {
- BIT(ICR_START, "START", NULL),
- BIT(ICR_STOP, "STOP", NULL),
- BIT(ICR_ACKNAK, "ACKNAK", NULL),
- BIT(ICR_TB, "TB", NULL),
- BIT(ICR_MA, "MA", NULL),
- BIT(ICR_SCLE, "SCLE", "scle"),
- BIT(ICR_IUE, "IUE", "iue"),
- BIT(ICR_GCD, "GCD", NULL),
- BIT(ICR_ITEIE, "ITEIE", NULL),
- BIT(ICR_IRFIE, "IRFIE", NULL),
- BIT(ICR_BEIE, "BEIE", NULL),
- BIT(ICR_SSDIE, "SSDIE", NULL),
- BIT(ICR_ALDIE, "ALDIE", NULL),
- BIT(ICR_SADIE, "SADIE", NULL),
- BIT(ICR_UR, "UR", "ur"),
+ PXA_BIT(ICR_START, "START", NULL),
+ PXA_BIT(ICR_STOP, "STOP", NULL),
+ PXA_BIT(ICR_ACKNAK, "ACKNAK", NULL),
+ PXA_BIT(ICR_TB, "TB", NULL),
+ PXA_BIT(ICR_MA, "MA", NULL),
+ PXA_BIT(ICR_SCLE, "SCLE", "scle"),
+ PXA_BIT(ICR_IUE, "IUE", "iue"),
+ PXA_BIT(ICR_GCD, "GCD", NULL),
+ PXA_BIT(ICR_ITEIE, "ITEIE", NULL),
+ PXA_BIT(ICR_IRFIE, "IRFIE", NULL),
+ PXA_BIT(ICR_BEIE, "BEIE", NULL),
+ PXA_BIT(ICR_SSDIE, "SSDIE", NULL),
+ PXA_BIT(ICR_ALDIE, "ALDIE", NULL),
+ PXA_BIT(ICR_SADIE, "SADIE", NULL),
+ PXA_BIT(ICR_UR, "UR", "ur"),
};
static void decode_ICR(unsigned int val)
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 81520868797..61716f6b14d 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -4,7 +4,7 @@
i2c Support for Via Technologies 82C586B South Bridge
- Copyright (c) 1998, 1999 Kysti Mlkki <kmalkki@cc.hut.fi>
+ Copyright (c) 1998, 1999 Kyösti Mälkki <kmalkki@cc.hut.fi>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -176,7 +176,7 @@ static void __exit i2c_vt586b_exit(void)
}
-MODULE_AUTHOR("Kysti Mlkki <kmalkki@cc.hut.fi>");
+MODULE_AUTHOR("Kyösti Mälkki <kmalkki@cc.hut.fi>");
MODULE_DESCRIPTION("i2c for Via vt82c586b southbridge");
MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index edc275002f8..c9ce77f13c0 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -2,7 +2,7 @@
i2c-viapro.c - Part of lm_sensors, Linux kernel modules for hardware
monitoring
Copyright (c) 1998 - 2002 Frodo Looijaard <frodol@dds.nl>,
- Philip Edelbrock <phil@netroedge.com>, Kysti Mlkki <kmalkki@cc.hut.fi>,
+ Philip Edelbrock <phil@netroedge.com>, Kyösti Mälkki <kmalkki@cc.hut.fi>,
Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2005 - 2007 Jean Delvare <khali@linux-fr.org>
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e73d58c43f3..1a4e8dc03b3 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -17,7 +17,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* ------------------------------------------------------------------------- */
-/* With some changes from Kysti Mlkki <kmalkki@cc.hut.fi>.
+/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
Jean Delvare <khali@linux-fr.org> */
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 6d9fd92763f..6eaece96524 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -1056,6 +1056,9 @@ endif
config BLK_DEV_IDEDMA
def_bool BLK_DEV_IDEDMA_PCI || BLK_DEV_IDEDMA_PMAC || BLK_DEV_IDEDMA_ICS || BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
+config IDE_ARCH_OBSOLETE_INIT
+ def_bool ALPHA || (ARM && !ARCH_L7200) || BLACKFIN || X86 || IA64 || M32R || MIPS || PARISC || PPC || (SUPERH64 && BLK_DEV_IDEPCI) || SPARC
+
endif
config BLK_DEV_HD_ONLY
diff --git a/drivers/ide/arm/bast-ide.c b/drivers/ide/arm/bast-ide.c
index f7449d04114..48db6167bb9 100644
--- a/drivers/ide/arm/bast-ide.c
+++ b/drivers/ide/arm/bast-ide.c
@@ -45,7 +45,7 @@ bastide_register(unsigned int base, unsigned int aux, int irq,
hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20);
hw.irq = irq;
- ide_register_hw(&hw, 0, hwif);
+ ide_register_hw(&hw, NULL, 0, hwif);
return 0;
}
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 3af33fbf1f8..410a0d13e35 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -316,27 +316,29 @@ static int icside_dma_end(ide_drive_t *drive)
drive->waiting_for_dma = 0;
- disable_dma(hwif->hw.dma);
+ disable_dma(state->dev->dma);
/* Teardown mappings after DMA has completed. */
dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents,
hwif->sg_dma_direction);
- return get_dma_residue(hwif->hw.dma) != 0;
+ return get_dma_residue(state->dev->dma) != 0;
}
static void icside_dma_start(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
+ struct icside_state *state = hwif->hwif_data;
/* We can not enable DMA on both channels simultaneously. */
- BUG_ON(dma_channel_active(hwif->hw.dma));
- enable_dma(hwif->hw.dma);
+ BUG_ON(dma_channel_active(state->dev->dma));
+ enable_dma(state->dev->dma);
}
static int icside_dma_setup(ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
+ struct icside_state *state = hwif->hwif_data;
struct request *rq = hwif->hwgroup->rq;
unsigned int dma_mode;
@@ -348,7 +350,7 @@ static int icside_dma_setup(ide_drive_t *drive)
/*
* We can not enable DMA on both channels.
*/
- BUG_ON(dma_channel_active(hwif->hw.dma));
+ BUG_ON(dma_channel_active(state->dev->dma));
icside_build_sglist(drive, rq);
@@ -365,14 +367,14 @@ static int icside_dma_setup(ide_drive_t *drive)
/*
* Select the correct timing for this drive.
*/
- set_dma_speed(hwif->hw.dma, drive->drive_data);
+ set_dma_speed(state->dev->dma, drive->drive_data);
/*
* Tell the DMA engine about the SG table and
* data direction.
*/
- set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents);
- set_dma_mode(hwif->hw.dma, dma_mode);
+ set_dma_sg(state->dev->dma, hwif->sg_table, hwif->sg_nents);
+ set_dma_mode(state->dev->dma, dma_mode);
drive->waiting_for_dma = 1;
@@ -438,40 +440,16 @@ static void icside_dma_init(ide_hwif_t *hwif)
#define icside_dma_init(hwif) (0)
#endif
-static ide_hwif_t *icside_find_hwif(unsigned long dataport)
-{
- ide_hwif_t *hwif;
- int index;
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = &ide_hwifs[index];
- if (hwif->io_ports[IDE_DATA_OFFSET] == dataport)
- goto found;
- }
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = &ide_hwifs[index];
- if (!hwif->io_ports[IDE_DATA_OFFSET])
- goto found;
- }
-
- hwif = NULL;
-found:
- return hwif;
-}
-
static ide_hwif_t *
icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *ec)
{
unsigned long port = (unsigned long)base + info->dataoffset;
ide_hwif_t *hwif;
- hwif = icside_find_hwif(port);
+ hwif = ide_find_port(port);
if (hwif) {
int i;
- memset(&hwif->hw, 0, sizeof(hw_regs_t));
-
/*
* Ensure we're using MMIO
*/
@@ -479,13 +457,10 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
hwif->mmio = 1;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hwif->hw.io_ports[i] = port;
hwif->io_ports[i] = port;
port += 1 << info->stepping;
}
- hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)base + info->ctrloffset;
- hwif->hw.irq = ec->irq;
hwif->irq = ec->irq;
hwif->noprobe = 0;
hwif->chipset = ide_acorn;
@@ -500,6 +475,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
{
ide_hwif_t *hwif;
void __iomem *base;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
if (!base)
@@ -523,9 +499,9 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
state->hwif[0] = hwif;
- probe_hwif_init(hwif);
+ idx[0] = hwif->index;
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
return 0;
}
@@ -537,6 +513,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
void __iomem *ioc_base, *easi_base;
unsigned int sel = 0;
int ret;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
if (!ioc_base) {
@@ -592,7 +569,6 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
hwif->serialized = 1;
hwif->config_data = (unsigned long)ioc_base;
hwif->select_data = sel;
- hwif->hw.dma = ec->dma;
mate->maskproc = icside_maskproc;
mate->channel = 1;
@@ -601,18 +577,16 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec)
mate->serialized = 1;
mate->config_data = (unsigned long)ioc_base;
mate->select_data = sel | 1;
- mate->hw.dma = ec->dma;
if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
icside_dma_init(hwif);
icside_dma_init(mate);
}
- probe_hwif_init(hwif);
- probe_hwif_init(mate);
+ idx[0] = hwif->index;
+ idx[1] = mate->index;
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c
index bce2bec8141..8957cbadf5c 100644
--- a/drivers/ide/arm/ide_arm.c
+++ b/drivers/ide/arm/ide_arm.c
@@ -31,5 +31,5 @@ void __init ide_arm_init(void)
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206);
hw.irq = IDE_ARM_IRQ;
- ide_register_hw(&hw, 1, NULL);
+ ide_register_hw(&hw, NULL, 1, NULL);
}
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 83811af1161..0775a3afef4 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -13,42 +13,25 @@
#include <asm/ecard.h>
-/*
- * Something like this really should be in generic code, but isn't.
- */
static ide_hwif_t *
rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq)
{
unsigned long port = (unsigned long)base;
- ide_hwif_t *hwif;
- int index, i;
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = ide_hwifs + index;
- if (hwif->io_ports[IDE_DATA_OFFSET] == port)
- goto found;
- }
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = ide_hwifs + index;
- if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
- goto found;
- }
+ ide_hwif_t *hwif = ide_find_port(port);
+ int i;
- return NULL;
+ if (hwif == NULL)
+ goto out;
- found:
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hwif->hw.io_ports[i] = port;
hwif->io_ports[i] = port;
port += sz;
}
- hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
- hwif->hw.irq = hwif->irq = irq;
+ hwif->irq = irq;
hwif->mmio = 1;
default_hwif_mmiops(hwif);
-
+out:
return hwif;
}
@@ -58,6 +41,7 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
ide_hwif_t *hwif;
void __iomem *base;
int ret;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
ret = ecard_request_resources(ec);
if (ret)
@@ -74,8 +58,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id)
hwif->hwif_data = base;
hwif->gendev.parent = &ec->dev;
hwif->noprobe = 0;
- probe_hwif_init(hwif);
- ide_proc_register_port(hwif);
+
+ idx[0] = hwif->index;
+
+ ide_device_add(idx);
+
ecard_set_drvdata(ec, hwif);
goto out;
}
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 9a96a10ba9d..e196aefa207 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -782,7 +782,7 @@ init_e100_ide (void)
ide_offsets,
0, 0, cris_ide_ack_intr,
ide_default_irq(0));
- ide_register_hw(&hw, 1, &hwif);
+ ide_register_hw(&hw, NULL, 1, &hwif);
hwif->mmio = 1;
hwif->chipset = ide_etrax100;
hwif->set_pio_mode = &cris_set_pio_mode;
@@ -935,11 +935,11 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
* than two possibly non-adjacent physical 4kB pages.
*/
/* group sequential buffers into one large buffer */
- addr = page_to_phys(sg->page) + sg->offset;
+ addr = sg_phys(sg);
size = sg_dma_len(sg);
while (--i) {
sg = sg_next(sg);
- if ((addr + size) != page_to_phys(sg->page) + sg->offset)
+ if ((addr + size) != sg_phys(sg))
break;
size += sg_dma_len(sg);
}
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 6d26ad7360d..4a49b5c59ac 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -68,7 +68,6 @@ static inline void hw_setup(hw_regs_t *hw)
hw->io_ports[i] = CONFIG_H8300_IDE_BASE + H8300_IDE_GAP*i;
hw->io_ports[IDE_CONTROL_OFFSET] = CONFIG_H8300_IDE_ALT;
hw->irq = EXT_IRQ0 + CONFIG_H8300_IDE_IRQ;
- hw->dma = NO_DMA;
hw->chipset = ide_generic;
}
@@ -101,7 +100,7 @@ void __init h8300_ide_init(void)
hw_setup(&hw);
/* register if */
- idx = ide_register_hw(&hw, 1, &hwif);
+ idx = ide_register_hw(&hw, NULL, 1, &hwif);
if (idx == -1) {
printk(KERN_ERR "ide-h8300: IDE I/F register failed\n");
return;
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 1d5f6823101..89df48fdc69 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -350,7 +350,7 @@ static int taskfile_load_raw(ide_drive_t *drive,
memset(&args, 0, sizeof(ide_task_t));
args.command_type = IDE_DRIVE_TASK_NO_DATA;
- args.data_phase = TASKFILE_IN;
+ args.data_phase = TASKFILE_NO_DATA;
args.handler = &task_no_data_intr;
/* convert gtf to IDE Taskfile */
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index ca843522f91..57a5f63d6ae 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -120,7 +120,7 @@
* Reformat to match kernel tabbing style.
* Add CDROM_GET_UPC ioctl.
* 3.10 Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
- * 3.11 Apr 29, 1996 -- Patch from Heiko Eissfeldt <heiko@colossus.escape.de>
+ * 3.11 Apr 29, 1996 -- Patch from Heiko Eißfeldt <heiko@colossus.escape.de>
* to remove redundant verify_area calls.
* 3.12 May 7, 1996 -- Rudimentary changer support. Based on patches
* from Gerhard Zuber <zuber@berlin.snafu.de>.
@@ -256,7 +256,7 @@
* - Minimize the TOC reading - only do it when we
* know a media change has occurred.
* - Moved all the CDROMREADx ioctls to the Uniform layer.
- * - Heiko Eissfeldt <heiko@colossus.escape.de> supplied
+ * - Heiko Eißfeldt <heiko@colossus.escape.de> supplied
* some fixes for CDI.
* - CD-ROM leaving door locked fix from Andries
* Brouwer <Andries.Brouwer@cwi.nl>
@@ -2341,7 +2341,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
If we get an error for the regular case, we assume
a CDI without additional audio tracks. In this case
the readable TOC is empty (CDI tracks are not included)
- and only holds the Leadout entry. Heiko Eifeldt */
+ and only holds the Leadout entry. Heiko Eißfeldt */
ntracks = 0;
stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
(char *)&toc->hdr,
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 2722d9165b6..00123d99527 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -593,28 +593,12 @@ static int smart_enable(ide_drive_t *drive)
return ide_raw_taskfile(drive, &args, NULL);
}
-static int get_smart_values(ide_drive_t *drive, u8 *buf)
+static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
{
ide_task_t args;
memset(&args, 0, sizeof(ide_task_t));
- args.tfRegister[IDE_FEATURE_OFFSET] = SMART_READ_VALUES;
- args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01;
- args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS;
- args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
- args.tfRegister[IDE_COMMAND_OFFSET] = WIN_SMART;
- args.command_type = IDE_DRIVE_TASK_IN;
- args.data_phase = TASKFILE_IN;
- args.handler = &task_in_intr;
- (void) smart_enable(drive);
- return ide_raw_taskfile(drive, &args, buf);
-}
-
-static int get_smart_thresholds(ide_drive_t *drive, u8 *buf)
-{
- ide_task_t args;
- memset(&args, 0, sizeof(ide_task_t));
- args.tfRegister[IDE_FEATURE_OFFSET] = SMART_READ_THRESHOLDS;
+ args.tfRegister[IDE_FEATURE_OFFSET] = sub_cmd;
args.tfRegister[IDE_NSECTOR_OFFSET] = 0x01;
args.tfRegister[IDE_LCYL_OFFSET] = SMART_LCYL_PASS;
args.tfRegister[IDE_HCYL_OFFSET] = SMART_HCYL_PASS;
@@ -656,7 +640,7 @@ static int proc_idedisk_read_smart_thresholds
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
- if (!get_smart_thresholds(drive, page)) {
+ if (get_smart_data(drive, page, SMART_READ_THRESHOLDS) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = ((char *)val) + (SECTOR_WORDS * 4);
page = out;
@@ -675,7 +659,7 @@ static int proc_idedisk_read_smart_values
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
- if (!get_smart_values(drive, page)) {
+ if (get_smart_data(drive, page, SMART_READ_VALUES) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = ((char *)val) + (SECTOR_WORDS * 4);
page = out;
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 80b4f17f394..428f7a8a00b 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -901,10 +901,7 @@ void ide_dma_timeout (ide_drive_t *drive)
EXPORT_SYMBOL(ide_dma_timeout);
-/*
- * Needed for allowing full modular support of ide-driver
- */
-static int ide_release_dma_engine(ide_hwif_t *hwif)
+static void ide_release_dma_engine(ide_hwif_t *hwif)
{
if (hwif->dmatable_cpu) {
pci_free_consistent(hwif->pci_dev,
@@ -913,7 +910,6 @@ static int ide_release_dma_engine(ide_hwif_t *hwif)
hwif->dmatable_dma);
hwif->dmatable_cpu = NULL;
}
- return 1;
}
static int ide_release_iomio_dma(ide_hwif_t *hwif)
@@ -956,12 +952,6 @@ static int ide_mapped_mmio_dma(ide_hwif_t *hwif, unsigned long base, unsigned in
{
printk(KERN_INFO " %s: MMIO-DMA ", hwif->name);
- hwif->dma_base = base;
-
- if(hwif->mate)
- hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base;
- else
- hwif->dma_master = base;
return 0;
}
@@ -975,8 +965,6 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
return 1;
}
- hwif->dma_base = base;
-
if (hwif->cds->extra) {
hwif->extra_base = base + (hwif->channel ? 8 : 16);
@@ -991,10 +979,6 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
}
}
- if(hwif->mate)
- hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base:base;
- else
- hwif->dma_master = base;
return 0;
}
@@ -1006,12 +990,9 @@ static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int por
return ide_iomio_dma(hwif, base, ports);
}
-/*
- * This can be called for a dynamically installed interface. Don't __init it
- */
-void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
+void ide_setup_dma(ide_hwif_t *hwif, unsigned long base, unsigned num_ports)
{
- if (ide_dma_iobase(hwif, dma_base, num_ports))
+ if (ide_dma_iobase(hwif, base, num_ports))
return;
if (ide_allocate_dma_engine(hwif)) {
@@ -1019,6 +1000,13 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
return;
}
+ hwif->dma_base = base;
+
+ if (hwif->mate)
+ hwif->dma_master = hwif->channel ? hwif->mate->dma_base : base;
+ else
+ hwif->dma_master = base;
+
if (!(hwif->dma_command))
hwif->dma_command = hwif->dma_base;
if (!(hwif->dma_vendor1))
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 5c8b008676f..c89f0d3058e 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -47,15 +47,15 @@
#include <linux/device.h>
#include <linux/kmod.h>
#include <linux/scatterlist.h>
+#include <linux/bitops.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/bitops.h>
static int __ide_end_request(ide_drive_t *drive, struct request *rq,
- int uptodate, unsigned int nr_bytes)
+ int uptodate, unsigned int nr_bytes, int dequeue)
{
int ret = 1;
@@ -80,9 +80,11 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
add_disk_randomness(rq->rq_disk);
- if (!list_empty(&rq->queuelist))
- blkdev_dequeue_request(rq);
- HWGROUP(drive)->rq = NULL;
+ if (dequeue) {
+ if (!list_empty(&rq->queuelist))
+ blkdev_dequeue_request(rq);
+ HWGROUP(drive)->rq = NULL;
+ }
end_that_request_last(rq, uptodate);
ret = 0;
}
@@ -122,7 +124,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
nr_bytes = rq->hard_cur_sectors << 9;
}
- ret = __ide_end_request(drive, rq, uptodate, nr_bytes);
+ ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
spin_unlock_irqrestore(&ide_lock, flags);
return ret;
@@ -255,39 +257,13 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
int uptodate, int nr_sectors)
{
unsigned long flags;
- int ret = 1;
+ int ret;
spin_lock_irqsave(&ide_lock, flags);
-
BUG_ON(!blk_rq_started(rq));
-
- /*
- * if failfast is set on a request, override number of sectors and
- * complete the whole request right now
- */
- if (blk_noretry_request(rq) && end_io_error(uptodate))
- nr_sectors = rq->hard_nr_sectors;
-
- if (!blk_fs_request(rq) && end_io_error(uptodate) && !rq->errors)
- rq->errors = -EIO;
-
- /*
- * decide whether to reenable DMA -- 3 is a random magic for now,
- * if we DMA timeout more than 3 times, just stay in PIO
- */
- if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
- drive->state = 0;
- HWGROUP(drive)->hwif->ide_dma_on(drive);
- }
-
- if (!end_that_request_first(rq, uptodate, nr_sectors)) {
- add_disk_randomness(rq->rq_disk);
- if (blk_rq_tagged(rq))
- blk_queue_end_tag(drive->queue, rq);
- end_that_request_last(rq, uptodate);
- ret = 0;
- }
+ ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
spin_unlock_irqrestore(&ide_lock, flags);
+
return ret;
}
EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
@@ -800,7 +776,20 @@ static ide_startstop_t do_special (ide_drive_t *drive)
s->b.set_tune = 0;
if (set_pio_mode_abuse(drive->hwif, req_pio)) {
- if (hwif->set_pio_mode)
+
+ if (hwif->set_pio_mode == NULL)
+ return ide_stopped;
+
+ /*
+ * take ide_lock for drive->[no_]unmask/[no_]io_32bit
+ */
+ if (req_pio == 8 || req_pio == 9) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&ide_lock, flags);
+ hwif->set_pio_mode(drive, req_pio);
+ spin_unlock_irqrestore(&ide_lock, flags);
+ } else
hwif->set_pio_mode(drive, req_pio);
} else {
int keep_dma = drive->using_dma;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index d4d790f91f9..95168833d06 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -693,35 +693,16 @@ static u8 ide_auto_reduce_xfer (ide_drive_t *drive)
}
#endif /* CONFIG_BLK_DEV_IDEDMA */
-/*
- * Update the
- */
-int ide_driveid_update (ide_drive_t *drive)
+int ide_driveid_update(ide_drive_t *drive)
{
- ide_hwif_t *hwif = HWIF(drive);
+ ide_hwif_t *hwif = drive->hwif;
struct hd_driveid *id;
-#if 0
- id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC);
- if (!id)
- return 0;
-
- taskfile_lib_get_identify(drive, (char *)&id);
+ unsigned long timeout, flags;
- ide_fix_driveid(id);
- if (id) {
- drive->id->dma_ultra = id->dma_ultra;
- drive->id->dma_mword = id->dma_mword;
- drive->id->dma_1word = id->dma_1word;
- /* anything more ? */
- kfree(id);
- }
- return 1;
-#else
/*
* Re-read drive->id for possible DMA mode
* change (copied from ide-probe.c)
*/
- unsigned long timeout, flags;
SELECT_MASK(drive, 1);
if (IDE_CONTROL_REG)
@@ -763,7 +744,6 @@ int ide_driveid_update (ide_drive_t *drive)
}
return 1;
-#endif
}
int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index 2b8009c50e9..e245521af7b 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -40,9 +40,8 @@ static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id
ide_std_init_ports(&hw, pnp_port_start(dev, 0),
pnp_port_start(dev, 1));
hw.irq = pnp_irq(dev, 0);
- hw.dma = NO_DMA;
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
if (index != -1) {
printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index e294c7415c2..ec55a173c08 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -717,7 +717,7 @@ EXPORT_SYMBOL_GPL(ide_undecoded_slave);
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/
-static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static void probe_hwif(ide_hwif_t *hwif)
{
unsigned long flags;
unsigned int irqd;
@@ -819,8 +819,8 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
return;
}
- if (fixup)
- fixup(hwif);
+ if (hwif->fixup)
+ hwif->fixup(hwif);
for (unit = 0; unit < MAX_DRIVES; ++unit) {
ide_drive_t *drive = &hwif->drives[unit];
@@ -859,10 +859,11 @@ static void probe_hwif(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
}
static int hwif_init(ide_hwif_t *hwif);
+static void hwif_register_devices(ide_hwif_t *hwif);
-int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif))
+static int probe_hwif_init(ide_hwif_t *hwif)
{
- probe_hwif(hwif, fixup);
+ probe_hwif(hwif);
if (!hwif_init(hwif)) {
printk(KERN_INFO "%s: failed to initialize IDE interface\n",
@@ -870,34 +871,12 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif)
return -1;
}
- if (hwif->present) {
- u16 unit = 0;
- int ret;
+ if (hwif->present)
+ hwif_register_devices(hwif);
- for (unit = 0; unit < MAX_DRIVES; ++unit) {
- ide_drive_t *drive = &hwif->drives[unit];
- /* For now don't attach absent drives, we may
- want them on default or a new "empty" class
- for hotplug reprobing ? */
- if (drive->present) {
- ret = device_register(&drive->gendev);
- if (ret < 0)
- printk(KERN_WARNING "IDE: %s: "
- "device_register error: %d\n",
- __FUNCTION__, ret);
- }
- }
- }
return 0;
}
-int probe_hwif_init(ide_hwif_t *hwif)
-{
- return probe_hwif_init_with_fixup(hwif, NULL);
-}
-
-EXPORT_SYMBOL(probe_hwif_init);
-
#if MAX_HWIFS > 1
/*
* save_match() is used to simplify logic in init_irq() below.
@@ -1338,12 +1317,14 @@ static int hwif_init(ide_hwif_t *hwif)
if (!hwif->sg_max_nents)
hwif->sg_max_nents = PRD_ENTRIES;
- hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
+ hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
GFP_KERNEL);
if (!hwif->sg_table) {
printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
goto out;
}
+
+ sg_init_table(hwif->sg_table, hwif->sg_max_nents);
if (init_irq(hwif) == 0)
goto done;
@@ -1379,6 +1360,24 @@ out:
return 0;
}
+static void hwif_register_devices(ide_hwif_t *hwif)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAX_DRIVES; i++) {
+ ide_drive_t *drive = &hwif->drives[i];
+
+ if (drive->present) {
+ int ret = device_register(&drive->gendev);
+
+ if (ret < 0)
+ printk(KERN_WARNING "IDE: %s: "
+ "device_register error: %d\n",
+ __FUNCTION__, ret);
+ }
+ }
+}
+
int ideprobe_init (void)
{
unsigned int index;
@@ -1390,27 +1389,18 @@ int ideprobe_init (void)
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
- probe_hwif(&ide_hwifs[index], NULL);
+ probe_hwif(&ide_hwifs[index]);
for (index = 0; index < MAX_HWIFS; ++index)
if (probe[index])
hwif_init(&ide_hwifs[index]);
for (index = 0; index < MAX_HWIFS; ++index) {
if (probe[index]) {
ide_hwif_t *hwif = &ide_hwifs[index];
- int unit;
if (!hwif->present)
continue;
if (hwif->chipset == ide_unknown || hwif->chipset == ide_forced)
hwif->chipset = ide_generic;
- for (unit = 0; unit < MAX_DRIVES; ++unit)
- if (hwif->drives[unit].present) {
- int ret = device_register(
- &hwif->drives[unit].gendev);
- if (ret < 0)
- printk(KERN_WARNING "IDE: %s: "
- "device_register error: %d\n",
- __FUNCTION__, ret);
- }
+ hwif_register_devices(hwif);
}
}
for (index = 0; index < MAX_HWIFS; ++index)
@@ -1420,3 +1410,22 @@ int ideprobe_init (void)
}
EXPORT_SYMBOL_GPL(ideprobe_init);
+
+int ide_device_add(u8 idx[4])
+{
+ int i, rc = 0;
+
+ for (i = 0; i < 4; i++) {
+ if (idx[i] != 0xff)
+ rc |= probe_hwif_init(&ide_hwifs[idx[i]]);
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (idx[i] != 0xff)
+ ide_proc_register_port(&ide_hwifs[idx[i]]);
+ }
+
+ return rc;
+}
+
+EXPORT_SYMBOL_GPL(ide_device_add);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index fc1d8ae6a80..a4007d30da5 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -804,8 +804,6 @@ void ide_proc_register_port(ide_hwif_t *hwif)
create_proc_ide_drives(hwif);
}
-EXPORT_SYMBOL_GPL(ide_proc_register_port);
-
#ifdef CONFIG_BLK_DEV_IDEPCI
void ide_pci_create_host_proc(const char *name, get_info_t *get_info)
{
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 1fa57947bca..7b9181b5469 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -565,7 +565,7 @@ typedef struct os_dat_s {
* The following parameter is used to select the point in the internal
* tape fifo in which we will start to refill the buffer. Decreasing
* the following parameter will improve the system's latency and
- * interactive response, while using a high value might improve sytem
+ * interactive response, while using a high value might improve system
* throughput.
*/
#define IDETAPE_FIFO_THRESHOLD 2
@@ -621,7 +621,6 @@ typedef struct os_dat_s {
*/
#define USE_IOTRACE 0
#if USE_IOTRACE
-#include <linux/io_trace.h>
#define IO_IDETAPE_FIFO 500
#endif
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 2a3c8d49834..d066546f283 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -8,23 +8,6 @@
* Copyright (C) 2003-2004 Bartlomiej Zolnierkiewicz
*
* The big the bad and the ugly.
- *
- * Problems to be fixed because of BH interface or the lack therefore.
- *
- * Fill me in stupid !!!
- *
- * HOST:
- * General refers to the Controller and Driver "pair".
- * DATA HANDLER:
- * Under the context of Linux it generally refers to an interrupt handler.
- * However, it correctly describes the 'HOST'
- * DATA BLOCK:
- * The amount of data needed to be transfered as predefined in the
- * setup of the device.
- * STORAGE ATOMIC:
- * The 'DATA BLOCK' associated to the 'DATA HANDLER', and can be as
- * small as a single sector or as large as the entire command block
- * request.
*/
#include <linux/module.h>
@@ -278,7 +261,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
hwif->cursg = sg;
}
- page = cursg->page;
+ page = sg_page(cursg);
offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
/* get the current page and offset */
@@ -695,9 +678,6 @@ int ide_wait_cmd (ide_drive_t *drive, u8 cmd, u8 nsect, u8 feature, u8 sectors,
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
int ide_cmd_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
{
int err = 0;
@@ -761,9 +741,6 @@ static int ide_wait_cmd_task(ide_drive_t *drive, u8 *buf)
return ide_do_drive_cmd(drive, &rq, ide_wait);
}
-/*
- * FIXME : this needs to map into at taskfile. <andre@linux-ide.org>
- */
int ide_task_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
{
void __user *p = (void __user *)arg;
@@ -860,9 +837,14 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
case TASKFILE_OUT_DMA:
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
- hwif->dma_setup(drive);
- hwif->dma_exec_cmd(drive, taskfile->command);
- hwif->dma_start(drive);
+ if (!drive->using_dma)
+ break;
+
+ if (!hwif->dma_setup(drive)) {
+ hwif->dma_exec_cmd(drive, taskfile->command);
+ hwif->dma_start(drive);
+ return ide_started;
+ }
break;
default:
@@ -876,7 +858,8 @@ ide_startstop_t flagged_taskfile (ide_drive_t *drive, ide_task_t *task)
return task->prehandler(drive, task->rq);
}
ide_execute_command(drive, taskfile->command, task->handler, WAIT_WORSTCASE, NULL);
+ return ide_started;
}
- return ide_started;
+ return ide_stopped;
}
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 961e6c89728..674a65c1a13 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -168,7 +168,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
- memcpy(&hwif->hw, &hw, sizeof(hw));
memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
@@ -214,7 +213,7 @@ static void __init init_ide_data (void)
init_hwif_data(hwif, index);
init_hwif_default(hwif, index);
#if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI)
- hwif->irq = hwif->hw.irq =
+ hwif->irq =
ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]);
#endif
}
@@ -265,6 +264,30 @@ static int ide_system_bus_speed(void)
return system_bus_speed;
}
+ide_hwif_t * ide_find_port(unsigned long base)
+{
+ ide_hwif_t *hwif;
+ int i;
+
+ for (i = 0; i < MAX_HWIFS; i++) {
+ hwif = &ide_hwifs[i];
+ if (hwif->io_ports[IDE_DATA_OFFSET] == base)
+ goto found;
+ }
+
+ for (i = 0; i < MAX_HWIFS; i++) {
+ hwif = &ide_hwifs[i];
+ if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
+ goto found;
+ }
+
+ hwif = NULL;
+found:
+ return hwif;
+}
+
+EXPORT_SYMBOL_GPL(ide_find_port);
+
static struct resource* hwif_request_region(ide_hwif_t *hwif,
unsigned long addr, int num)
{
@@ -391,6 +414,8 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
hwif->cds = tmp_hwif->cds;
#endif
+ hwif->fixup = tmp_hwif->fixup;
+
hwif->set_pio_mode = tmp_hwif->set_pio_mode;
hwif->set_dma_mode = tmp_hwif->set_dma_mode;
hwif->mdma_filter = tmp_hwif->mdma_filter;
@@ -652,7 +677,6 @@ void ide_setup_ports ( hw_regs_t *hw,
}
}
hw->irq = irq;
- hw->dma = NO_DMA;
hw->ack_intr = ack_intr;
/*
* hw->iops = iops;
@@ -660,11 +684,11 @@ void ide_setup_ports ( hw_regs_t *hw,
}
/**
- * ide_register_hw_with_fixup - register IDE interface
+ * ide_register_hw - register IDE interface
* @hw: hardware registers
+ * @fixup: fixup function
* @initializing: set while initializing built-in drivers
* @hwifp: pointer to returned hwif
- * @fixup: fixup function
*
* Register an IDE interface, specifying exactly the registers etc.
* Set init=1 iff calling before probes have taken place.
@@ -672,9 +696,8 @@ void ide_setup_ports ( hw_regs_t *hw,
* Returns -1 on error.
*/
-int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
- ide_hwif_t **hwifp,
- void(*fixup)(ide_hwif_t *hwif))
+int ide_register_hw(hw_regs_t *hw, void (*fixup)(ide_hwif_t *),
+ int initializing, ide_hwif_t **hwifp)
{
int index, retry = 1;
ide_hwif_t *hwif;
@@ -682,7 +705,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
do {
for (index = 0; index < MAX_HWIFS; ++index) {
hwif = &ide_hwifs[index];
- if (hwif->hw.io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
+ if (hwif->io_ports[IDE_DATA_OFFSET] == hw->io_ports[IDE_DATA_OFFSET])
goto found;
}
for (index = 0; index < MAX_HWIFS; ++index) {
@@ -690,7 +713,7 @@ int ide_register_hw_with_fixup(hw_regs_t *hw, int initializing,
if (hwif->hold)
continue;
if ((!hwif->present && !hwif->mate && !initializing) ||
- (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing))
+ (!hwif->io_ports[IDE_DATA_OFFSET] && initializing))
goto found;
}
for (index = 0; index < MAX_HWIFS; index++)
@@ -706,16 +729,18 @@ found:
}
if (hwif->present)
return -1;
- memcpy(&hwif->hw, hw, sizeof(*hw));
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+ memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
hwif->irq = hw->irq;
hwif->noprobe = 0;
+ hwif->fixup = fixup;
hwif->chipset = hw->chipset;
hwif->gendev.parent = hw->dev;
+ hwif->ack_intr = hw->ack_intr;
+
+ if (initializing == 0) {
+ u8 idx[4] = { index, 0xff, 0xff, 0xff };
- if (!initializing) {
- probe_hwif_init_with_fixup(hwif, fixup);
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
}
if (hwifp)
@@ -724,13 +749,6 @@ found:
return (initializing || hwif->present) ? index : -1;
}
-EXPORT_SYMBOL(ide_register_hw_with_fixup);
-
-int ide_register_hw(hw_regs_t *hw, int initializing, ide_hwif_t **hwifp)
-{
- return ide_register_hw_with_fixup(hw, initializing, hwifp, NULL);
-}
-
EXPORT_SYMBOL(ide_register_hw);
/*
@@ -1046,7 +1064,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
ide_init_hwif_ports(&hw, (unsigned long) args[0],
(unsigned long) args[1], NULL);
hw.irq = args[2];
- if (ide_register_hw(&hw, 0, NULL) == -1)
+ if (ide_register_hw(&hw, NULL, 0, NULL) == -1)
return -EIO;
return 0;
}
@@ -1397,6 +1415,9 @@ static int __init ide_setup(char *s)
"reset", "minus6", "ata66", "minus8", "minus9",
"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
"dtc2278", "umc8672", "ali14xx", NULL };
+
+ hw_regs_t hwregs;
+
hw = s[3] - '0';
hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3);
@@ -1506,9 +1527,9 @@ static int __init ide_setup(char *s)
case 2: /* base,ctl */
vals[2] = 0; /* default irq = probe for it */
case 3: /* base,ctl,irq */
- hwif->hw.irq = vals[2];
- ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ memset(&hwregs, 0, sizeof(hwregs));
+ ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq);
+ memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports));
hwif->irq = vals[2];
hwif->noprobe = 0;
hwif->chipset = ide_forced;
diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c
index 2f0ef9b4403..10311ecc674 100644
--- a/drivers/ide/legacy/ali14xx.c
+++ b/drivers/ide/legacy/ali14xx.c
@@ -102,6 +102,8 @@ static void outReg (u8 data, u8 reg)
outb_p(data, dataPort);
}
+static DEFINE_SPINLOCK(ali14xx_lock);
+
/*
* Set PIO mode for the specified drive.
* This function computes timing parameters
@@ -129,14 +131,14 @@ static void ali14xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
/* stuff timing parameters into controller registers */
driveNum = (HWIF(drive)->index << 1) + drive->select.b.unit;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&ali14xx_lock, flags);
outb_p(regOn, basePort);
outReg(param1, regTab[driveNum].reg1);
outReg(param2, regTab[driveNum].reg2);
outReg(param3, regTab[driveNum].reg3);
outReg(param4, regTab[driveNum].reg4);
outb_p(regOff, basePort);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&ali14xx_lock, flags);
}
/*
@@ -193,6 +195,7 @@ static int __init initRegisters (void) {
static int __init ali14xx_probe(void)
{
ide_hwif_t *hwif, *mate;
+ static u8 idx[4] = { 0, 1, 0xff, 0xff };
printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
basePort, regOn);
@@ -217,11 +220,7 @@ static int __init ali14xx_probe(void)
mate->mate = hwif;
mate->channel = 1;
- probe_hwif_init(hwif);
- probe_hwif_init(mate);
-
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
}
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 101aee1711c..4a0be251a05 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -212,8 +212,8 @@ fail_base2:
// xsurf_iops,
IRQ_AMIGA_PORTS);
}
-
- index = ide_register_hw(&hw, 1, &hwif);
+
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
if (index != -1) {
hwif->mmio = 1;
printk("ide%d: ", index);
diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c
index f1652125486..24a845d45bd 100644
--- a/drivers/ide/legacy/dtc2278.c
+++ b/drivers/ide/legacy/dtc2278.c
@@ -67,20 +67,24 @@ static void sub22 (char b, char c)
}
}
+static DEFINE_SPINLOCK(dtc2278_lock);
+
static void dtc2278_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
unsigned long flags;
if (pio >= 3) {
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&dtc2278_lock, flags);
/*
* This enables PIO mode4 (3?) on the first interface
*/
sub22(1,0xc3);
sub22(0,0xa0);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&dtc2278_lock, flags);
} else {
/* we don't know how to set it back again.. */
+ /* Actually we do - there is a data sheet available for the
+ Winbond but does anyone actually care */
}
/*
@@ -94,6 +98,7 @@ static int __init dtc2278_probe(void)
{
unsigned long flags;
ide_hwif_t *hwif, *mate;
+ static u8 idx[4] = { 0, 1, 0xff, 0xff };
hwif = &ide_hwifs[0];
mate = &ide_hwifs[1];
@@ -129,16 +134,13 @@ static int __init dtc2278_probe(void)
mate->serialized = 1;
mate->chipset = ide_dtc2278;
+ mate->pio_mask = ATA_PIO4;
mate->drives[0].no_unmask = 1;
mate->drives[1].no_unmask = 1;
mate->mate = hwif;
mate->channel = 1;
- probe_hwif_init(hwif);
- probe_hwif_init(mate);
-
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
}
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c
index f0829b83e97..7d7936f1b90 100644
--- a/drivers/ide/legacy/falconide.c
+++ b/drivers/ide/legacy/falconide.c
@@ -72,7 +72,7 @@ void __init falconide_init(void)
0, 0, NULL,
// falconide_iops,
IRQ_MFP_IDE);
- index = ide_register_hw(&hw, 1, NULL);
+ index = ide_register_hw(&hw, NULL, 1, NULL);
if (index != -1)
printk("ide%d: Falcon IDE interface\n", index);
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 0830a021bbb..53331ee1e95 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -165,7 +165,7 @@ found:
// &gayle_iops,
IRQ_AMIGA_PORTS);
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
if (index != -1) {
hwif->mmio = 1;
switch (i) {
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index 2e5a9cc5c0f..a4245d13f11 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -247,6 +247,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
}
}
+static DEFINE_SPINLOCK(ht6560b_lock);
+
/*
* Enable/Disable so called prefetch mode
*/
@@ -254,9 +256,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
{
unsigned long flags;
int t = HT_PREFETCH_MODE << 8;
-
- spin_lock_irqsave(&ide_lock, flags);
-
+
+ spin_lock_irqsave(&ht6560b_lock, flags);
+
/*
* Prefetch mode and unmask irq seems to conflict
*/
@@ -268,9 +270,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
drive->drive_data &= ~t; /* disable prefetch mode */
drive->no_unmask = 0;
}
-
- spin_unlock_irqrestore(&ide_lock, flags);
-
+
+ spin_unlock_irqrestore(&ht6560b_lock, flags);
+
#ifdef DEBUG
printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
#endif
@@ -287,16 +289,14 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
ht_set_prefetch(drive, pio & 1);
return;
}
-
+
timing = ht_pio2timings(drive, pio);
-
- spin_lock_irqsave(&ide_lock, flags);
-
+
+ spin_lock_irqsave(&ht6560b_lock, flags);
drive->drive_data &= 0xff00;
drive->drive_data |= timing;
-
- spin_unlock_irqrestore(&ide_lock, flags);
-
+ spin_unlock_irqrestore(&ht6560b_lock, flags);
+
#ifdef DEBUG
printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
#endif
@@ -311,6 +311,7 @@ MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
int __init ht6560b_init(void)
{
ide_hwif_t *hwif, *mate;
+ static u8 idx[4] = { 0, 1, 0xff, 0xff };
int t;
if (probe_ht6560b == 0)
@@ -359,11 +360,7 @@ int __init ht6560b_init(void)
mate->drives[0].drive_data = t;
mate->drives[1].drive_data = t;
- probe_hwif_init(hwif);
- probe_hwif_init(mate);
-
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c
index e8e360c2619..03715c05866 100644
--- a/drivers/ide/legacy/ide-cs.c
+++ b/drivers/ide/legacy/ide-cs.c
@@ -153,7 +153,7 @@ static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq
hw.irq = irq;
hw.chipset = ide_pci;
hw.dev = &handle->dev;
- return ide_register_hw_with_fixup(&hw, 0, NULL, ide_undecoded_slave);
+ return ide_register_hw(&hw, &ide_undecoded_slave, 0, NULL);
}
/*======================================================================
diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c
index b992b2b91fe..7bb79f53dac 100644
--- a/drivers/ide/legacy/ide_platform.c
+++ b/drivers/ide/legacy/ide_platform.c
@@ -33,39 +33,24 @@ static ide_hwif_t *__devinit plat_ide_locate_hwif(void __iomem *base,
int mmio)
{
unsigned long port = (unsigned long)base;
- ide_hwif_t *hwif;
- int index, i;
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = ide_hwifs + index;
- if (hwif->io_ports[IDE_DATA_OFFSET] == port)
- goto found;
- }
-
- for (index = 0; index < MAX_HWIFS; ++index) {
- hwif = ide_hwifs + index;
- if (hwif->io_ports[IDE_DATA_OFFSET] == 0)
- goto found;
- }
+ ide_hwif_t *hwif = ide_find_port(port);
+ int i;
- return NULL;
-
-found:
+ if (hwif == NULL)
+ goto out;
- hwif->hw.io_ports[IDE_DATA_OFFSET] = port;
+ hwif->io_ports[IDE_DATA_OFFSET] = port;
port += (1 << pdata->ioport_shift);
for (i = IDE_ERROR_OFFSET; i <= IDE_STATUS_OFFSET;
i++, port += (1 << pdata->ioport_shift))
- hwif->hw.io_ports[i] = port;
+ hwif->io_ports[i] = port;
- hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
+ hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
- hwif->hw.irq = hwif->irq = irq;
+ hwif->irq = irq;
- hwif->hw.dma = NO_DMA;
- hwif->chipset = hwif->hw.chipset = ide_generic;
+ hwif->chipset = ide_generic;
if (mmio) {
hwif->mmio = 1;
@@ -73,8 +58,8 @@ found:
}
hwif_prop.hwif = hwif;
- hwif_prop.index = index;
-
+ hwif_prop.index = hwif->index;
+out:
return hwif;
}
@@ -83,6 +68,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
struct resource *res_base, *res_alt, *res_irq;
ide_hwif_t *hwif;
struct pata_platform_info *pdata;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
int ret = 0;
int mmio = 0;
@@ -130,10 +116,11 @@ static int __devinit plat_ide_probe(struct platform_device *pdev)
hwif->gendev.parent = &pdev->dev;
hwif->noprobe = 0;
- probe_hwif_init(hwif);
+ idx[0] = hwif->index;
+
+ ide_device_add(idx);
platform_set_drvdata(pdev, hwif);
- ide_proc_register_port(hwif);
return 0;
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index b557c45a5a9..e87cd2f1643 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -93,21 +93,21 @@ void macide_init(void)
0, 0, macide_ack_intr,
// quadra_ide_iops,
IRQ_NUBUS_F);
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
break;
case MAC_IDE_PB:
ide_setup_ports(&hw, IDE_BASE, macide_offsets,
0, 0, macide_ack_intr,
// macide_pb_iops,
IRQ_NUBUS_C);
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
break;
case MAC_IDE_BABOON:
ide_setup_ports(&hw, BABOON_BASE, macide_offsets,
0, 0, NULL,
// macide_baboon_iops,
IRQ_BABOON_1);
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
if (index == -1) break;
if (macintosh_config->ident == MAC_MODEL_PB190) {
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index e628a983ce3..a73db1bd482 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -89,9 +89,8 @@ void q40_ide_setup_ports ( hw_regs_t *hw,
else
hw->io_ports[i] = Q40_ISA_IO_B(base + offsets[i]);
}
-
+
hw->irq = irq;
- hw->dma = NO_DMA;
hw->ack_intr = ack_intr;
/*
* hw->iops = iops;
@@ -102,7 +101,7 @@ void q40_ide_setup_ports ( hw_regs_t *hw,
/*
* the static array is needed to have the name reported in /proc/ioports,
- * hwif->name unfortunately isnt available yet
+ * hwif->name unfortunately isn't available yet
*/
static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={
"ide0", "ide1"
@@ -142,7 +141,7 @@ void q40ide_init(void)
0, NULL,
// m68kide_iops,
q40ide_default_irq(pcide_bases[i]));
- index = ide_register_hw(&hw, 1, &hwif);
+ index = ide_register_hw(&hw, NULL, 1, &hwif);
// **FIXME**
if (index != -1)
hwif->mmio = 1;
diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c
index 0c81d2d0b94..912e73853fa 100644
--- a/drivers/ide/legacy/qd65xx.c
+++ b/drivers/ide/legacy/qd65xx.c
@@ -89,26 +89,6 @@
static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
-static void qd_write_reg (u8 content, unsigned long reg)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ide_lock, flags);
- outb(content,reg);
- spin_unlock_irqrestore(&ide_lock, flags);
-}
-
-static u8 __init qd_read_reg (unsigned long reg)
-{
- unsigned long flags;
- u8 read;
-
- spin_lock_irqsave(&ide_lock, flags);
- read = inb(reg);
- spin_unlock_irqrestore(&ide_lock, flags);
- return read;
-}
-
/*
* qd_select:
*
@@ -121,7 +101,7 @@ static void qd_select (ide_drive_t *drive)
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
- qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+ outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
}
/*
@@ -284,7 +264,7 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
}
if (!HWIF(drive)->channel && drive->media != ide_disk) {
- qd_write_reg(0x5f, QD_CONTROL_PORT);
+ outb(0x5f, QD_CONTROL_PORT);
printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO "
"and post-write buffer on %s.\n",
drive->name, HWIF(drive)->name);
@@ -301,16 +281,15 @@ static void qd6580_set_pio_mode(ide_drive_t *drive, const u8 pio)
static int __init qd_testreg(int port)
{
- u8 savereg;
- u8 readreg;
unsigned long flags;
+ u8 savereg, readreg;
- spin_lock_irqsave(&ide_lock, flags);
+ local_irq_save(flags);
savereg = inb_p(port);
outb_p(QD_TESTVAL, port); /* safe value */
readreg = inb_p(port);
outb(savereg, port);
- spin_unlock_irqrestore(&ide_lock, flags);
+ local_irq_restore(flags);
if (savereg == QD_TESTVAL) {
printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
@@ -364,13 +343,13 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
if (set_pio_mode == (void *)qd6500_set_pio_mode) {
// will do it for both
- qd_write_reg(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ outb(QD6500_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
} else if (set_pio_mode == (void *)qd6580_set_pio_mode) {
if (QD_CONTROL(hwif) & QD_CONTR_SEC_DISABLED) {
- qd_write_reg(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
- qd_write_reg(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
+ outb(QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ outb(QD6580_DEF_DATA2, QD_TIMREG(&hwif->drives[1]));
} else {
- qd_write_reg(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
+ outb(hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA, QD_TIMREG(&hwif->drives[0]));
}
} else {
printk(KERN_WARNING "Unknown qd65xx tuning fonction !\n");
@@ -389,10 +368,11 @@ static void __exit qd_unsetup(ide_hwif_t *hwif)
static int __init qd_probe(int base)
{
ide_hwif_t *hwif;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
u8 config;
u8 unit;
- config = qd_read_reg(QD_CONFIG_PORT);
+ config = inb(QD_CONFIG_PORT);
if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) )
return 1;
@@ -419,9 +399,9 @@ static int __init qd_probe(int base)
hwif->set_pio_mode = &qd6500_set_pio_mode;
- probe_hwif_init(hwif);
+ idx[0] = unit;
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
return 1;
}
@@ -436,7 +416,7 @@ static int __init qd_probe(int base)
/* qd6580 found */
- control = qd_read_reg(QD_CONTROL_PORT);
+ control = inb(QD_CONTROL_PORT);
printk(KERN_NOTICE "qd6580 at %#x\n", base);
printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
@@ -453,11 +433,11 @@ static int __init qd_probe(int base)
hwif->set_pio_mode = &qd6580_set_pio_mode;
- probe_hwif_init(hwif);
+ idx[0] = unit;
- qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+ ide_device_add(idx);
- ide_proc_register_port(hwif);
+ outb(QD_DEF_CONTR, QD_CONTROL_PORT);
return 1;
} else {
@@ -474,19 +454,17 @@ static int __init qd_probe(int base)
hwif->set_pio_mode = &qd6580_set_pio_mode;
- probe_hwif_init(hwif);
-
qd_setup(mate, base, config | (control << 8),
QD6580_DEF_DATA2, QD6580_DEF_DATA2);
mate->set_pio_mode = &qd6580_set_pio_mode;
- probe_hwif_init(mate);
+ idx[0] = 0;
+ idx[1] = 1;
- qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+ ide_device_add(idx);
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ outb(QD_DEF_CONTR, QD_CONTROL_PORT);
return 0; /* no other qd65xx possible */
}
diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c
index 1151c92dd53..79577b91687 100644
--- a/drivers/ide/legacy/umc8672.c
+++ b/drivers/ide/legacy/umc8672.c
@@ -124,8 +124,9 @@ static void umc_set_pio_mode(ide_drive_t *drive, const u8 pio)
static int __init umc8672_probe(void)
{
- unsigned long flags;
ide_hwif_t *hwif, *mate;
+ unsigned long flags;
+ static u8 idx[4] = { 0, 1, 0xff, 0xff };
if (!request_region(0x108, 2, "umc8672")) {
printk(KERN_ERR "umc8672: ports 0x108-0x109 already in use.\n");
@@ -158,11 +159,7 @@ static int __init umc8672_probe(void)
mate->mate = hwif;
mate->channel = 1;
- probe_hwif_init(hwif);
- probe_hwif_init(mate);
-
- ide_proc_register_port(hwif);
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
}
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index 2f322d7e881..a4ce3ba15d6 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -276,8 +276,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (iswrite) {
if(!put_source_flags(ahwif->tx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
+ (void*) sg_virt(sg),
tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
__FUNCTION__, __LINE__);
@@ -285,8 +284,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
} else
{
if(!put_dest_flags(ahwif->rx_chan,
- (void*)(page_address(sg->page)
- + sg->offset),
+ (void*) sg_virt(sg),
tc, flags)) {
printk(KERN_ERR "%s failed %d\n",
__FUNCTION__, __LINE__);
@@ -601,8 +599,9 @@ static int au_ide_probe(struct device *dev)
_auide_hwif *ahwif = &auide_hwif;
ide_hwif_t *hwif;
struct resource *res;
- hw_regs_t *hw;
int ret = 0;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)
char *mode = "MWDMA2";
@@ -644,12 +643,12 @@ static int au_ide_probe(struct device *dev)
/* FIXME: This might possibly break PCMCIA IDE devices */
hwif = &ide_hwifs[pdev->id];
- hw = &hwif->hw;
- hwif->irq = hw->irq = ahwif->irq;
+ hwif->irq = ahwif->irq;
hwif->chipset = ide_au1xxx;
- auide_setup_ports(hw, ahwif);
- memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports));
+ memset(&hw, 0, sizeof(hw));
+ auide_setup_ports(&hw, ahwif);
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
@@ -706,8 +705,10 @@ static int au_ide_probe(struct device *dev)
hwif->config_data = 0; /* no chipset-specific code */
hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */
+ hwif->drives[1].autotune = 1;
#endif
- hwif->drives[0].no_io_32bit = 1;
+ hwif->drives[0].no_io_32bit = 1;
+ hwif->drives[1].no_io_32bit = 1;
auide_hwif.hwif = hwif;
hwif->hwif_data = &auide_hwif;
@@ -717,9 +718,9 @@ static int au_ide_probe(struct device *dev)
dbdma_init_done = 1;
#endif
- probe_hwif_init(hwif);
+ idx[0] = hwif->index;
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
dev_set_drvdata(dev, hwif);
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index c2e29571b00..521edd41b57 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -71,6 +71,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
u8 __iomem *base;
phys_t offset, size;
int i;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
if (!SIBYTE_HAVE_IDE)
return -ENODEV;
@@ -119,18 +120,15 @@ static int __devinit swarm_ide_probe(struct device *dev)
hwif->noprobe = 0;
for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
- hwif->hw.io_ports[i] =
+ hwif->io_ports[i] =
(unsigned long)(base + ((0x1f0 + i) << 5));
- hwif->hw.io_ports[IDE_CONTROL_OFFSET] =
+ hwif->io_ports[IDE_CONTROL_OFFSET] =
(unsigned long)(base + (0x3f6 << 5));
- hwif->hw.irq = K_INT_GB_IDE;
+ hwif->irq = K_INT_GB_IDE;
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
- hwif->irq = hwif->hw.irq;
+ idx[0] = hwif->index;
- probe_hwif_init(hwif);
-
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
dev_set_drvdata(dev, hwif);
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index b3dc12a70d5..19ec421f7b9 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/aec62xx.c Version 0.26 Sep 1, 2007
+ * linux/drivers/ide/pci/aec62xx.c Version 0.27 Sep 16, 2007
*
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
@@ -141,19 +141,6 @@ static void aec_set_pio_mode(ide_drive_t *drive, const u8 pio)
drive->hwif->set_dma_mode(drive, pio + XFER_PIO_0);
}
-static void aec62xx_dma_lost_irq (ide_drive_t *drive)
-{
- switch (HWIF(drive)->pci_dev->device) {
- case PCI_DEVICE_ID_ARTOP_ATP860:
- case PCI_DEVICE_ID_ARTOP_ATP860R:
- case PCI_DEVICE_ID_ARTOP_ATP865:
- case PCI_DEVICE_ID_ARTOP_ATP865R:
- printk(" AEC62XX time out ");
- default:
- break;
- }
-}
-
static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const char *name)
{
int bus_speed = system_bus_clock();
@@ -195,8 +182,6 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
if (hwif->dma_base == 0)
return;
- hwif->dma_lost_irq = &aec62xx_dma_lost_irq;
-
if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
return;
@@ -209,7 +194,7 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
}
}
-static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
+static const struct ide_port_info aec62xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "AEC6210",
.init_chipset = init_chipset_aec62xx,
@@ -268,12 +253,12 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = {
* finds a device matching our IDE device tables.
*
* NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
- * chips, pass a local copy of 'struct pci_device_id' down the call chain.
+ * chips, pass a local copy of 'struct ide_port_info' down the call chain.
*/
-
+
static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d;
+ struct ide_port_info d;
u8 idx = id->driver_data;
d = aec62xx_chipsets[idx];
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 8ee2b48d105..a607dd31a64 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/alim15x3.c Version 0.27 Aug 27 2007
+ * linux/drivers/ide/pci/alim15x3.c Version 0.29 Sep 16 2007
*
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
@@ -492,6 +492,13 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
* clear bit 7
*/
pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F);
+ /*
+ * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
+ */
+ if (m5229_revision >= 0x20 && isa_dev) {
+ pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
+ chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
+ }
goto out;
}
@@ -537,7 +544,30 @@ static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const c
pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
}
}
+
out:
+ /*
+ * CD_ROM DMA on (m5229, 0x53, bit0)
+ * Enable this bit even if we want to use PIO.
+ * PIO FIFO off (m5229, 0x53, bit1)
+ * The hardware will use 0x54h and 0x55h to control PIO FIFO.
+ * (Not on later devices it seems)
+ *
+ * 0x53 changes meaning on later revs - we must no touch
+ * bit 1 on them. Need to check if 0x20 is the right break.
+ */
+ if (m5229_revision >= 0x20) {
+ pci_read_config_byte(dev, 0x53, &tmpbyte);
+
+ if (m5229_revision <= 0x20)
+ tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+ else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
+ tmpbyte |= 0x03;
+ else
+ tmpbyte |= 0x01;
+
+ pci_write_config_byte(dev, 0x53, tmpbyte);
+ }
pci_dev_put(north);
pci_dev_put(isa_dev);
local_irq_restore(flags);
@@ -616,36 +646,8 @@ static u8 __devinit ata66_ali15x3(ide_hwif_t *hwif)
if ((tmpbyte & (1 << hwif->channel)) == 0)
cbl = ATA_CBL_PATA80;
}
- } else {
- /*
- * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
- */
- pci_read_config_byte(isa_dev, 0x5e, &tmpbyte);
- chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0;
}
- /*
- * CD_ROM DMA on (m5229, 0x53, bit0)
- * Enable this bit even if we want to use PIO
- * PIO FIFO off (m5229, 0x53, bit1)
- * The hardware will use 0x54h and 0x55h to control PIO FIFO
- * (Not on later devices it seems)
- *
- * 0x53 changes meaning on later revs - we must no touch
- * bit 1 on them. Need to check if 0x20 is the right break
- */
-
- pci_read_config_byte(dev, 0x53, &tmpbyte);
-
- if(m5229_revision <= 0x20)
- tmpbyte = (tmpbyte & (~0x02)) | 0x01;
- else if (m5229_revision == 0xc7 || m5229_revision == 0xc8)
- tmpbyte |= 0x03;
- else
- tmpbyte |= 0x01;
-
- pci_write_config_byte(dev, 0x53, tmpbyte);
-
local_irq_restore(flags);
return cbl;
@@ -664,31 +666,9 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif)
hwif->set_dma_mode = &ali_set_dma_mode;
hwif->udma_filter = &ali_udma_filter;
- /* don't use LBA48 DMA on ALi devices before rev 0xC5 */
- if (m5229_revision <= 0xC4)
- hwif->host_flags |= IDE_HFLAG_NO_LBA48_DMA;
-
if (hwif->dma_base == 0)
return;
- /*
- * check in ->init_dma guarantees m5229_revision >= 0x20 here
- */
-
- if (m5229_revision == 0x20)
- hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
-
- if (m5229_revision <= 0x20)
- hwif->ultra_mask = 0x00; /* no udma */
- else if (m5229_revision < 0xC2)
- hwif->ultra_mask = ATA_UDMA2;
- else if (m5229_revision == 0xC2 || m5229_revision == 0xC3)
- hwif->ultra_mask = ATA_UDMA4;
- else if (m5229_revision == 0xC4)
- hwif->ultra_mask = ATA_UDMA5;
- else
- hwif->ultra_mask = ATA_UDMA6;
-
hwif->dma_setup = &ali15x3_dma_setup;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -766,7 +746,7 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
ide_setup_dma(hwif, dmabase, 8);
}
-static ide_pci_device_t ali15x3_chipset __devinitdata = {
+static const struct ide_port_info ali15x3_chipset __devinitdata = {
.name = "ALI15X3",
.init_chipset = init_chipset_ali15x3,
.init_hwif = init_hwif_ali15x3,
@@ -792,15 +772,34 @@ static int __devinit alim15x3_init_one(struct pci_dev *dev, const struct pci_dev
{ },
};
- ide_pci_device_t *d = &ali15x3_chipset;
+ struct ide_port_info d = ali15x3_chipset;
+ u8 rev = dev->revision;
if (pci_dev_present(ati_rs100))
printk(KERN_WARNING "alim15x3: ATI Radeon IGP Northbridge is not yet fully tested.\n");
+ /* don't use LBA48 DMA on ALi devices before rev 0xC5 */
+ if (rev <= 0xC4)
+ d.host_flags |= IDE_HFLAG_NO_LBA48_DMA;
+
+ if (rev >= 0x20) {
+ if (rev == 0x20)
+ d.host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
+
+ if (rev < 0xC2)
+ d.udma_mask = ATA_UDMA2;
+ else if (rev == 0xC2 || rev == 0xC3)
+ d.udma_mask = ATA_UDMA4;
+ else if (rev == 0xC4)
+ d.udma_mask = ATA_UDMA5;
+ else
+ d.udma_mask = ATA_UDMA6;
+ }
+
#if defined(CONFIG_SPARC64)
- d->init_hwif = init_hwif_common_ali15x3;
+ d.init_hwif = init_hwif_common_ali15x3;
#endif /* CONFIG_SPARC64 */
- return ide_setup_pci_device(dev, d);
+ return ide_setup_pci_device(dev, &d);
}
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index 7cafefbf6c1..8d4125ec252 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -77,7 +77,7 @@ static struct amd_ide_chip {
};
static struct amd_ide_chip *amd_config;
-static ide_pci_device_t *amd_chipset;
+static const struct ide_port_info *amd_chipset;
static unsigned int amd_80w;
static unsigned int amd_clock;
@@ -242,19 +242,12 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch
static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
{
- int i;
-
if (hwif->irq == 0) /* 0 is bogus but will do for now */
hwif->irq = pci_get_legacy_ide_irq(hwif->pci_dev, hwif->channel);
hwif->set_pio_mode = &amd_set_pio_mode;
hwif->set_dma_mode = &amd_set_drive;
- for (i = 0; i < 2; i++) {
- hwif->drives[i].io_32bit = 1;
- hwif->drives[i].unmask = 1;
- }
-
if (!hwif->dma_base)
return;
@@ -270,16 +263,21 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
}
}
+#define IDE_HFLAGS_AMD \
+ (IDE_HFLAG_PIO_NO_BLACKLIST | \
+ IDE_HFLAG_PIO_NO_DOWNGRADE | \
+ IDE_HFLAG_POST_SET_MODE | \
+ IDE_HFLAG_IO_32BIT | \
+ IDE_HFLAG_UNMASK_IRQS | \
+ IDE_HFLAG_BOOTABLE)
+
#define DECLARE_AMD_DEV(name_str) \
{ \
.name = name_str, \
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | \
- IDE_HFLAG_PIO_NO_DOWNGRADE | \
- IDE_HFLAG_POST_SET_MODE | \
- IDE_HFLAG_BOOTABLE, \
+ .host_flags = IDE_HFLAGS_AMD, \
.pio_mask = ATA_PIO5, \
.swdma_mask = ATA_SWDMA2, \
.mwdma_mask = ATA_MWDMA2, \
@@ -291,16 +289,13 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif)
.init_chipset = init_chipset_amd74xx, \
.init_hwif = init_hwif_amd74xx, \
.enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | \
- IDE_HFLAG_PIO_NO_DOWNGRADE | \
- IDE_HFLAG_POST_SET_MODE | \
- IDE_HFLAG_BOOTABLE, \
+ .host_flags = IDE_HFLAGS_AMD, \
.pio_mask = ATA_PIO5, \
.swdma_mask = ATA_SWDMA2, \
.mwdma_mask = ATA_MWDMA2, \
}
-static ide_pci_device_t amd74xx_chipsets[] __devinitdata = {
+static const struct ide_port_info amd74xx_chipsets[] __devinitdata = {
/* 0 */ DECLARE_AMD_DEV("AMD7401"),
/* 1 */ DECLARE_AMD_DEV("AMD7409"),
/* 2 */ DECLARE_AMD_DEV("AMD7411"),
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 30784305307..ef8e0164ef7 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -189,8 +189,7 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
hwif->dma_host_off = &atiixp_dma_host_off;
}
-
-static ide_pci_device_t atiixp_pci_info[] __devinitdata = {
+static const struct ide_port_info atiixp_pci_info[] __devinitdata = {
{ /* 0 */
.name = "ATIIXP",
.init_hwif = init_hwif_atiixp,
diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c
index f369645e4d1..4aa48104e0c 100644
--- a/drivers/ide/pci/cmd640.c
+++ b/drivers/ide/pci/cmd640.c
@@ -185,6 +185,8 @@ static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */
#endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
+static DEFINE_SPINLOCK(cmd640_lock);
+
/*
* These are initialized to point at the devices we control
*/
@@ -258,12 +260,12 @@ static u8 get_cmd640_reg_vlb (u16 reg)
static u8 get_cmd640_reg(u16 reg)
{
- u8 b;
unsigned long flags;
+ u8 b;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
b = __get_cmd640_reg(reg);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return b;
}
@@ -271,9 +273,9 @@ static void put_cmd640_reg(u16 reg, u8 val)
{
unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
__put_cmd640_reg(reg,val);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
}
static int __init match_pci_cmd640_device (void)
@@ -351,7 +353,7 @@ static int __init secondary_port_responding (void)
{
unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
outb_p(0x0a, 0x170 + IDE_SELECT_OFFSET); /* select drive0 */
udelay(100);
@@ -359,11 +361,11 @@ static int __init secondary_port_responding (void)
outb_p(0x1a, 0x170 + IDE_SELECT_OFFSET); /* select drive1 */
udelay(100);
if ((inb_p(0x170 + IDE_SELECT_OFFSET) & 0x1f) != 0x1a) {
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 0; /* nothing responded */
}
}
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 1; /* success */
}
@@ -440,11 +442,11 @@ static void __init setup_device_ptrs (void)
static void set_prefetch_mode (unsigned int index, int mode)
{
ide_drive_t *drive = cmd_drives[index];
+ unsigned long flags;
int reg = prefetch_regs[index];
u8 b;
- unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
b = __get_cmd640_reg(reg);
if (mode) { /* want prefetch on? */
#if CMD640_PREFETCH_MASKS
@@ -460,7 +462,7 @@ static void set_prefetch_mode (unsigned int index, int mode)
b |= prefetch_masks[index]; /* disable prefetch */
}
__put_cmd640_reg(reg, b);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
}
/*
@@ -561,7 +563,7 @@ static void program_drive_counts (unsigned int index)
/*
* Now that everything is ready, program the new timings
*/
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
/*
* Program the address_setup clocks into ARTTIM reg,
* and then the active/recovery counts into the DRWTIM reg
@@ -570,7 +572,7 @@ static void program_drive_counts (unsigned int index)
setup_count |= __get_cmd640_reg(arttim_regs[index]) & 0x3f;
__put_cmd640_reg(arttim_regs[index], setup_count);
__put_cmd640_reg(drwtim_regs[index], pack_nibbles(active_count, recovery_count));
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
}
/*
@@ -670,20 +672,20 @@ static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
static int pci_conf1(void)
{
- u32 tmp;
unsigned long flags;
+ u32 tmp;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
outb(0x01, 0xCFB);
tmp = inl(0xCF8);
outl(0x80000000, 0xCF8);
if (inl(0xCF8) == 0x80000000) {
outl(tmp, 0xCF8);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 1;
}
outl(tmp, 0xCF8);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 0;
}
@@ -691,15 +693,15 @@ static int pci_conf2(void)
{
unsigned long flags;
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&cmd640_lock, flags);
outb(0x00, 0xCFB);
outb(0x00, 0xCF8);
outb(0x00, 0xCFA);
if (inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00) {
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 1;
}
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&cmd640_lock, flags);
return 0;
}
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index adee2ef6fd7..ea0143ef5fe 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -535,7 +535,6 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
hwif->ide_dma_test_irq = &cmd648_ide_dma_test_irq;
break;
case PCI_DEVICE_ID_CMD_646:
- hwif->chipset = ide_cmd646;
if (dev->revision == 0x01) {
hwif->ide_dma_end = &cmd646_1_ide_dma_end;
break;
@@ -549,7 +548,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif)
}
}
-static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
+static const struct ide_port_info cmd64x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "CMD643",
.init_chipset = init_chipset_cmd64x,
@@ -573,6 +572,7 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
.init_chipset = init_chipset_cmd64x,
.init_hwif = init_hwif_cmd64x,
.enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+ .chipset = ide_cmd646,
.host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
.mwdma_mask = ATA_MWDMA2,
@@ -591,7 +591,7 @@ static ide_pci_device_t cmd64x_chipsets[] __devinitdata = {
static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d;
+ struct ide_port_info d;
u8 idx = id->driver_data;
d = cmd64x_chipsets[idx];
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index aa98e817d38..0466462fd21 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -141,7 +141,7 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif)
.pio_mask = ATA_PIO4, \
}
-static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
+static const struct ide_port_info cyrix_chipsets[] __devinitdata = {
/* 0 */ DECLARE_CS_DEV("Cyrix 5510"),
/* 1 */ DECLARE_CS_DEV("Cyrix 5520")
};
@@ -154,9 +154,8 @@ static ide_pci_device_t cyrix_chipsets[] __devinitdata = {
static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_hwif_t *hwif = NULL, *mate = NULL;
- ata_index_t index;
- ide_pci_device_t *d = &cyrix_chipsets[id->driver_data];
+ const struct ide_port_info *d = &cyrix_chipsets[id->driver_data];
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
ide_setup_pci_noise(dev, d);
@@ -172,29 +171,14 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic
return -ENODEV;
}
- index.all = 0xf0f0;
-
/*
* Now the chipset is configured we can let the core
* do all the device setup for us
*/
- ide_pci_setup_ports(dev, d, 14, &index);
-
- if ((index.b.low & 0xf0) != 0xf0)
- hwif = &ide_hwifs[index.b.low];
- if ((index.b.high & 0xf0) != 0xf0)
- mate = &ide_hwifs[index.b.high];
-
- if (hwif)
- probe_hwif_init(hwif);
- if (mate)
- probe_hwif_init(mate);
+ ide_pci_setup_ports(dev, d, 14, &idx[0]);
- if (hwif)
- ide_proc_register_port(hwif);
- if (mate)
- ide_proc_register_port(mate);
+ ide_device_add(idx);
return 0;
}
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index ba0c6eba024..599408952bd 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/cs5530.c Version 0.76 Aug 3 2007
+ * linux/drivers/ide/pci/cs5530.c Version 0.77 Sep 24 2007
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2000 Mark Lord <mlord@pobox.com>
@@ -146,7 +146,6 @@ static void cs5530_set_dma_mode(ide_drive_t *drive, const u8 mode)
static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name)
{
struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
- unsigned long flags;
if (pci_resource_start(dev, 4) == 0)
return -EFAULT;
@@ -171,9 +170,6 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
goto out;
}
- spin_lock_irqsave(&ide_lock, flags);
- /* all CPUs (there should only be one CPU with this chipset) */
-
/*
* Enable BusMaster and MemoryWriteAndInvalidate for the cs5530:
* --> OR 0x14 into 16-bit PCI COMMAND reg of function 0 of the cs5530
@@ -224,8 +220,6 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch
pci_write_config_byte(master_0, 0x42, 0x00);
pci_write_config_byte(master_0, 0x43, 0xc1);
- spin_unlock_irqrestore(&ide_lock, flags);
-
out:
pci_dev_put(master_0);
pci_dev_put(cs5530_0);
@@ -261,7 +255,7 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
hwif->udma_filter = cs5530_udma_filter;
}
-static ide_pci_device_t cs5530_chipset __devinitdata = {
+static const struct ide_port_info cs5530_chipset __devinitdata = {
.name = "CS5530",
.init_chipset = init_chipset_cs5530,
.init_hwif = init_hwif_cs5530,
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 5ac82ffa5c0..9094916e378 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -186,7 +186,7 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif)
hwif->cbl = cs5535_cable_detect(hwif->pci_dev);
}
-static ide_pci_device_t cs5535_chipset __devinitdata = {
+static const struct ide_port_info cs5535_chipset __devinitdata = {
.name = "CS5535",
.init_hwif = init_hwif_cs5535,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE |
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index efc20bd97fd..3ef4fc10fe2 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -428,7 +428,6 @@ static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const c
*/
static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
{
- hwif->chipset = ide_cy82c693;
hwif->set_pio_mode = &cy82c693_set_pio_mode;
if (hwif->dma_base == 0)
@@ -449,11 +448,12 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
}
}
-static ide_pci_device_t cy82c693_chipset __devinitdata = {
+static const struct ide_port_info cy82c693_chipset __devinitdata = {
.name = "CY82C693",
.init_chipset = init_chipset_cy82c693,
.init_iops = init_iops_cy82c693,
.init_hwif = init_hwif_cy82c693,
+ .chipset = ide_cy82c693,
.host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO4,
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 46f4a888c03..83829081640 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -80,7 +80,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
hw.irq = dev->irq;
hw.chipset = ide_pci; /* this enables IRQ sharing */
- rc = ide_register_hw_with_fixup(&hw, 0, &hwif, ide_undecoded_slave);
+ rc = ide_register_hw(&hw, &ide_undecoded_slave, 0, &hwif);
if (rc < 0) {
printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
pci_disable_device(dev);
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c
index 51165832e7f..f44d70852c3 100644
--- a/drivers/ide/pci/generic.c
+++ b/drivers/ide/pci/generic.c
@@ -54,37 +54,24 @@ __setup("all-generic-ide", ide_generic_all_on);
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
-static void __devinit init_hwif_generic (ide_hwif_t *hwif)
-{
- switch(hwif->pci_dev->device) {
- case PCI_DEVICE_ID_UMC_UM8673F:
- case PCI_DEVICE_ID_UMC_UM8886A:
- case PCI_DEVICE_ID_UMC_UM8886BF:
- hwif->irq = hwif->channel ? 15 : 14;
- break;
- default:
- break;
- }
-}
+#define IDE_HFLAGS_UMC (IDE_HFLAG_NO_DMA | IDE_HFLAG_FORCE_LEGACY_IRQS)
-#define DECLARE_GENERIC_PCI_DEV(name_str, dma_setting) \
+#define DECLARE_GENERIC_PCI_DEV(name_str, extra_flags) \
{ \
.name = name_str, \
- .init_hwif = init_hwif_generic, \
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \
- dma_setting | \
+ extra_flags | \
IDE_HFLAG_BOOTABLE, \
.swdma_mask = ATA_SWDMA2, \
.mwdma_mask = ATA_MWDMA2, \
.udma_mask = ATA_UDMA6, \
}
-static ide_pci_device_t generic_chipsets[] __devinitdata = {
+static const struct ide_port_info generic_chipsets[] __devinitdata = {
/* 0 */ DECLARE_GENERIC_PCI_DEV("Unknown", 0),
{ /* 1 */
.name = "NS87410",
- .init_hwif = init_hwif_generic,
.enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}},
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_BOOTABLE,
@@ -95,16 +82,15 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
/* 2 */ DECLARE_GENERIC_PCI_DEV("SAMURAI", 0),
/* 3 */ DECLARE_GENERIC_PCI_DEV("HT6565", 0),
- /* 4 */ DECLARE_GENERIC_PCI_DEV("UM8673F", IDE_HFLAG_NO_DMA),
- /* 5 */ DECLARE_GENERIC_PCI_DEV("UM8886A", IDE_HFLAG_NO_DMA),
- /* 6 */ DECLARE_GENERIC_PCI_DEV("UM8886BF", IDE_HFLAG_NO_DMA),
+ /* 4 */ DECLARE_GENERIC_PCI_DEV("UM8673F", IDE_HFLAGS_UMC),
+ /* 5 */ DECLARE_GENERIC_PCI_DEV("UM8886A", IDE_HFLAGS_UMC),
+ /* 6 */ DECLARE_GENERIC_PCI_DEV("UM8886BF", IDE_HFLAGS_UMC),
/* 7 */ DECLARE_GENERIC_PCI_DEV("HINT_IDE", 0),
/* 8 */ DECLARE_GENERIC_PCI_DEV("VIA_IDE", IDE_HFLAG_NO_AUTODMA),
/* 9 */ DECLARE_GENERIC_PCI_DEV("OPTI621V", IDE_HFLAG_NO_AUTODMA),
{ /* 10 */
.name = "VIA8237SATA",
- .init_hwif = init_hwif_generic,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD,
.swdma_mask = ATA_SWDMA2,
@@ -118,7 +104,6 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
{ /* 14 */
.name = "Revolution",
- .init_hwif = init_hwif_generic,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_OFF_BOARD,
.swdma_mask = ATA_SWDMA2,
@@ -138,7 +123,7 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = {
static int __devinit generic_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &generic_chipsets[id->driver_data];
+ const struct ide_port_info *d = &generic_chipsets[id->driver_data];
int ret = -ENODEV;
/* Don't use the generic entry unless instructed to do so */
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index 67af1a7dde3..ae6307fae4f 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -129,7 +129,7 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
hwif->set_dma_mode = &hpt34x_set_mode;
}
-static ide_pci_device_t hpt34x_chipsets[] __devinitdata = {
+static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT343",
.init_chipset = init_chipset_hpt34x,
@@ -158,7 +158,7 @@ static ide_pci_device_t hpt34x_chipsets[] __devinitdata = {
static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d;
+ const struct ide_port_info *d;
u16 pcicmd = 0;
pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 18f5b7ddaee..612b795241b 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -1425,7 +1425,7 @@ static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2)
return 0;
}
-static ide_pci_device_t hpt366_chipsets[] __devinitdata = {
+static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
{ /* 0 */
.name = "HPT36x",
.init_chipset = init_chipset_hpt366,
@@ -1510,7 +1510,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
{
struct hpt_info *info = NULL;
struct pci_dev *dev2 = NULL;
- ide_pci_device_t d;
+ struct ide_port_info d;
u8 idx = id->driver_data;
u8 rev = dev->revision;
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index dfbe605120c..90b52ed37bf 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -193,7 +193,7 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif)
.udma_mask = ATA_UDMA6, \
}
-static ide_pci_device_t it8213_chipsets[] __devinitdata = {
+static const struct ide_port_info it8213_chipsets[] __devinitdata = {
/* 0 */ DECLARE_ITE_DEV("IT8213"),
};
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index ec45b724720..5c997543531 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -95,7 +95,7 @@ struct it821x_dev
/*
* We allow users to force the card into non raid mode without
- * flashing the alternative BIOS. This is also neccessary right now
+ * flashing the alternative BIOS. This is also necessary right now
* for embedded platforms that cannot run a PC BIOS but are using this
* device.
*/
@@ -564,7 +564,7 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif)
/*
* Not in the docs but according to the reference driver
- * this is neccessary.
+ * this is necessary.
*/
pci_read_config_byte(hwif->pci_dev, 0x08, &conf);
@@ -638,7 +638,7 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha
.pio_mask = ATA_PIO4, \
}
-static ide_pci_device_t it821x_chipsets[] __devinitdata = {
+static const struct ide_port_info it821x_chipsets[] __devinitdata = {
/* 0 */ DECLARE_ITE_DEV("IT8212"),
};
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index 2eeff670d9a..bdf64d99770 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -118,7 +118,7 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif)
hwif->cbl = ata66_jmicron(hwif);
}
-static ide_pci_device_t jmicron_chipset __devinitdata = {
+static const struct ide_port_info jmicron_chipset __devinitdata = {
.name = "JMB",
.init_hwif = init_hwif_jmicron,
.host_flags = IDE_HFLAG_BOOTABLE,
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index d21b5892382..d4df4642dbb 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -260,7 +260,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
hwif->ide_dma_end = &ns87415_ide_dma_end;
}
-static ide_pci_device_t ns87415_chipset __devinitdata = {
+static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = "NS87415",
#ifdef CONFIG_SUPERIO
.init_iops = init_iops_ns87415,
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 3573ffeaaa3..8953d9c3926 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/opti621.c Version 0.8 Aug 27, 2007
+ * linux/drivers/ide/pci/opti621.c Version 0.9 Sep 24, 2007
*
* Copyright (C) 1996-1998 Linus Torvalds & authors (see below)
*/
@@ -133,6 +133,8 @@ static int reg_base;
#define PIO_NOT_EXIST 254
#define PIO_DONT_KNOW 255
+static DEFINE_SPINLOCK(opti621_lock);
+
/* there are stored pio numbers from other calls of opti621_set_pio_mode */
static void compute_pios(ide_drive_t *drive, const u8 pio)
/* Store values into drive->drive_data
@@ -278,7 +280,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
second.recovery_time, drdy);
#endif
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&opti621_lock, flags);
reg_base = hwif->io_ports[IDE_DATA_OFFSET];
@@ -317,7 +319,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio)
/* and read prefetch for both drives */
write_reg(misc, MISC_REG);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&opti621_lock, flags);
}
/*
@@ -331,7 +333,7 @@ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif)
hwif->set_pio_mode = &opti621_set_pio_mode;
}
-static ide_pci_device_t opti621_chipsets[] __devinitdata = {
+static const struct ide_port_info opti621_chipsets[] __devinitdata = {
{ /* 0 */
.name = "OPTI621",
.init_hwif = init_hwif_opti621,
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index d1e7823454f..4234efeba60 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -513,7 +513,7 @@ static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev)
.udma_mask = udma, \
}
-static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
+static const struct ide_port_info pdcnew_chipsets[] __devinitdata = {
/* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5),
/* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6),
/* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5),
@@ -534,7 +534,7 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = {
static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d;
+ const struct ide_port_info *d;
struct pci_dev *bridge = dev->bus->self;
u8 idx = id->driver_data;
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 29306121dc4..e09742e2ba5 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -302,13 +302,6 @@ static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
{
- struct pci_dev *dev = hwif->pci_dev;
-
- /* PDC20265 has problems with large LBA48 requests */
- if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) ||
- (dev->device == PCI_DEVICE_ID_PROMISE_20265))
- hwif->rqsize = 256;
-
hwif->set_pio_mode = &pdc202xx_set_pio_mode;
hwif->set_dma_mode = &pdc202xx_set_mode;
@@ -382,7 +375,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
}
}
-#define DECLARE_PDC2026X_DEV(name_str, udma) \
+#define DECLARE_PDC2026X_DEV(name_str, udma, extra_flags) \
{ \
.name = name_str, \
.init_chipset = init_chipset_pdc202xx, \
@@ -390,13 +383,14 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev,
.init_dma = init_dma_pdc202xx, \
.extra = 48, \
.host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | \
+ extra_flags | \
IDE_HFLAG_OFF_BOARD, \
.pio_mask = ATA_PIO4, \
.mwdma_mask = ATA_MWDMA2, \
.udma_mask = udma, \
}
-static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
+static const struct ide_port_info pdc202xx_chipsets[] __devinitdata = {
{ /* 0 */
.name = "PDC20246",
.init_chipset = init_chipset_pdc202xx,
@@ -410,10 +404,10 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
.udma_mask = ATA_UDMA2,
},
- /* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4),
- /* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4),
- /* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5),
- /* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5),
+ /* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4, 0),
+ /* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4, 0),
+ /* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
+ /* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5, IDE_HFLAG_RQSIZE_256),
};
/**
@@ -427,7 +421,7 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d;
+ const struct ide_port_info *d;
u8 idx = id->driver_data;
d = &pdc202xx_chipsets[idx];
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index ec0c6e96a21..9329d4a810e 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -396,7 +396,7 @@ static void __devinit init_hwif_ich(ide_hwif_t *hwif)
.udma_mask = udma, \
}
-static ide_pci_device_t piix_pci_info[] __devinitdata = {
+static const struct ide_port_info piix_pci_info[] __devinitdata = {
/* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */
/* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */
@@ -449,9 +449,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = {
static int __devinit piix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &piix_pci_info[id->driver_data];
-
- return ide_setup_pci_device(dev, d);
+ return ide_setup_pci_device(dev, &piix_pci_info[id->driver_data]);
}
/**
diff --git a/drivers/ide/pci/rz1000.c b/drivers/ide/pci/rz1000.c
index dd2583ef1ad..6b10ae260fa 100644
--- a/drivers/ide/pci/rz1000.c
+++ b/drivers/ide/pci/rz1000.c
@@ -35,13 +35,13 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
u16 reg;
struct pci_dev *dev = hwif->pci_dev;
- hwif->chipset = ide_rz1000;
if (!pci_read_config_word (dev, 0x40, &reg) &&
!pci_write_config_word(dev, 0x40, reg & 0xdfff)) {
printk(KERN_INFO "%s: disabled chipset read-ahead "
"(buggy RZ1000/RZ1001)\n", hwif->name);
} else {
- hwif->serialized = 1;
+ if (hwif->mate)
+ hwif->mate->serialized = hwif->serialized = 1;
hwif->drives[0].no_unmask = 1;
hwif->drives[1].no_unmask = 1;
printk(KERN_INFO "%s: serialized, disabled unmasking "
@@ -49,9 +49,10 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif)
}
}
-static ide_pci_device_t rz1000_chipset __devinitdata = {
+static const struct ide_port_info rz1000_chipset __devinitdata = {
.name = "RZ100x",
.init_hwif = init_hwif_rz1000,
+ .chipset = ide_rz1000,
.host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE,
};
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index b2423e03bf3..d2c8b5524f2 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -372,7 +372,7 @@ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif)
hwif->ide_dma_end = &sc1200_ide_dma_end;
}
-static ide_pci_device_t sc1200_chipset __devinitdata = {
+static const struct ide_port_info sc1200_chipset __devinitdata = {
.name = "SC1200",
.init_hwif = init_hwif_sc1200,
.host_flags = IDE_HFLAG_SERIALIZE |
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index ae9b50331d2..ebb7132b9b8 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -538,12 +538,13 @@ static int setup_mmio_scc (struct pci_dev *dev, const char *name)
/**
* init_setup_scc - set up an SCC PATA Controller
* @dev: PCI device
- * @d: IDE PCI device
+ * @d: IDE port info
*
* Perform the initial set up for this device.
*/
-static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
+static int __devinit init_setup_scc(struct pci_dev *dev,
+ const struct ide_port_info *d)
{
unsigned long ctl_base;
unsigned long dma_base;
@@ -702,7 +703,7 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif)
.pio_mask = ATA_PIO4, \
}
-static ide_pci_device_t scc_chipsets[] __devinitdata = {
+static const struct ide_port_info scc_chipsets[] __devinitdata = {
/* 0 */ DECLARE_SCC_DEV("sccIDE"),
};
@@ -717,9 +718,7 @@ static ide_pci_device_t scc_chipsets[] __devinitdata = {
static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t *d = &scc_chipsets[id->driver_data];
-
- return init_setup_scc(dev, d);
+ return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
}
/**
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index a3d880e21d0..a7280311357 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -158,13 +158,6 @@ static void svwks_set_dma_mode(ide_drive_t *drive, const u8 speed)
u8 ultra_enable = 0, ultra_timing = 0, dma_timing = 0;
- /* If we are about to put a disk into UDMA mode we screwed up.
- Our code assumes we never _ever_ do this on an OSB4 */
-
- if(dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4 &&
- drive->media == ide_disk && speed >= XFER_UDMA_0)
- BUG();
-
pci_read_config_byte(dev, (0x56|hwif->channel), &ultra_timing);
pci_read_config_byte(dev, 0x54, &ultra_enable);
@@ -373,7 +366,7 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
}
}
-static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
+static const struct ide_port_info serverworks_chipsets[] __devinitdata = {
{ /* 0 */
.name = "SvrWks OSB4",
.init_chipset = init_chipset_svwks,
@@ -430,7 +423,7 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- ide_pci_device_t d;
+ struct ide_port_info d;
u8 idx = id->driver_data;
d = serverworks_chipsets[idx];
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 5af74ea1d46..de820aa58cd 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -614,6 +614,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
void __iomem *virt_base;
ide_hwif_t *hwif;
int h;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
/*
* Find an empty HWIF; if none available, return -ENOMEM.
@@ -654,10 +655,12 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
}
if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) {
+ hw_regs_t hw;
+
/* Initialize the IO registers */
- sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport);
- memcpy(hwif->io_ports, hwif->hw.io_ports,
- sizeof (hwif->io_ports));
+ memset(&hw, 0, sizeof(hw));
+ sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
}
@@ -679,11 +682,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
ide_init_sgiioc4(hwif);
- if (probe_hwif_init(hwif))
- return -EIO;
+ idx[0] = hwif->index;
- /* Create /proc/ide entries */
- ide_proc_register_port(hwif);
+ if (ide_device_add(idx))
+ return -EIO;
return 0;
}
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 689786df1ed..6d99441c605 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/siimage.c Version 1.17 Oct 18 2007
+ * linux/drivers/ide/pci/siimage.c Version 1.18 Oct 18 2007
*
* Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2003 Red Hat <alan@redhat.com>
@@ -26,7 +26,7 @@
*
* If you have strange problems with nVidia chipset systems please
* see the SI support documentation and update your system BIOS
- * if neccessary
+ * if necessary
*
* The Dell DRAC4 has some interesting features including effectively hot
* unplugging/replugging the virtual CD interface when the DRAC is reset.
@@ -57,8 +57,8 @@
static int pdev_is_sata(struct pci_dev *pdev)
{
- switch(pdev->device)
- {
+#ifdef CONFIG_BLK_DEV_IDE_SATA
+ switch(pdev->device) {
case PCI_DEVICE_ID_SII_3112:
case PCI_DEVICE_ID_SII_1210SA:
return 1;
@@ -66,9 +66,10 @@ static int pdev_is_sata(struct pci_dev *pdev)
return 0;
}
BUG();
+#endif
return 0;
}
-
+
/**
* is_sata - check if hwif is SATA
* @hwif: interface to check
@@ -136,7 +137,7 @@ static inline unsigned long siimage_seldev(ide_drive_t *drive, int r)
* SI3112 SATA controller life is a bit simpler.
*/
-static u8 sil_udma_filter(ide_drive_t *drive)
+static u8 sil_pata_udma_filter(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long base = (unsigned long) hwif->hwif_data;
@@ -147,23 +148,23 @@ static u8 sil_udma_filter(ide_drive_t *drive)
else
pci_read_config_byte(hwif->pci_dev, 0x8A, &scsc);
- if (is_sata(hwif)) {
- mask = strstr(drive->id->model, "Maxtor") ? 0x3f : 0x7f;
- goto out;
- }
-
if ((scsc & 0x30) == 0x10) /* 133 */
- mask = 0x7f;
+ mask = ATA_UDMA6;
else if ((scsc & 0x30) == 0x20) /* 2xPCI */
- mask = 0x7f;
+ mask = ATA_UDMA6;
else if ((scsc & 0x30) == 0x00) /* 100 */
- mask = 0x3f;
+ mask = ATA_UDMA5;
else /* Disabled ? */
BUG();
-out:
+
return mask;
}
+static u8 sil_sata_udma_filter(ide_drive_t *drive)
+{
+ return strstr(drive->id->model, "Maxtor") ? ATA_UDMA5 : ATA_UDMA6;
+}
+
/**
* sil_set_pio_mode - set host controller for PIO mode
* @drive: drive
@@ -340,10 +341,11 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive)
static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
{
ide_hwif_t *hwif = HWIF(drive);
- unsigned long base = (unsigned long)hwif->hwif_data;
unsigned long addr = siimage_selreg(hwif, 0x1);
if (SATA_ERROR_REG) {
+ unsigned long base = (unsigned long)hwif->hwif_data;
+
u32 ext_stat = readl((void __iomem *)(base + 0x10));
u8 watchdog = 0;
if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
@@ -376,7 +378,7 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
}
/**
- * siimage_busproc - bus isolation ioctl
+ * sil_sata_busproc - bus isolation IOCTL
* @drive: drive to isolate/restore
* @state: bus state to set
*
@@ -384,8 +386,8 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
* SATA controller the work required is quite limited, we
* just have to clean up the statistics
*/
-
-static int siimage_busproc (ide_drive_t * drive, int state)
+
+static int sil_sata_busproc(ide_drive_t * drive, int state)
{
ide_hwif_t *hwif = HWIF(drive);
u32 stat_config = 0;
@@ -417,14 +419,14 @@ static int siimage_busproc (ide_drive_t * drive, int state)
}
/**
- * siimage_reset_poll - wait for sata reset
+ * sil_sata_reset_poll - wait for SATA reset
* @drive: drive we are resetting
*
* Poll the SATA phy and see whether it has come back from the dead
* yet.
*/
-
-static int siimage_reset_poll (ide_drive_t *drive)
+
+static int sil_sata_reset_poll(ide_drive_t *drive)
{
if (SATA_STATUS_REG) {
ide_hwif_t *hwif = HWIF(drive);
@@ -436,27 +438,22 @@ static int siimage_reset_poll (ide_drive_t *drive)
HWGROUP(drive)->polling = 0;
return ide_started;
}
- return 0;
- } else {
- return 0;
}
+
+ return 0;
}
/**
- * siimage_pre_reset - reset hook
+ * sil_sata_pre_reset - reset hook
* @drive: IDE device being reset
*
* For the SATA devices we need to handle recalibration/geometry
* differently
*/
-
-static void siimage_pre_reset (ide_drive_t *drive)
-{
- if (drive->media != ide_disk)
- return;
- if (is_sata(HWIF(drive)))
- {
+static void sil_sata_pre_reset(ide_drive_t *drive)
+{
+ if (drive->media == ide_disk) {
drive->special.b.set_geometry = 0;
drive->special.b.recalibrate = 0;
}
@@ -502,7 +499,6 @@ static void siimage_reset (ide_drive_t *drive)
drive->failures++;
}
}
-
}
/**
@@ -758,16 +754,11 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148;
}
- hw.irq = hwif->pci_dev->irq;
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
- memcpy(&hwif->hw, &hw, sizeof(hw));
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
+ hwif->irq = dev->irq;
- hwif->irq = hw.irq;
-
- base = (unsigned long) addr;
-
- hwif->dma_base = base + (ch ? 0x08 : 0x00);
+ hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00);
hwif->mmio = 1;
}
@@ -864,28 +855,31 @@ static u8 __devinit ata66_siimage(ide_hwif_t *hwif)
static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
{
+ u8 sata = is_sata(hwif);
+
hwif->resetproc = &siimage_reset;
hwif->set_pio_mode = &sil_set_pio_mode;
hwif->set_dma_mode = &sil_set_dma_mode;
- hwif->reset_poll = &siimage_reset_poll;
- hwif->pre_reset = &siimage_pre_reset;
- hwif->udma_filter = &sil_udma_filter;
- if(is_sata(hwif)) {
+ if (sata) {
static int first = 1;
- hwif->busproc = &siimage_busproc;
+ hwif->busproc = &sil_sata_busproc;
+ hwif->reset_poll = &sil_sata_reset_poll;
+ hwif->pre_reset = &sil_sata_pre_reset;
+ hwif->udma_filter = &sil_sata_udma_filter;
if (first) {
printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n");
first = 0;
}
- }
+ } else
+ hwif->udma_filter = &sil_pata_udma_filter;
if (hwif->dma_base == 0)
return;
- if (is_sata(hwif))
+ if (sata)
hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA;
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
@@ -911,7 +905,7 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif)
.udma_mask = ATA_UDMA6, \
}
-static ide_pci_device_t siimage_chipsets[] __devinitdata = {
+static const struct ide_port_info siimage_chipsets[] __devinitdata = {
/* 0 */ DECLARE_SII_DEV("SiI680"),
/* 1 */ DECLARE_SII_DEV("SiI3112 Serial ATA"),
/* 2 */ DECLARE_SII_DEV("Adaptec AAR-1210SA")
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index c1d280b0639..6b7bb53acef 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -264,7 +264,7 @@ static void sis_ata133_program_timings(ide_drive_t *drive, const u8 mode)
if (mode >= XFER_MW_DMA_0) {
t1 &= ~0x04; /* disable UDMA */
idx = mode - XFER_MW_DMA_0 + 5;
- }
+ } else
idx = mode - XFER_PIO_0;
t1 |= ini_time_value[clk][idx] << 12;
t1 |= act_time_value[clk][idx] << 16;
@@ -579,7 +579,7 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif)
hwif->cbl = ata66_sis5513(hwif);
}
-static ide_pci_device_t sis5513_chipset __devinitdata = {
+static const struct ide_port_info sis5513_chipset __devinitdata = {
.name = "SIS5513",
.init_chipset = init_chipset_sis5513,
.init_hwif = init_hwif_sis5513,
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 0dce459b126..147d783f752 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -361,13 +361,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->selectproc = &sl82c105_selectproc;
hwif->resetproc = &sl82c105_resetproc;
- /*
- * We support 32-bit I/O on this interface, and
- * it doesn't have problems with interrupts.
- */
- hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1;
- hwif->drives[0].unmask = hwif->drives[1].unmask = 1;
-
if (!hwif->dma_base)
return;
@@ -394,12 +387,15 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
hwif->serialized = hwif->mate->serialized = 1;
}
-static ide_pci_device_t sl82c105_chipset __devinitdata = {
+static const struct ide_port_info sl82c105_chipset __devinitdata = {
.name = "W82C105",
.init_chipset = init_chipset_sl82c105,
.init_hwif = init_hwif_sl82c105,
.enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}},
- .host_flags = IDE_HFLAG_NO_AUTODMA | IDE_HFLAG_BOOTABLE,
+ .host_flags = IDE_HFLAG_IO_32BIT |
+ IDE_HFLAG_UNMASK_IRQS |
+ IDE_HFLAG_NO_AUTODMA |
+ IDE_HFLAG_BOOTABLE,
.pio_mask = ATA_PIO5,
};
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 4f22dffdf8e..eb4445b229e 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/ide/pci/slc90e66.c Version 0.18 Aug 9, 2007
+ * linux/drivers/ide/pci/slc90e66.c Version 0.19 Sep 24, 2007
*
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2006-2007 MontaVista Software, Inc. <source@mvista.com>
@@ -21,6 +21,8 @@
#include <asm/io.h>
+static DEFINE_SPINLOCK(slc90e66_lock);
+
static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{
ide_hwif_t *hwif = HWIF(drive);
@@ -40,7 +42,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
{ 2, 1 },
{ 2, 3 }, };
- spin_lock_irqsave(&ide_lock, flags);
+ spin_lock_irqsave(&slc90e66_lock, flags);
pci_read_config_word(dev, master_port, &master_data);
if (pio > 1)
@@ -71,7 +73,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio)
pci_write_config_word(dev, master_port, master_data);
if (is_slave)
pci_write_config_byte(dev, slave_port, slave_data);
- spin_unlock_irqrestore(&ide_lock, flags);
+ spin_unlock_irqrestore(&slc90e66_lock, flags);
}
static void slc90e66_set_dma_mode(ide_drive_t *drive, const u8 speed)
@@ -146,7 +148,7 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
-static ide_pci_device_t slc90e66_chipset __devinitdata = {
+static const struct ide_port_info slc90e66_chipset __devinitdata = {
.name = "SLC90E66",
.init_hwif = init_hwif_slc90e66,
.enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}},
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 631506e9b5d..a66ebd14664 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -218,7 +218,7 @@ static unsigned int __devinit init_chipset_tc86c001(struct pci_dev *dev,
return err;
}
-static ide_pci_device_t tc86c001_chipset __devinitdata = {
+static const struct ide_port_info tc86c001_chipset __devinitdata = {
.name = "TC86C001",
.init_chipset = init_chipset_tc86c001,
.init_hwif = init_hwif_tc86c001,
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index 30b52f62699..a227c41d23a 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -102,7 +102,7 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
hwif->set_dma_mode = &triflex_set_mode;
}
-static ide_pci_device_t triflex_device __devinitdata = {
+static const struct ide_port_info triflex_device __devinitdata = {
.name = "TRIFLEX",
.init_hwif = init_hwif_triflex,
.enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}},
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 140d486f623..5011ba22e36 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -250,7 +250,6 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
u8 reg = 0;
struct pci_dev *dev = hwif->pci_dev;
- hwif->chipset = ide_trm290;
cfgbase = pci_resource_start(dev, 4);
if ((dev->class & 5) && cfgbase) {
hwif->config_data = cfgbase;
@@ -320,9 +319,10 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
-static ide_pci_device_t trm290_chipset __devinitdata = {
+static const struct ide_port_info trm290_chipset __devinitdata = {
.name = "TRM290",
.init_hwif = init_hwif_trm290,
+ .chipset = ide_trm290,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
#if 0 /* play it safe for now */
IDE_HFLAG_TRUST_BIOS_FOR_DMA |
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index c8022a92a0e..a0d3c16b68e 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -1,6 +1,6 @@
/*
*
- * Version 3.49
+ * Version 3.50
*
* VIA IDE driver for Linux. Supported southbridges:
*
@@ -422,65 +422,40 @@ static u8 __devinit via82cxxx_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
{
- struct via82cxxx_dev *vdev = pci_get_drvdata(hwif->pci_dev);
- int i;
-
hwif->set_pio_mode = &via_set_pio_mode;
hwif->set_dma_mode = &via_set_drive;
-#ifdef CONFIG_PPC_CHRP
- if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
- hwif->irq = hwif->channel ? 15 : 14;
- }
-#endif
-
- for (i = 0; i < 2; i++) {
- hwif->drives[i].io_32bit = 1;
- hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1;
- }
-
if (!hwif->dma_base)
return;
- hwif->ultra_mask = vdev->via_config->udma_mask;
-
if (hwif->cbl != ATA_CBL_PATA40_SHORT)
hwif->cbl = via82cxxx_cable_detect(hwif);
}
-static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = {
- { /* 0 */
- .name = "VP_IDE",
- .init_chipset = init_chipset_via82cxxx,
- .init_hwif = init_hwif_via82cxxx,
- .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}},
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
- IDE_HFLAG_PIO_NO_DOWNGRADE |
- IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_NO_AUTODMA |
- IDE_HFLAG_BOOTABLE,
- .pio_mask = ATA_PIO5,
- .swdma_mask = ATA_SWDMA2,
- .mwdma_mask = ATA_MWDMA2,
- },{ /* 1 */
- .name = "VP_IDE",
- .init_chipset = init_chipset_via82cxxx,
- .init_hwif = init_hwif_via82cxxx,
- .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}},
- .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
- IDE_HFLAG_PIO_NO_DOWNGRADE |
- IDE_HFLAG_POST_SET_MODE |
- IDE_HFLAG_BOOTABLE,
- .pio_mask = ATA_PIO5,
- .swdma_mask = ATA_SWDMA2,
- .mwdma_mask = ATA_MWDMA2,
- }
+static const struct ide_port_info via82cxxx_chipset __devinitdata = {
+ .name = "VP_IDE",
+ .init_chipset = init_chipset_via82cxxx,
+ .init_hwif = init_hwif_via82cxxx,
+ .enablebits = { { 0x40, 0x02, 0x02 }, { 0x40, 0x01, 0x01 } },
+ .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST |
+ IDE_HFLAG_PIO_NO_DOWNGRADE |
+ IDE_HFLAG_POST_SET_MODE |
+ IDE_HFLAG_IO_32BIT |
+ IDE_HFLAG_BOOTABLE,
+ .pio_mask = ATA_PIO5,
+ .swdma_mask = ATA_SWDMA2,
+ .mwdma_mask = ATA_MWDMA2,
};
static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
struct pci_dev *isa = NULL;
struct via_isa_bridge *via_config;
+ u8 idx = id->driver_data;
+ struct ide_port_info d;
+
+ d = via82cxxx_chipset;
+
/*
* Find the ISA bridge and check we know what it is.
*/
@@ -490,7 +465,23 @@ static int __devinit via_init_one(struct pci_dev *dev, const struct pci_device_i
printk(KERN_WARNING "VP_IDE: Unknown VIA SouthBridge, disabling DMA.\n");
return -ENODEV;
}
- return ide_setup_pci_device(dev, &via82cxxx_chipsets[id->driver_data]);
+
+ if (idx == 0)
+ d.host_flags |= IDE_HFLAG_NO_AUTODMA;
+ else
+ d.enablebits[1].reg = d.enablebits[0].reg = 0;
+
+ if ((via_config->flags & VIA_NO_UNMASK) == 0)
+ d.host_flags |= IDE_HFLAG_UNMASK_IRQS;
+
+#ifdef CONFIG_PPC_CHRP
+ if (machine_is(chrp) && _chrp_type == _CHRP_Pegasos)
+ d.host_flags |= IDE_HFLAG_FORCE_LEGACY_IRQS;
+#endif
+
+ d.udma_mask = via_config->udma_mask;
+
+ return ide_setup_pci_device(dev, &d);
}
static const struct pci_device_id via_pci_tbl[] = {
diff --git a/drivers/ide/ppc/mpc8xx.c b/drivers/ide/ppc/mpc8xx.c
index df2e92034f5..5f0da35ab5a 100644
--- a/drivers/ide/ppc/mpc8xx.c
+++ b/drivers/ide/ppc/mpc8xx.c
@@ -316,8 +316,8 @@ m8xx_ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
ide_hwifs[data_port].pio_mask = ATA_PIO4;
ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+ ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
- hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
/* Enable Harddisk Interrupt,
* and make it edge sensitive
*/
@@ -402,8 +402,8 @@ void m8xx_ide_init_hwif_ports (hw_regs_t *hw,
ide_hwifs[data_port].pio_mask = ATA_PIO4;
ide_hwifs[data_port].set_pio_mode = m8xx_ide_set_pio_mode;
+ ide_hwifs[data_port].ack_intr = (ide_ack_intr_t *)ide_interrupt_ack;
- hw->ack_intr = (ide_ack_intr_t *) ide_interrupt_ack;
/* Enable Harddisk Interrupt,
* and make it edge sensitive
*/
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index c5547935676..816b5311dad 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1039,6 +1039,8 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
{
struct device_node *np = pmif->node;
const int *bidp;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+ hw_regs_t hw;
pmif->cable_80 = 0;
pmif->broken_dma = pmif->broken_dma_warn = 0;
@@ -1124,8 +1126,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
/* Tell common code _not_ to mess with resources */
hwif->mmio = 1;
hwif->hwif_data = pmif;
- pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ memset(&hw, 0, sizeof(hw));
+ pmac_ide_init_hwif_ports(&hw, pmif->regbase, 0, &hwif->irq);
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
hwif->chipset = ide_pmac;
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;
hwif->hold = pmif->mediabay;
@@ -1163,10 +1166,9 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
pmac_ide_setup_dma(pmif, hwif);
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
- /* We probe the hwif now */
- probe_hwif_init(hwif);
+ idx[0] = hwif->index;
- ide_proc_register_port(hwif);
+ ide_device_add(idx);
return 0;
}
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index fff567bcedb..02d14bf85ab 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -147,15 +147,15 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name)
#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
/**
* ide_get_or_set_dma_base - setup BMIBA
- * @d: IDE pci device data
- * @hwif: Interface
+ * @d: IDE port info
+ * @hwif: IDE interface
*
* Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
* Where a device has a partner that is already in DMA mode we check
* and enforce IDE simplex rules.
*/
-static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hwif)
+static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
{
unsigned long dma_base = 0;
struct pci_dev *dev = hwif->pci_dev;
@@ -225,10 +225,11 @@ static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hw
}
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
-void ide_setup_pci_noise (struct pci_dev *dev, ide_pci_device_t *d)
+void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
{
- printk(KERN_INFO "%s: IDE controller at PCI slot %s\n",
- d->name, pci_name(dev));
+ printk(KERN_INFO "%s: IDE controller (0x%04x:0x%04x rev 0x%02x) at "
+ " PCI slot %s\n", d->name, dev->vendor, dev->device,
+ dev->revision, pci_name(dev));
}
EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
@@ -237,15 +238,15 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
/**
* ide_pci_enable - do PCI enables
* @dev: PCI device
- * @d: IDE pci device data
+ * @d: IDE port info
*
* Enable the IDE PCI device. We attempt to enable the device in full
* but if that fails then we only need BAR4 so we will enable that.
*
* Returns zero on success or an error code
*/
-
-static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_enable(struct pci_dev *dev, const struct ide_port_info *d)
{
int ret;
@@ -260,9 +261,9 @@ static int ide_pci_enable(struct pci_dev *dev, ide_pci_device_t *d)
}
/*
- * assume all devices can do 32-bit dma for now. we can add a
- * dma mask field to the ide_pci_device_t if we need it (or let
- * lower level driver set the dma mask)
+ * assume all devices can do 32-bit DMA for now, we can add
+ * a DMA mask field to the struct ide_port_info if we need it
+ * (or let lower level driver set the DMA mask)
*/
ret = pci_set_dma_mask(dev, DMA_32BIT_MASK);
if (ret < 0) {
@@ -284,13 +285,13 @@ out:
/**
* ide_pci_configure - configure an unconfigured device
* @dev: PCI device
- * @d: IDE pci device data
+ * @d: IDE port info
*
* Enable and configure the PCI device we have been passed.
* Returns zero on success or an error code.
*/
-
-static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d)
+
+static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
{
u16 pcicmd = 0;
/*
@@ -318,15 +319,15 @@ static int ide_pci_configure(struct pci_dev *dev, ide_pci_device_t *d)
/**
* ide_pci_check_iomem - check a register is I/O
- * @dev: pci device
- * @d: ide_pci_device
- * @bar: bar number
+ * @dev: PCI device
+ * @d: IDE port info
+ * @bar: BAR number
*
* Checks if a BAR is configured and points to MMIO space. If so
* print an error and return an error code. Otherwise return 0
*/
-
-static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar)
+
+static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d, int bar)
{
ulong flags = pci_resource_flags(dev, bar);
@@ -348,7 +349,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar
/**
* ide_hwif_configure - configure an IDE interface
* @dev: PCI device holding interface
- * @d: IDE pci data
+ * @d: IDE port info
* @mate: Paired interface if any
*
* Perform the initial set up for the hardware interface structure. This
@@ -357,8 +358,8 @@ static int ide_pci_check_iomem(struct pci_dev *dev, ide_pci_device_t *d, int bar
*
* Returns the new hardware interface structure, or NULL on a failure
*/
-
-static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *mate, int port, int irq)
+
+static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *mate, int port, int irq)
{
unsigned long ctl = 0, base = 0;
ide_hwif_t *hwif;
@@ -387,19 +388,20 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
return NULL; /* no room in ide_hwifs[] */
if (hwif->io_ports[IDE_DATA_OFFSET] != base ||
hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {
- memset(&hwif->hw, 0, sizeof(hwif->hw));
-#ifndef IDE_ARCH_OBSOLETE_INIT
- ide_std_init_ports(&hwif->hw, base, (ctl | 2));
- hwif->hw.io_ports[IDE_IRQ_OFFSET] = 0;
+ hw_regs_t hw;
+
+ memset(&hw, 0, sizeof(hw));
+#ifndef CONFIG_IDE_ARCH_OBSOLETE_INIT
+ ide_std_init_ports(&hw, base, ctl | 2);
#else
- ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);
+ ide_init_hwif_ports(&hw, base, ctl | 2, NULL);
#endif
- memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
+ memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports));
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
}
- hwif->chipset = ide_pci;
+ hwif->chipset = d->chipset ? d->chipset : ide_pci;
hwif->pci_dev = dev;
- hwif->cds = (struct ide_pci_device_s *) d;
+ hwif->cds = d;
hwif->channel = port;
if (!hwif->irq)
@@ -414,21 +416,17 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d,
/**
* ide_hwif_setup_dma - configure DMA interface
* @dev: PCI device
- * @d: IDE pci data
- * @hwif: Hardware interface we are configuring
+ * @d: IDE port info
+ * @hwif: IDE interface
*
* Set up the DMA base for the interface. Enable the master bits as
* necessary and attempt to bring the device DMA into a ready to use
* state
*/
-
-#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
-{
-}
-#else
-static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif)
+
+static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
{
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
u16 pcicmd;
pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
@@ -460,13 +458,13 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
"(BIOS)\n", hwif->name, d->name);
}
}
-}
#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+}
/**
* ide_setup_pci_controller - set up IDE PCI
* @dev: PCI device
- * @d: IDE PCI data
+ * @d: IDE port info
* @noisy: verbose flag
* @config: returned as 1 if we configured the hardware
*
@@ -474,8 +472,8 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi
* up the PCI side of the device, checks that the device is enabled
* and enables it if need be
*/
-
-static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config)
+
+static int ide_setup_pci_controller(struct pci_dev *dev, const struct ide_port_info *d, int noisy, int *config)
{
int ret;
u16 pcicmd;
@@ -500,9 +498,6 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in
printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);
}
- if (noisy)
- printk(KERN_INFO "%s: chipset revision %d\n",
- d->name, dev->revision);
out:
return ret;
}
@@ -510,9 +505,9 @@ out:
/**
* ide_pci_setup_ports - configure ports/devices on PCI IDE
* @dev: PCI device
- * @d: IDE pci device info
+ * @d: IDE port info
* @pciirq: IRQ line
- * @index: ata index to update
+ * @idx: ATA index table to update
*
* Scan the interfaces attached to this device and do any
* necessary per port setup. Attach the devices and ask the
@@ -522,26 +517,25 @@ out:
* but is also used directly as a helper function by some controllers
* where the chipset setup is not the default PCI IDE one.
*/
-
-void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, ata_index_t *index)
+
+void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, int pciirq, u8 *idx)
{
int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
- int at_least_one_hwif_enabled = 0;
ide_hwif_t *hwif, *mate = NULL;
u8 tmp;
- index->all = 0xf0f0;
-
/*
* Set up the IDE ports
*/
-
+
for (port = 0; port < channels; ++port) {
- ide_pci_enablebit_t *e = &(d->enablebits[port]);
-
+ const ide_pci_enablebit_t *e = &(d->enablebits[port]);
+
if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
- (tmp & e->mask) != e->val))
+ (tmp & e->mask) != e->val)) {
+ printk(KERN_INFO "%s: IDE port disabled\n", d->name);
continue; /* port not enabled */
+ }
if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)
continue;
@@ -549,11 +543,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
/* setup proper ancestral information */
hwif->gendev.parent = &dev->dev;
- if (hwif->channel) {
- index->b.high = hwif->index;
- } else {
- index->b.low = hwif->index;
- }
+ *(idx + port) = hwif->index;
if (d->init_iops)
@@ -562,15 +552,28 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
ide_hwif_setup_dma(dev, d, hwif);
- if ((d->host_flags & IDE_HFLAG_LEGACY_IRQS) && hwif->irq == 0)
+ if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
+ (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
hwif->irq = port ? 15 : 14;
+ hwif->fixup = d->fixup;
+
hwif->host_flags = d->host_flags;
hwif->pio_mask = d->pio_mask;
if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)
hwif->mate->serialized = hwif->serialized = 1;
+ if (d->host_flags & IDE_HFLAG_IO_32BIT) {
+ hwif->drives[0].io_32bit = 1;
+ hwif->drives[1].io_32bit = 1;
+ }
+
+ if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
+ hwif->drives[0].unmask = 1;
+ hwif->drives[1].unmask = 1;
+ }
+
if (hwif->dma_base) {
hwif->swdma_mask = d->swdma_mask;
hwif->mwdma_mask = d->mwdma_mask;
@@ -580,6 +583,9 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
+ if (d->host_flags & IDE_HFLAG_RQSIZE_256)
+ hwif->rqsize = 256;
+
if (d->init_hwif)
/* Call chipset-specific routine
* for each enabled hwif
@@ -587,10 +593,7 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
d->init_hwif(hwif);
mate = hwif;
- at_least_one_hwif_enabled = 1;
}
- if (!at_least_one_hwif_enabled)
- printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name);
}
EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
@@ -602,13 +605,13 @@ EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
*
* One thing that is not standardized is the location of the
* primary/secondary interface "enable/disable" bits. For chipsets that
- * we "know" about, this information is in the ide_pci_device_t struct;
+ * we "know" about, this information is in the struct ide_port_info;
* for all other chipsets, we just assume both interfaces are enabled.
*/
-static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
- ata_index_t *index, u8 noisy)
+static int do_ide_setup_pci_device(struct pci_dev *dev,
+ const struct ide_port_info *d,
+ u8 *idx, u8 noisy)
{
- static ata_index_t ata_index = { .b = { .low = 0xff, .high = 0xff } };
int tried_config = 0;
int pciirq, ret;
@@ -658,51 +661,35 @@ static int do_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d,
/* FIXME: silent failure can happen */
- *index = ata_index;
- ide_pci_setup_ports(dev, d, pciirq, index);
+ ide_pci_setup_ports(dev, d, pciirq, idx);
out:
return ret;
}
-int ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d)
+int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d)
{
- ide_hwif_t *hwif = NULL, *mate = NULL;
- ata_index_t index_list;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
int ret;
- ret = do_ide_setup_pci_device(dev, d, &index_list, 1);
- if (ret < 0)
- goto out;
+ ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);
- if ((index_list.b.low & 0xf0) != 0xf0)
- hwif = &ide_hwifs[index_list.b.low];
- if ((index_list.b.high & 0xf0) != 0xf0)
- mate = &ide_hwifs[index_list.b.high];
+ if (ret >= 0)
+ ide_device_add(idx);
- if (hwif)
- probe_hwif_init_with_fixup(hwif, d->fixup);
- if (mate)
- probe_hwif_init_with_fixup(mate, d->fixup);
-
- if (hwif)
- ide_proc_register_port(hwif);
- if (mate)
- ide_proc_register_port(mate);
-out:
return ret;
}
EXPORT_SYMBOL_GPL(ide_setup_pci_device);
int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
- ide_pci_device_t *d)
+ const struct ide_port_info *d)
{
struct pci_dev *pdev[] = { dev1, dev2 };
- ata_index_t index_list[2];
int ret, i;
+ u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
for (i = 0; i < 2; i++) {
- ret = do_ide_setup_pci_device(pdev[i], d, index_list + i, !i);
+ ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i);
/*
* FIXME: Mom, mom, they stole me the helper function to undo
* do_ide_setup_pci_device() on the first device!
@@ -711,25 +698,7 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,
goto out;
}
- for (i = 0; i < 2; i++) {
- u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
- int j;
-
- for (j = 0; j < 2; j++) {
- if ((idx[j] & 0xf0) != 0xf0)
- probe_hwif_init(ide_hwifs + idx[j]);
- }
- }
-
- for (i = 0; i < 2; i++) {
- u8 idx[2] = { index_list[i].b.low, index_list[i].b.high };
- int j;
-
- for (j = 0; j < 2; j++) {
- if ((idx[j] & 0xf0) != 0xf0)
- ide_proc_register_port(ide_hwifs + idx[j]);
- }
- }
+ ide_device_add(idx);
out:
return ret;
}
@@ -754,9 +723,6 @@ static LIST_HEAD(ide_pci_drivers);
* hands the controllers off to the core PCI code to do the rest of
* the work.
*
- * The driver_data of the driver table must point to an ide_pci_device_t
- * describing the interface.
- *
* Returns are the same as for pci_register_driver
*/
diff --git a/drivers/ieee1394/dma.c b/drivers/ieee1394/dma.c
index 45d60558192..25e113b50d8 100644
--- a/drivers/ieee1394/dma.c
+++ b/drivers/ieee1394/dma.c
@@ -111,7 +111,7 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
unsigned long va =
(unsigned long)dma->kvirt + (i << PAGE_SHIFT);
- dma->sglist[i].page = vmalloc_to_page((void *)va);
+ sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
dma->sglist[i].length = PAGE_SIZE;
}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1b353b964b3..d5dfe11aa5c 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -1466,7 +1466,7 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
cmd->dma_size = sgpnt[0].length;
cmd->dma_type = CMD_DMA_PAGE;
cmd->cmd_dma = dma_map_page(hi->host->device.parent,
- sgpnt[0].page, sgpnt[0].offset,
+ sg_page(&sgpnt[0]), sgpnt[0].offset,
cmd->dma_size, cmd->dma_dir);
orb->data_descriptor_lo = cmd->cmd_dma;
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 93644f82592..d08fb30768b 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -2797,11 +2797,12 @@ static void cma_remove_one(struct ib_device *device)
static int cma_init(void)
{
- int ret, low, high;
+ int ret, low, high, remaining;
get_random_bytes(&next_port, sizeof next_port);
inet_get_local_port_range(&low, &high);
- next_port = ((unsigned int) next_port % (high - low)) + low;
+ remaining = (high - low) + 1;
+ next_port = ((unsigned int) next_port % remaining) + low;
cma_wq = create_singlethread_workqueue("rdma_cm");
if (!cma_wq)
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
index 2f54e29dc7a..14159ff2940 100644
--- a/drivers/infiniband/core/umem.c
+++ b/drivers/infiniband/core/umem.c
@@ -55,9 +55,11 @@ static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int d
ib_dma_unmap_sg(dev, chunk->page_list,
chunk->nents, DMA_BIDIRECTIONAL);
for (i = 0; i < chunk->nents; ++i) {
+ struct page *page = sg_page(&chunk->page_list[i]);
+
if (umem->writable && dirty)
- set_page_dirty_lock(chunk->page_list[i].page);
- put_page(chunk->page_list[i].page);
+ set_page_dirty_lock(page);
+ put_page(page);
}
kfree(chunk);
@@ -164,11 +166,12 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
}
chunk->nents = min_t(int, ret, IB_UMEM_MAX_PAGE_CHUNK);
+ sg_init_table(chunk->page_list, chunk->nents);
for (i = 0; i < chunk->nents; ++i) {
if (vma_list &&
!is_vm_hugetlb_page(vma_list[i + off]))
umem->hugetlb = 0;
- chunk->page_list[i].page = page_list[i + off];
+ sg_set_page(&chunk->page_list[i], page_list[i + off]);
chunk->page_list[i].offset = 0;
chunk->page_list[i].length = PAGE_SIZE;
}
@@ -179,7 +182,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
DMA_BIDIRECTIONAL);
if (chunk->nmap <= 0) {
for (i = 0; i < chunk->nents; ++i)
- put_page(chunk->page_list[i].page);
+ put_page(sg_page(&chunk->page_list[i]));
kfree(chunk);
ret = -ENOMEM;
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 22709a4f8fc..e90a0ea538a 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -108,7 +108,7 @@ static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
BUG_ON(!valid_dma_direction(direction));
for_each_sg(sgl, sg, nents, i) {
- addr = (u64) page_address(sg->page);
+ addr = (u64) page_address(sg_page(sg));
/* TODO: handle highmem pages */
if (!addr) {
ret = 0;
@@ -127,7 +127,7 @@ static void ipath_unmap_sg(struct ib_device *dev,
static u64 ipath_sg_dma_address(struct ib_device *dev, struct scatterlist *sg)
{
- u64 addr = (u64) page_address(sg->page);
+ u64 addr = (u64) page_address(sg_page(sg));
if (addr)
addr += sg->offset;
diff --git a/drivers/infiniband/hw/ipath/ipath_mr.c b/drivers/infiniband/hw/ipath/ipath_mr.c
index e442470a237..db4ba92f79f 100644
--- a/drivers/infiniband/hw/ipath/ipath_mr.c
+++ b/drivers/infiniband/hw/ipath/ipath_mr.c
@@ -225,7 +225,7 @@ struct ib_mr *ipath_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
for (i = 0; i < chunk->nents; i++) {
void *vaddr;
- vaddr = page_address(chunk->page_list[i].page);
+ vaddr = page_address(sg_page(&chunk->page_list[i]));
if (!vaddr) {
ret = ERR_PTR(-EINVAL);
goto bail;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index e61f3e62698..007b38157fc 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -71,7 +71,7 @@ static void mthca_free_icm_pages(struct mthca_dev *dev, struct mthca_icm_chunk *
PCI_DMA_BIDIRECTIONAL);
for (i = 0; i < chunk->npages; ++i)
- __free_pages(chunk->mem[i].page,
+ __free_pages(sg_page(&chunk->mem[i]),
get_order(chunk->mem[i].length));
}
@@ -81,7 +81,7 @@ static void mthca_free_icm_coherent(struct mthca_dev *dev, struct mthca_icm_chun
for (i = 0; i < chunk->npages; ++i) {
dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
- lowmem_page_address(chunk->mem[i].page),
+ lowmem_page_address(sg_page(&chunk->mem[i])),
sg_dma_address(&chunk->mem[i]));
}
}
@@ -107,10 +107,13 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm, int coherent)
static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
{
- mem->page = alloc_pages(gfp_mask, order);
- if (!mem->page)
+ struct page *page;
+
+ page = alloc_pages(gfp_mask, order);
+ if (!page)
return -ENOMEM;
+ sg_set_page(mem, page);
mem->length = PAGE_SIZE << order;
mem->offset = 0;
return 0;
@@ -157,6 +160,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
if (!chunk)
goto fail;
+ sg_init_table(chunk->mem, MTHCA_ICM_CHUNK_LEN);
chunk->npages = 0;
chunk->nsg = 0;
list_add_tail(&chunk->list, &icm->chunk_list);
@@ -304,7 +308,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj, dma_addr_t *dma_h
* so if we found the page, dma_handle has already
* been assigned to. */
if (chunk->mem[i].length > offset) {
- page = chunk->mem[i].page;
+ page = sg_page(&chunk->mem[i]);
goto out;
}
offset -= chunk->mem[i].length;
@@ -445,6 +449,7 @@ static u64 mthca_uarc_virt(struct mthca_dev *dev, struct mthca_uar *uar, int pag
int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
struct mthca_user_db_table *db_tab, int index, u64 uaddr)
{
+ struct page *pages[1];
int ret = 0;
u8 status;
int i;
@@ -472,16 +477,17 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
}
ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
- &db_tab->page[i].mem.page, NULL);
+ pages, NULL);
if (ret < 0)
goto out;
+ sg_set_page(&db_tab->page[i].mem, pages[0]);
db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
if (ret < 0) {
- put_page(db_tab->page[i].mem.page);
+ put_page(pages[0]);
goto out;
}
@@ -491,7 +497,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
ret = -EINVAL;
if (ret) {
pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
- put_page(db_tab->page[i].mem.page);
+ put_page(sg_page(&db_tab->page[i].mem));
goto out;
}
@@ -557,7 +563,7 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
if (db_tab->page[i].uvirt) {
mthca_UNMAP_ICM(dev, mthca_uarc_virt(dev, uar, i), 1, &status);
pci_unmap_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
- put_page(db_tab->page[i].mem.page);
+ put_page(sg_page(&db_tab->page[i].mem));
}
}
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index f3529b6f0a3..d6879806179 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -131,7 +131,7 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
p = mem;
for_each_sg(sgl, sg, data->size, i) {
- from = kmap_atomic(sg->page, KM_USER0);
+ from = kmap_atomic(sg_page(sg), KM_USER0);
memcpy(p,
from + sg->offset,
sg->length);
@@ -191,7 +191,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
p = mem;
for_each_sg(sgl, sg, sg_size, i) {
- to = kmap_atomic(sg->page, KM_SOFTIRQ0);
+ to = kmap_atomic(sg_page(sg), KM_SOFTIRQ0);
memcpy(to + sg->offset,
p,
sg->length);
@@ -300,7 +300,7 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
for_each_sg(sgl, sg, data->dma_nents, i) {
/* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
"offset: %ld sz: %ld\n", i,
- (unsigned long)page_to_phys(sg->page),
+ (unsigned long)sg_phys(sg),
(unsigned long)sg->offset,
(unsigned long)sg->length); */
end_addr = ib_sg_dma_address(ibdev, sg) +
@@ -336,7 +336,7 @@ static void iser_data_buf_dump(struct iser_data_buf *data,
iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
"off:0x%x sz:0x%x dma_len:0x%x\n",
i, (unsigned long)ib_sg_dma_address(ibdev, sg),
- sg->page, sg->offset,
+ sg_page(sg), sg->offset,
sg->length, ib_sg_dma_len(ibdev, sg));
}
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1d62c8b88e1..e5b4e9bfbdc 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -495,7 +495,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait)
#ifdef CONFIG_COMPAT
#define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)
-#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
+#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1)
#ifdef __BIG_ENDIAN
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
@@ -504,7 +504,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
int len, i;
if (compat) {
- len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t);
+ len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
if (len > maxlen)
len = maxlen;
@@ -515,7 +515,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
sizeof(compat_long_t)))
return -EFAULT;
} else {
- len = NBITS(maxbit) * sizeof(long);
+ len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
@@ -530,8 +530,8 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p, int compat)
{
int len = compat ?
- NBITS_COMPAT(maxbit) * sizeof(compat_long_t) :
- NBITS(maxbit) * sizeof(long);
+ BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) :
+ BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
@@ -545,7 +545,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit,
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p, int compat)
{
- int len = NBITS(maxbit) * sizeof(long);
+ int len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
diff --git a/drivers/input/fixp-arith.h b/drivers/input/fixp-arith.h
index ed3d2da0c48..3089d738232 100644
--- a/drivers/input/fixp-arith.h
+++ b/drivers/input/fixp-arith.h
@@ -24,7 +24,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Should you need to contact me, the author, you can do so by
- * e-mail - mail your message to <deneux@ifrance.com>
+ * e-mail - mail your message to <johann.deneux@gmail.com>
*/
#include <linux/types.h>
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index ec1b6cfefcd..bfc6061f155 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -136,7 +136,8 @@ static int gameport_measure_speed(struct gameport *gameport)
}
gameport_close(gameport);
- return (cpu_data[raw_smp_processor_id()].loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
+ return (cpu_data(raw_smp_processor_id()).loops_per_jiffy *
+ (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx);
#else
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 2f2b020cd62..307c7b5c2b3 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -584,10 +584,10 @@ static int input_default_setkeycode(struct input_dev *dev,
#define MATCH_BIT(bit, max) \
- for (i = 0; i < NBITS(max); i++) \
+ for (i = 0; i < BITS_TO_LONGS(max); i++) \
if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
break; \
- if (i != NBITS(max)) \
+ if (i != BITS_TO_LONGS(max)) \
continue;
static const struct input_device_id *input_match_device(const struct input_device_id *id,
@@ -698,7 +698,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name,
{
int i;
- for (i = NBITS(max) - 1; i > 0; i--)
+ for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
if (bitmap[i])
break;
@@ -892,7 +892,7 @@ static int input_print_modalias_bits(char *buf, int size,
len += snprintf(buf, max(size, 0), "%c", name);
for (i = min_bit; i < max_bit; i++)
- if (bm[LONG(i)] & BIT(i))
+ if (bm[BIT_WORD(i)] & BIT_MASK(i))
len += snprintf(buf + len, max(size - len, 0), "%X,", i);
return len;
}
@@ -991,7 +991,7 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
int i;
int len = 0;
- for (i = NBITS(max) - 1; i > 0; i--)
+ for (i = BITS_TO_LONGS(max) - 1; i > 0; i--)
if (bitmap[i])
break;
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 2b201f9aa02..22b2789ef58 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -844,8 +844,8 @@ static const struct input_device_id joydev_blacklist[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT,
- .evbit = { BIT(EV_KEY) },
- .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
}, /* Avoid itouchpads, touchscreens and tablets */
{ } /* Terminating entry */
};
@@ -854,20 +854,20 @@ static const struct input_device_id joydev_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_ABS) },
- .absbit = { BIT(ABS_X) },
+ .evbit = { BIT_MASK(EV_ABS) },
+ .absbit = { BIT_MASK(ABS_X) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_ABS) },
- .absbit = { BIT(ABS_WHEEL) },
+ .evbit = { BIT_MASK(EV_ABS) },
+ .absbit = { BIT_MASK(ABS_WHEEL) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_ABS) },
- .absbit = { BIT(ABS_THROTTLE) },
+ .evbit = { BIT_MASK(EV_ABS) },
+ .absbit = { BIT_MASK(ABS_THROTTLE) },
},
{ } /* Terminating entry */
};
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index ff701ab10d7..52ba16f487c 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -326,14 +326,19 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
a3d->length = 33;
- input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
- input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
- input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER)
- | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y);
- input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE)
- | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP)
- | BIT(BTN_PINKIE);
+ input_dev->evbit[0] |= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) |
+ BIT_MASK(EV_REL);
+ input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_THROTTLE) | BIT_MASK(ABS_RUDDER) |
+ BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
+ BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+ BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) |
+ BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+ input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] |=
+ BIT_MASK(BTN_TRIGGER) | BIT_MASK(BTN_THUMB) |
+ BIT_MASK(BTN_TOP) | BIT_MASK(BTN_PINKIE);
a3d_read(a3d, data);
@@ -348,9 +353,10 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
} else {
a3d->length = 29;
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL);
- input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y);
- input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE);
+ input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
+ BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE);
a3d_read(a3d, data);
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index 28140c4a110..d1ca8a14950 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -431,7 +431,7 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
input_dev->open = adi_open;
input_dev->close = adi_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
set_bit(adi->abs[i], input_dev->absbit);
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index b0f5541ec3e..5cf9f3610e6 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -137,9 +137,10 @@ static int __init amijoy_init(void)
amijoy_dev[i]->open = amijoy_open;
amijoy_dev[i]->close = amijoy_close;
- amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ amijoy_dev[i]->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ amijoy_dev[i]->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+ amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
for (j = 0; j < 2; j++) {
amijoy_dev[i]->absmin[ABS_X + j] = -1;
amijoy_dev[i]->absmax[ABS_X + j] = 1;
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index bdd157c1ebf..15739880afc 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -456,7 +456,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i
input_dev->open = analog_open;
input_dev->close = analog_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = j = 0; i < 4; i++)
if (analog->mask & (1 << i)) {
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index d3352a849b8..55646a6d89f 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -218,7 +218,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
input_dev->open = cobra_open;
input_dev->close = cobra_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
for (j = 0; cobra_btn[j]; j++)
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index b069ee18e35..a6ca9d5e252 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -4,7 +4,7 @@
* Copyright (c) 1999-2001 Vojtech Pavlik
*
* Based on the work of:
- * Andree Borrmann Mats Sjvall
+ * Andree Borrmann Mats Sjövall
*/
/*
@@ -631,7 +631,7 @@ static struct db9 __init *db9_probe(int parport, int mode)
input_dev->open = db9_open;
input_dev->close = db9_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (j = 0; j < db9_mode->n_buttons; j++)
set_bit(db9_mode->buttons[j], input_dev->keybit);
for (j = 0; j < db9_mode->n_axis; j++) {
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 1a452e0e5f2..df2a9d02ca6 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -653,12 +653,12 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
input_dev->close = gc_close;
if (pad_type != GC_SNESMOUSE) {
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < 2; i++)
input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
} else
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
gc->pads[0] |= gc_status_bit[idx];
gc->pads[pad_type] |= gc_status_bit[idx];
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index d514aebf755..1f6302c0eb3 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -315,7 +315,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
input_dev->open = gf2k_open;
input_dev->close = gf2k_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < gf2k_axes[gf2k->id]; i++)
set_bit(gf2k_abs[i], input_dev->absbit);
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 73eb5ab6f14..fd3853ab1aa 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -370,7 +370,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
input_dev->open = grip_open;
input_dev->close = grip_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 4ed3a3eadf1..c57e21d68c0 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -606,7 +606,7 @@ static int register_slot(int slot, struct grip_mp *grip)
input_dev->open = grip_open;
input_dev->close = grip_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
input_set_abs_params(input_dev, t, -1, 1, 0, 0);
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index d4e8073caf2..aa6bfb3fb8c 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -238,7 +238,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
input_dev->open = guillemot_open;
input_dev->close = guillemot_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
input_set_abs_params(input_dev, t, 0, 255, 0, 0);
diff --git a/drivers/input/joystick/iforce/Makefile b/drivers/input/joystick/iforce/Makefile
index 17ae42bf9ff..74daff49ab6 100644
--- a/drivers/input/joystick/iforce/Makefile
+++ b/drivers/input/joystick/iforce/Makefile
@@ -1,7 +1,7 @@
#
# Makefile for the I-Force driver
#
-# By Johann Deneux <deneux@ifrance.com>
+# By Johann Deneux <johann.deneux@gmail.com>
#
# Goal definition
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 682244b1c04..6f826b37d9a 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -389,7 +389,8 @@ int iforce_init_device(struct iforce *iforce)
* Set input device bitfields and ranges.
*/
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+ BIT_MASK(EV_FF_STATUS);
for (i = 0; iforce->type->btn[i] >= 0; i++)
set_bit(iforce->type->btn[i], input_dev->keybit);
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index 40a853ac21c..a964a7cfd21 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -62,13 +62,13 @@
#define FF_CORE_IS_PLAYED 3 /* Effect is currently being played */
#define FF_CORE_SHOULD_PLAY 4 /* User wants the effect to be played */
#define FF_CORE_UPDATE 5 /* Effect is being updated */
-#define FF_MODCORE_MAX 5
+#define FF_MODCORE_CNT 6
struct iforce_core_effect {
/* Information about where modifiers are stored in the device's memory */
struct resource mod1_chunk;
struct resource mod2_chunk;
- unsigned long flags[NBITS(FF_MODCORE_MAX)];
+ unsigned long flags[BITS_TO_LONGS(FF_MODCORE_CNT)];
};
#define FF_CMD_EFFECT 0x010e
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 1aec1e9d7c5..bc8ea95dfd0 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -269,7 +269,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
input_dev->open = interact_open;
input_dev->close = interact_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
set_bit(t, input_dev->absbit);
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
index b35604ee43a..54e676948eb 100644
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -170,7 +170,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < 9; i++)
set_bit(magellan_buttons[i], input_dev->keybit);
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 2adf73f63c9..7b4865fdee5 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -758,7 +758,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
input_dev->open = sw_open;
input_dev->close = sw_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
code = sw_abs[sw->type][j];
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
index abb7c4cf54a..d4087fd4965 100644
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -228,18 +228,23 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
switch (id) {
case SPACEBALL_4000FLX:
case SPACEBALL_4000FLX_L:
- input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
- input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+ input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_9);
+ input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) |
+ BIT_MASK(BTN_B) | BIT_MASK(BTN_C) |
+ BIT_MASK(BTN_MODE);
default:
- input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
- | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
+ input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) |
+ BIT_MASK(BTN_3) | BIT_MASK(BTN_4) |
+ BIT_MASK(BTN_5) | BIT_MASK(BTN_6) |
+ BIT_MASK(BTN_7) | BIT_MASK(BTN_8);
case SPACEBALL_3003C:
- input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+ input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) |
+ BIT_MASK(BTN_8);
}
for (i = 0; i < 3; i++) {
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index c4937f1e837..f7ce4004f4b 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -185,7 +185,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < 6; i++)
set_bit(spaceorb_buttons[i], input_dev->keybit);
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
index 8581ee991d4..baa10b2f7ba 100644
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -156,10 +156,11 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
- BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
- BIT(BTN_START) | BIT(BTN_SELECT);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_A)] = BIT_MASK(BTN_A) | BIT_MASK(BTN_B) |
+ BIT_MASK(BTN_C) | BIT_MASK(BTN_X) | BIT_MASK(BTN_Y) |
+ BIT_MASK(BTN_Z) | BIT_MASK(BTN_TL) | BIT_MASK(BTN_TR) |
+ BIT_MASK(BTN_START) | BIT_MASK(BTN_SELECT);
input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 3b36ee04f72..0feeb8acb53 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -333,7 +333,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
input_dev->open = tmdc_open;
input_dev->close = tmdc_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
for (i = 0; i < port->absc && i < TMDC_ABS; i++)
if (port->abs[i] >= 0)
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 8381c6f1437..bbebd4e2ad7 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -229,7 +229,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
input_dev->open = tgfx_open;
input_dev->close = tgfx_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index c91504ec38e..1085c841fec 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -207,7 +207,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index 4e85f72eefd..e928b6e3724 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -162,9 +162,11 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
- input_dev->relbit[0] = BIT(REL_DIAL);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+ BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TRIGGER)] = BIT_MASK(BTN_TRIGGER) |
+ BIT_MASK(BTN_THUMB) | BIT_MASK(BTN_TOP) | BIT_MASK(BTN_TOP2);
+ input_dev->relbit[0] = BIT_MASK(REL_DIAL);
input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 623629a69b0..6dd375825a1 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -658,7 +658,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
input_dev->open = xpad_open;
input_dev->close = xpad_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
/* set up buttons */
for (i = 0; xpad_btn[i] >= 0; i++)
diff --git a/drivers/input/keyboard/aaed2000_kbd.c b/drivers/input/keyboard/aaed2000_kbd.c
index 63d6ead6b87..72abc196ce6 100644
--- a/drivers/input/keyboard/aaed2000_kbd.c
+++ b/drivers/input/keyboard/aaed2000_kbd.c
@@ -125,7 +125,7 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = aaedkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode);
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index c67e84ec2d6..81bf7562aca 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -209,7 +209,7 @@ static int __init amikbd_init(void)
amikbd_dev->id.product = 0x0001;
amikbd_dev->id.version = 0x0100;
- amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
for (i = 0; i < 0x78; i++)
set_bit(i, amikbd_dev->keybit);
diff --git a/drivers/input/keyboard/atakbd.c b/drivers/input/keyboard/atakbd.c
index a1800151b6c..4e92100c56a 100644
--- a/drivers/input/keyboard/atakbd.c
+++ b/drivers/input/keyboard/atakbd.c
@@ -237,7 +237,7 @@ static int __init atakbd_init(void)
atakbd_dev->id.product = 0x0001;
atakbd_dev->id.version = 0x0100;
- atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ atakbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
atakbd_dev->keycode = atakbd_keycode;
atakbd_dev->keycodesize = sizeof(unsigned char);
atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 41fc3d03b6e..b39c5b31e62 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -900,27 +900,32 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd)
input_set_drvdata(input_dev, atkbd);
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+ BIT_MASK(EV_MSC);
if (atkbd->write) {
- input_dev->evbit[0] |= BIT(EV_LED);
- input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ input_dev->evbit[0] |= BIT_MASK(EV_LED);
+ input_dev->ledbit[0] = BIT_MASK(LED_NUML) |
+ BIT_MASK(LED_CAPSL) | BIT_MASK(LED_SCROLLL);
}
if (atkbd->extra)
- input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
- BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
+ input_dev->ledbit[0] |= BIT_MASK(LED_COMPOSE) |
+ BIT_MASK(LED_SUSPEND) | BIT_MASK(LED_SLEEP) |
+ BIT_MASK(LED_MUTE) | BIT_MASK(LED_MISC);
if (!atkbd->softrepeat) {
input_dev->rep[REP_DELAY] = 250;
input_dev->rep[REP_PERIOD] = 33;
}
- input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+ input_dev->mscbit[0] = atkbd->softraw ? BIT_MASK(MSC_SCAN) :
+ BIT_MASK(MSC_RAW) | BIT_MASK(MSC_SCAN);
if (atkbd->scroll) {
- input_dev->evbit[0] |= BIT(EV_REL);
- input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+ input_dev->evbit[0] |= BIT_MASK(EV_REL);
+ input_dev->relbit[0] = BIT_MASK(REL_WHEEL) |
+ BIT_MASK(REL_HWHEEL);
set_bit(BTN_MIDDLE, input_dev->keybit);
}
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index a67b29b089e..e5f4da92834 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -256,7 +256,6 @@ static int __devinit bfin_kpad_probe(struct platform_device *pdev)
printk(KERN_ERR DRV_NAME
": unable to claim irq %d; error %d\n",
bf54x_kpad->irq, error);
- error = -EBUSY;
goto out2;
}
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index 6578bfff644..790fed368aa 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -325,7 +325,8 @@ static int __init corgikbd_probe(struct platform_device *pdev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+ BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
input_dev->keycode = corgikbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e2a3293bc67..3eddf52a0bb 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -62,7 +62,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, input);
- input->evbit[0] = BIT(EV_KEY);
+ input->evbit[0] = BIT_MASK(EV_KEY);
input->name = pdev->name;
input->phys = "gpio-keys/input0";
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c
index cdd254f2e6c..adbf29f0169 100644
--- a/drivers/input/keyboard/hil_kbd.c
+++ b/drivers/input/keyboard/hil_kbd.c
@@ -323,8 +323,9 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
goto bail2;
}
- kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ kbd->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ kbd->dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+ BIT_MASK(LED_SCROLLL);
kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]);
kbd->dev->keycode = hil_kbd_set1;
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 499b6974457..50d80ecf0b8 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -266,8 +266,9 @@ hil_keyb_init(void)
if (hphilkeyb_keycode[i] != KEY_RESERVED)
set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
- hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
- hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+ hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+ hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
+ BIT_MASK(LED_SCROLLL);
hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
hil_dev.dev->keycode = hphilkeyb_keycode;
diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c
index 7a41b271f22..5a0ca18d675 100644
--- a/drivers/input/keyboard/locomokbd.c
+++ b/drivers/input/keyboard/locomokbd.c
@@ -233,7 +233,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &dev->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = locomokbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode);
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
index b97a41e3ee5..48d1cab0aa1 100644
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -106,7 +106,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = nkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 76f1969552c..babc913d549 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -4,7 +4,7 @@
* OMAP Keypad Driver
*
* Copyright (C) 2003 Nokia Corporation
- * Written by Timo Ters <ext-timo.teras@nokia.com>
+ * Written by Timo Teräs <ext-timo.teras@nokia.com>
*
* Added support for H2 & H3 Keypad
* Copyright (C) 2004 Texas Instruments
@@ -481,6 +481,6 @@ static void __exit omap_kp_exit(void)
module_init(omap_kp_init);
module_exit(omap_kp_exit);
-MODULE_AUTHOR("Timo Ters");
+MODULE_AUTHOR("Timo Teräs");
MODULE_DESCRIPTION("OMAP Keypad Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/keyboard/pxa27x_keyboard.c b/drivers/input/keyboard/pxa27x_keyboard.c
index b7061aa3881..bdd64ee4c5c 100644
--- a/drivers/input/keyboard/pxa27x_keyboard.c
+++ b/drivers/input/keyboard/pxa27x_keyboard.c
@@ -183,8 +183,9 @@ static int __devinit pxakbd_probe(struct platform_device *pdev)
input_dev->close = pxakbd_close;
input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
- input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+ BIT_MASK(EV_REL);
+ input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL);
for (row = 0; row < pdata->nr_rows; row++) {
for (col = 0; col < pdata->nr_cols; col++) {
int code = pdata->keycodes[row][col];
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 41b80385476..410d78a774d 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -381,7 +381,8 @@ static int __init spitzkbd_probe(struct platform_device *dev)
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) |
+ BIT_MASK(EV_PWR) | BIT_MASK(EV_SW);
input_dev->keycode = spitzkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c
index b44b0684d54..7437219370b 100644
--- a/drivers/input/keyboard/stowaway.c
+++ b/drivers/input/keyboard/stowaway.c
@@ -110,7 +110,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = skbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(skbd_keycode);
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 1d4e39624cf..be0f5d19d02 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -277,9 +277,11 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
input_dev->event = sunkbd_event;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
- input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
- input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+ BIT_MASK(EV_SND) | BIT_MASK(EV_REP);
+ input_dev->ledbit[0] = BIT_MASK(LED_CAPSL) | BIT_MASK(LED_COMPOSE) |
+ BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML);
+ input_dev->sndbit[0] = BIT_MASK(SND_CLICK) | BIT_MASK(SND_BELL);
input_dev->keycode = sunkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
index f3a56eb58ed..152a2c07050 100644
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -110,7 +110,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
input_dev->keycode = xtkbd->keycode;
input_dev->keycodesize = sizeof(unsigned char);
input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 7acc6351bb4..8f5c7b90187 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -70,9 +70,9 @@ config INPUT_WISTRON_BTNS
select LEDS_CLASS
select CHECK_SIGNATURE
help
- Say Y here for support of Winstron laptop button interface, used on
+ Say Y here for support of Wistron laptop button interfaces, used on
laptops of various brands, including Acer and Fujitsu-Siemens. If
- available, mail and wifi leds will be controlable via /sys/class/leds.
+ available, mail and wifi LEDs will be controllable via /sys/class/leds.
To compile this driver as a module, choose M here: the module will
be called wistron_btns.
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index 471aab20644..3a7937481ad 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -662,10 +662,10 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
struct input_dev *idev = ati_remote->idev;
int i;
- idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) |
- BIT(BTN_SIDE) | BIT(BTN_EXTRA) );
- idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+ idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++)
if (ati_remote_tbl[i].type == EV_KEY)
set_bit(ati_remote_tbl[i].code, idev->keybit);
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index 1031543e5c3..f2709b82485 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -346,9 +346,10 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
ar2->idev = idev;
input_set_drvdata(idev, ar2);
- idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL);
- idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
- idev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);
+ idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT);
+ idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
set_bit(ati_remote2_key_table[i].key_code, idev->keybit);
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c
index e43e92fd9e2..4e3ad657ed8 100644
--- a/drivers/input/misc/atlas_btns.c
+++ b/drivers/input/misc/atlas_btns.c
@@ -81,7 +81,7 @@ static int atlas_acpi_button_add(struct acpi_device *device)
input_dev->name = "Atlas ACPI button driver";
input_dev->phys = "ASIM0000/atlas/input0";
input_dev->id.bustype = BUS_HOST;
- input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY);
+ input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY);
set_bit(KEY_F1, input_dev->keybit);
set_bit(KEY_F2, input_dev->keybit);
diff --git a/drivers/input/misc/cobalt_btns.c b/drivers/input/misc/cobalt_btns.c
index 064b0793601..1aef97ed5e8 100644
--- a/drivers/input/misc/cobalt_btns.c
+++ b/drivers/input/misc/cobalt_btns.c
@@ -104,7 +104,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev)
input->id.bustype = BUS_HOST;
input->cdev.dev = &pdev->dev;
- input->evbit[0] = BIT(EV_KEY);
+ input->evbit[0] = BIT_MASK(EV_KEY);
for (i = 0; i < ARRAY_SIZE(buttons_map); i++) {
set_bit(buttons_map[i].keycode, input->keybit);
buttons_map[i].count = 0;
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index e759944041a..d2ade7443b7 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -109,8 +109,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &dev->dev;
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ input_dev->evbit[0] = BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
input_dev->event = ixp4xx_spkr_event;
err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c
index 1bffc9fa98c..fd74347047d 100644
--- a/drivers/input/misc/keyspan_remote.c
+++ b/drivers/input/misc/keyspan_remote.c
@@ -497,7 +497,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
usb_to_input_id(udev, &input_dev->id);
input_dev->dev.parent = &interface->dev;
- input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */
+ input_dev->evbit[0] = BIT_MASK(EV_KEY); /* We will only report KEY events. */
for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
if (keyspan_key_table[i] != KEY_RESERVED)
set_bit(keyspan_key_table[i], input_dev->keybit);
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index e9f26e766b4..0c64d9bb718 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -65,8 +65,8 @@ static int __devinit m68kspkr_probe(struct platform_device *dev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &dev->dev;
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ input_dev->evbit[0] = BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
input_dev->event = m68kspkr_event;
err = input_register_device(input_dev);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index c19f77fbaf2..4941a9e61e9 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -86,8 +86,8 @@ static int __devinit pcspkr_probe(struct platform_device *dev)
pcspkr_dev->id.version = 0x0100;
pcspkr_dev->dev.parent = &dev->dev;
- pcspkr_dev->evbit[0] = BIT(EV_SND);
- pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ pcspkr_dev->evbit[0] = BIT_MASK(EV_SND);
+ pcspkr_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
pcspkr_dev->event = pcspkr_event;
err = input_register_device(pcspkr_dev);
diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c
index 448a470d28f..7a7b8c7b963 100644
--- a/drivers/input/misc/powermate.c
+++ b/drivers/input/misc/powermate.c
@@ -363,10 +363,11 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
input_dev->event = powermate_input_event;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
- input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
- input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
- input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) |
+ BIT_MASK(EV_MSC);
+ input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+ input_dev->relbit[BIT_WORD(REL_DIAL)] = BIT_MASK(REL_DIAL);
+ input_dev->mscbit[BIT_WORD(MSC_PULSELED)] = BIT_MASK(MSC_PULSELED);
/* get a handle to the interrupt data pipe */
pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index e36ec1d92be..a3637d87088 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -115,8 +115,8 @@ static int __devinit sparcspkr_probe(struct device *dev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = dev;
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ input_dev->evbit[0] = BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
input_dev->event = state->event;
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index ab15880fd56..46279ef2b64 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -945,7 +945,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* input_dev->event = input_ev; TODO */
/* register available key events */
- input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
for (i = 0; i < 256; i++) {
int k = map_p1k_to_key(i);
if (k >= 0) {
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 64d70a9b714..2b5ed119c9a 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -455,24 +455,25 @@ int alps_init(struct psmouse *psmouse)
if (alps_hw_init(psmouse, &version))
goto init_fail;
- dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
- dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
- dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
- dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY);
+ dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH);
+ dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER);
+ dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
- dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+ dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS);
input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
if (priv->i->flags & ALPS_WHEEL) {
- dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
- dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+ dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL);
+ dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL);
}
if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
- dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
- dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+ dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD);
+ dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK);
}
snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys);
@@ -483,9 +484,10 @@ int alps_init(struct psmouse *psmouse)
dev2->id.product = PSMOUSE_ALPS;
dev2->id.version = 0x0000;
- dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
- dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
if (input_register_device(priv->dev2))
goto init_fail;
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index 239a0e16d91..a185ac78a42 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -111,9 +111,10 @@ static int __init amimouse_init(void)
amimouse_dev->id.product = 0x0002;
amimouse_dev->id.version = 0x0100;
- amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
amimouse_dev->open = amimouse_open;
amimouse_dev->close = amimouse_close;
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 0117817bf53..f132702d137 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -504,25 +504,22 @@ static void atp_complete(struct urb* urb)
memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
}
- /* Geyser 3 will continue to send packets continually after
+ input_report_key(dev->input, BTN_LEFT, key);
+ input_sync(dev->input);
+
+ /* Many Geysers will continue to send packets continually after
the first touch unless reinitialised. Do so if it's been
idle for a while in order to avoid waking the kernel up
several hundred times a second */
- if (atp_is_geyser_3(dev)) {
- if (!x && !y && !key) {
- dev->idlecount++;
- if (dev->idlecount == 10) {
- dev->valid = 0;
- schedule_work(&dev->work);
- }
+ if (!x && !y && !key) {
+ dev->idlecount++;
+ if (dev->idlecount == 10) {
+ dev->valid = 0;
+ schedule_work(&dev->work);
}
- else
- dev->idlecount = 0;
- }
-
- input_report_key(dev->input, BTN_LEFT, key);
- input_sync(dev->input);
+ } else
+ dev->idlecount = 0;
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
diff --git a/drivers/input/mouse/atarimouse.c b/drivers/input/mouse/atarimouse.c
index c8c7244b48a..98a3561d4b0 100644
--- a/drivers/input/mouse/atarimouse.c
+++ b/drivers/input/mouse/atarimouse.c
@@ -137,9 +137,10 @@ static int __init atamouse_init(void)
atamouse_dev->id.product = 0x0002;
atamouse_dev->id.version = 0x0100;
- atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+ atamouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
atamouse_dev->open = atamouse_open;
atamouse_dev->close = atamouse_close;
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c
index 449bf4dcbbc..27f88fbb713 100644
--- a/drivers/input/mouse/hil_ptr.c
+++ b/drivers/input/mouse/hil_ptr.c
@@ -298,12 +298,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
idd = ptr->idd + 1;
txt = "unknown";
if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
- ptr->dev->evbit[0] = BIT(EV_REL);
+ ptr->dev->evbit[0] = BIT_MASK(EV_REL);
txt = "relative";
}
if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
- ptr->dev->evbit[0] = BIT(EV_ABS);
+ ptr->dev->evbit[0] = BIT_MASK(EV_ABS);
txt = "absolute";
}
if (!ptr->dev->evbit[0])
@@ -311,7 +311,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
if (ptr->nbtn)
- ptr->dev->evbit[0] |= BIT(EV_KEY);
+ ptr->dev->evbit[0] |= BIT_MASK(EV_KEY);
naxsets = HIL_IDD_NUM_AXSETS(*idd);
ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 79b624fe899..655a3921743 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -163,9 +163,10 @@ static int __init inport_init(void)
inport_dev->id.product = 0x0001;
inport_dev->id.version = 0x0100;
- inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
inport_dev->open = inport_open;
inport_dev->close = inport_close;
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index d7de4c53b3d..9ec57d80186 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -270,9 +270,10 @@ static int lifebook_create_relative_device(struct psmouse *psmouse)
dev2->id.version = 0x0000;
dev2->dev.parent = &psmouse->ps2dev.serio->dev;
- dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y);
- dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+ dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT);
error = input_register_device(priv->dev2);
if (error)
@@ -295,9 +296,9 @@ int lifebook_init(struct psmouse *psmouse)
if (lifebook_absolute_mode(psmouse))
return -1;
- dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+ dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
dev1->relbit[0] = 0;
- dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0);
input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0);
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index 26c3b2e2ca9..b23a4f3ea5c 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -156,9 +156,10 @@ static int __init logibm_init(void)
logibm_dev->id.product = 0x0001;
logibm_dev->id.version = 0x0100;
- logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ logibm_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ logibm_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ logibm_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
logibm_dev->open = logibm_open;
logibm_dev->close = logibm_close;
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index 05d992e514f..8991ab0b4fe 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -144,9 +144,9 @@ static int __init pc110pad_init(void)
pc110pad_dev->id.product = 0x0001;
pc110pad_dev->id.version = 0x0100;
- pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
- pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ pc110pad_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y);
+ pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
pc110pad_dev->absmax[ABS_X] = 0x1ff;
pc110pad_dev->absmax[ABS_Y] = 0x0ff;
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index 07352575653..21a9c0b69a1 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -906,7 +906,7 @@ static void psmouse_activate(struct psmouse *psmouse)
/*
* psmouse_deactivate() puts the mouse into poll mode so that we don't get motion
- * reports from it unless we explicitely request it.
+ * reports from it unless we explicitly request it.
*/
static void psmouse_deactivate(struct psmouse *psmouse)
@@ -1115,9 +1115,10 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse
input_dev->dev.parent = &psmouse->ps2dev.serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
psmouse->set_rate = psmouse_set_rate;
psmouse->set_resolution = psmouse_set_resolution;
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 355efd0423e..18a48636ba4 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -78,9 +78,10 @@ static int __init rpcmouse_init(void)
rpcmouse_dev->id.product = 0x0001;
rpcmouse_dev->id.version = 0x0100;
- rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- rpcmouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ rpcmouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ rpcmouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ rpcmouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index 77b8ee2b965..ed917bfd086 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -268,9 +268,10 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c
index 7b977fd2357..3fadb2accac 100644
--- a/drivers/input/mouse/touchkit_ps2.c
+++ b/drivers/input/mouse/touchkit_ps2.c
@@ -85,7 +85,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties)
return -ENODEV;
if (set_properties) {
- dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+ dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
set_bit(BTN_TOUCH, dev->keybit);
input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0);
input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0);
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index 4a321576f34..404eedd5ffa 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -330,7 +330,7 @@ vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse)
/*
* Check for Power-On-Reset packets. These are sent out
- * after plugging the mouse in, or when explicitely
+ * after plugging the mouse in, or when explicitly
* requested by sending 'T'.
*
* [0]: 1 0 1 0 R3 R2 R1 R0
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 79146d6ed2a..78c3ea75da2 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -998,34 +998,36 @@ static const struct input_device_id mousedev_ids[] = {
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_RELBIT,
- .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
- .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) },
- .relbit = { BIT(REL_X) | BIT(REL_Y) },
+ .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+ .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) },
+ .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) },
}, /* A mouse like device, at least one button,
two relative axes */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_RELBIT,
- .evbit = { BIT(EV_KEY) | BIT(EV_REL) },
- .relbit = { BIT(REL_WHEEL) },
+ .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) },
+ .relbit = { BIT_MASK(REL_WHEEL) },
}, /* A separate scrollwheel */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
- .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) },
+ .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+ .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+ .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
}, /* A tablet like device, at least touch detection,
two absolute axes */
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
INPUT_DEVICE_ID_MATCH_KEYBIT |
INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT(EV_KEY) | BIT(EV_ABS) },
- .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) },
- .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) |
- BIT(ABS_TOOL_WIDTH) },
+ .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) },
+ .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] =
+ BIT_MASK(BTN_TOOL_FINGER) },
+ .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_PRESSURE) |
+ BIT_MASK(ABS_TOOL_WIDTH) },
}, /* A touchpad */
{ }, /* Terminating entry */
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 11dafc0ee99..1a0cea3c529 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -20,6 +20,7 @@
#include <linux/err.h>
#include <linux/rcupdate.h>
#include <linux/platform_device.h>
+#include <linux/i8042.h>
#include <asm/io.h>
@@ -208,7 +209,7 @@ static int __i8042_command(unsigned char *param, int command)
return 0;
}
-static int i8042_command(unsigned char *param, int command)
+int i8042_command(unsigned char *param, int command)
{
unsigned long flags;
int retval;
@@ -219,6 +220,7 @@ static int i8042_command(unsigned char *param, int command)
return retval;
}
+EXPORT_SYMBOL(i8042_command);
/*
* i8042_kbd_write() sends a byte out through the keyboard interface.
diff --git a/drivers/input/serio/i8042.h b/drivers/input/serio/i8042.h
index b3eb7a72d96..dd22d91f8b3 100644
--- a/drivers/input/serio/i8042.h
+++ b/drivers/input/serio/i8042.h
@@ -61,28 +61,6 @@
#define I8042_CTR_XLATE 0x40
/*
- * Commands.
- */
-
-#define I8042_CMD_CTL_RCTR 0x0120
-#define I8042_CMD_CTL_WCTR 0x1060
-#define I8042_CMD_CTL_TEST 0x01aa
-
-#define I8042_CMD_KBD_DISABLE 0x00ad
-#define I8042_CMD_KBD_ENABLE 0x00ae
-#define I8042_CMD_KBD_TEST 0x01ab
-#define I8042_CMD_KBD_LOOP 0x11d2
-
-#define I8042_CMD_AUX_DISABLE 0x00a7
-#define I8042_CMD_AUX_ENABLE 0x00a8
-#define I8042_CMD_AUX_TEST 0x01a9
-#define I8042_CMD_AUX_SEND 0x10d4
-#define I8042_CMD_AUX_LOOP 0x11d3
-
-#define I8042_CMD_MUX_PFX 0x0090
-#define I8042_CMD_MUX_SEND 0x1090
-
-/*
* Return codes.
*/
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index dd2310458c4..b973d0ef6d1 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -192,10 +192,14 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
input_dev->open = usb_acecad_open;
input_dev->close = usb_acecad_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
- input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_PRESSURE);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) |
+ BIT_MASK(BTN_STYLUS2);
switch (id->driver_info) {
case 0:
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index b2ca10f2fe0..d2c6da26472 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -573,10 +573,12 @@ static void gtco_setup_caps(struct input_dev *inputdev)
struct gtco *device = input_get_drvdata(inputdev);
/* Which events */
- inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+ inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+ BIT_MASK(EV_MSC);
/* Misc event menu block */
- inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ;
+ inputdev->mscbit[0] = BIT_MASK(MSC_SCAN) | BIT_MASK(MSC_SERIAL) |
+ BIT_MASK(MSC_RAW);
/* Absolute values based on HID report info */
input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X,
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index 91e6d00d4a4..1182fc13316 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -153,10 +153,13 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
input_dev->open = kbtab_open;
input_dev->close = kbtab_close;
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+ input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+ BIT_MASK(EV_MSC);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_TOUCH);
+ input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 064e123c9b7..d64b1ea136b 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -140,48 +140,58 @@ static void wacom_close(struct input_dev *dev)
void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) |
+ BIT_MASK(BTN_5);
input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
}
void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->evbit[0] |= BIT(EV_MSC);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4);
+ input_dev->evbit[0] |= BIT_MASK(EV_MSC);
+ input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+ BIT_MASK(BTN_4);
}
void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->evbit[0] |= BIT(EV_REL);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+ input_dev->evbit[0] |= BIT_MASK(EV_REL);
+ input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
}
void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+ BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
}
void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) |
+ BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
}
void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
- input_dev->mscbit[0] |= BIT(MSC_SERIAL);
- input_dev->relbit[0] |= BIT(REL_WHEEL);
- input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH)
- | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
+ input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
+ input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
+ input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
+ input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
+ BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
+ BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) |
+ BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) |
+ BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2);
input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0);
input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
@@ -192,12 +202,13 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) |
+ BIT_MASK(BTN_TOOL_RUBBER);
}
void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
{
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
}
static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -243,12 +254,13 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
input_dev->open = wacom_open;
input_dev->close = wacom_close;
- input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+ input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
+ BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
- input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC);
+ input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
wacom_init_input_dev(input_dev, wacom_wac);
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index e3e0baa1a15..fa8442b6241 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -202,6 +202,7 @@ config TOUCHSCREEN_USB_COMPOSITE
- DMC TSC-10/25
- IRTOUCHSYSTEMS/UNITOP
- IdealTEK URTC1000
+ - GoTop Super_Q2/GogoPen/PenPower tablets
Have a look at <http://linux.chapter7.ch/touchkit/> for
a usage description and the required user-space stuff.
@@ -259,4 +260,9 @@ config TOUCHSCREEN_USB_GENERAL_TOUCH
bool "GeneralTouch Touchscreen device support" if EMBEDDED
depends on TOUCHSCREEN_USB_COMPOSITE
+config TOUCHSCREEN_USB_GOTOP
+ default y
+ bool "GoTop Super_Q2/GogoPen/PenPower tablet device support" if EMBEDDED
+ depends on TOUCHSCREEN_USB_COMPOSITE
+
endif
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 51ae4fb7d12..f59aecf5ec1 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -917,8 +917,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
input_dev->phys = ts->phys;
input_dev->dev.parent = &spi->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X,
pdata->x_min ? : 0,
pdata->x_max ? : MAX_12BIT,
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index e6a31d11878..b1b2e07bf08 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -302,8 +302,8 @@ static int __init corgits_probe(struct platform_device *pdev)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 557d781719f..d20689cdbd5 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -320,8 +320,8 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
serio_set_drvdata(serio, elo);
err = serio_open(serio, drv);
diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c
index daf7a4afc93..80b21800355 100644
--- a/drivers/input/touchscreen/fujitsu_ts.c
+++ b/drivers/input/touchscreen/fujitsu_ts.c
@@ -122,8 +122,8 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.vendor = SERIO_FUJITSU;
input_dev->id.product = 0;
input_dev->id.version = 0x0100;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0);
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 39d602600d7..a48a15868c4 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -137,8 +137,8 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.product = 0x0051;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index 09ed7803cb8..2ae6c6016a8 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -373,8 +373,9 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
input_dev->event = h3600ts_event;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
- input_dev->ledbit[0] = BIT(LED_SLEEP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) |
+ BIT_MASK(EV_LED) | BIT_MASK(EV_PWR);
+ input_dev->ledbit[0] = BIT_MASK(LED_SLEEP);
input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 1a15475aedf..c38d4e0f95c 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -81,8 +81,8 @@ static int __init hp680_ts_init(void)
if (!hp680_ts_dev)
return -ENOMEM;
- hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
- hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
+ hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(hp680_ts_dev, ABS_X,
HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0);
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index 44140feeffc..80a65886870 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -186,8 +186,8 @@ static int __init mk712_init(void)
mk712_dev->open = mk712_open;
mk712_dev->close = mk712_close;
- mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ mk712_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ mk712_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index 4ec3b1f940c..9077228418b 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -151,8 +151,8 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.product = 0;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index f2c0d3c7149..c7f9cebebbb 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -113,8 +113,8 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0);
input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0);
diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c
index 3def7bb1df4..3a5c142c2a7 100644
--- a/drivers/input/touchscreen/touchright.c
+++ b/drivers/input/touchscreen/touchright.c
@@ -125,8 +125,8 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.product = 0;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0);
input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0);
diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c
index ac4bdcf1866..763a656a59f 100644
--- a/drivers/input/touchscreen/touchwin.c
+++ b/drivers/input/touchscreen/touchwin.c
@@ -132,8 +132,8 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv)
input_dev->id.product = 0;
input_dev->id.version = 0x0100;
input_dev->dev.parent = &serio->dev;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0);
input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0);
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 89373b01d8f..7549939b953 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -517,7 +517,7 @@ static int ucb1400_ts_probe(struct device *dev)
idev->id.product = id;
idev->open = ucb1400_ts_open;
idev->close = ucb1400_ts_close;
- idev->evbit[0] = BIT(EV_ABS);
+ idev->evbit[0] = BIT_MASK(EV_ABS);
ucb1400_adc_enable(ucb);
x_res = ucb1400_ts_read_xres(ucb);
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 9fb3d5c3099..19055e7381f 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -11,8 +11,9 @@
* - DMC TSC-10/25
* - IRTOUCHSYSTEMS/UNITOP
* - IdealTEK URTC1000
+ * - GoTop Super_Q2/GogoPen/PenPower tablets
*
- * Copyright (C) 2004-2006 by Daniel Ritz <daniel.ritz@gmx.ch>
+ * Copyright (C) 2004-2007 by Daniel Ritz <daniel.ritz@gmx.ch>
* Copyright (C) by Todd E. Johnson (mtouchusb.c)
*
* This program is free software; you can redistribute it and/or
@@ -115,6 +116,7 @@ enum {
DEVTYPE_IRTOUCH,
DEVTYPE_IDEALTEK,
DEVTYPE_GENERAL_TOUCH,
+ DEVTYPE_GOTOP,
};
static struct usb_device_id usbtouch_devices[] = {
@@ -168,6 +170,12 @@ static struct usb_device_id usbtouch_devices[] = {
{USB_DEVICE(0x0dfc, 0x0001), .driver_info = DEVTYPE_GENERAL_TOUCH},
#endif
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+ {USB_DEVICE(0x08f2, 0x007f), .driver_info = DEVTYPE_GOTOP},
+ {USB_DEVICE(0x08f2, 0x00ce), .driver_info = DEVTYPE_GOTOP},
+ {USB_DEVICE(0x08f2, 0x00f4), .driver_info = DEVTYPE_GOTOP},
+#endif
+
{}
};
@@ -501,6 +509,20 @@ static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
#endif
/*****************************************************************************
+ * GoTop Part
+ */
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+static int gotop_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
+{
+ dev->x = ((pkt[1] & 0x38) << 4) | pkt[2];
+ dev->y = ((pkt[1] & 0x07) << 7) | pkt[3];
+ dev->touch = pkt[0] & 0x01;
+ return 1;
+}
+#endif
+
+
+/*****************************************************************************
* the different device descriptors
*/
static struct usbtouch_device_info usbtouch_dev_info[] = {
@@ -623,9 +645,19 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
.max_yc = 0x0500,
.rept_size = 7,
.read_data = general_touch_read_data,
- }
+ },
#endif
+#ifdef CONFIG_TOUCHSCREEN_USB_GOTOP
+ [DEVTYPE_GOTOP] = {
+ .min_xc = 0x0,
+ .max_xc = 0x03ff,
+ .min_yc = 0x0,
+ .max_yc = 0x03ff,
+ .rept_size = 4,
+ .read_data = gotop_read_data,
+ },
+#endif
};
@@ -868,8 +900,8 @@ static int usbtouch_probe(struct usb_interface *intf,
input_dev->open = usbtouch_open;
input_dev->close = usbtouch_close;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0);
input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0);
if (type->max_press)
diff --git a/drivers/isdn/act2000/act2000_isa.c b/drivers/isdn/act2000/act2000_isa.c
index 09ea50dd345..819ea85576a 100644
--- a/drivers/isdn/act2000/act2000_isa.c
+++ b/drivers/isdn/act2000/act2000_isa.c
@@ -126,7 +126,7 @@ act2000_isa_enable_irq(act2000_card * card)
/*
* Install interrupt handler, enable irq on card.
- * If irq is -1, choose next free irq, else irq is given explicitely.
+ * If irq is -1, choose next free irq, else irq is given explicitly.
*/
int
act2000_isa_config_irq(act2000_card * card, short irq)
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 428872b653e..669f6f67449 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -486,11 +486,13 @@ static void b1dma_handle_rx(avmcard *card)
card->name);
} else {
memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
+ if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) {
+ spin_lock(&card->lock);
capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
- CAPIMSG_NCCI(skb->data),
- CAPIMSG_MSGID(skb->data));
-
+ CAPIMSG_NCCI(skb->data),
+ CAPIMSG_MSGID(skb->data));
+ spin_unlock(&card->lock);
+ }
capi_ctr_handle_message(ctrl, ApplId, skb);
}
break;
@@ -500,9 +502,9 @@ static void b1dma_handle_rx(avmcard *card)
ApplId = _get_word(&p);
NCCI = _get_word(&p);
WindowSize = _get_word(&p);
-
+ spin_lock(&card->lock);
capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+ spin_unlock(&card->lock);
break;
case RECEIVE_FREE_NCCI:
@@ -510,9 +512,11 @@ static void b1dma_handle_rx(avmcard *card)
ApplId = _get_word(&p);
NCCI = _get_word(&p);
- if (NCCI != 0xffffffff)
+ if (NCCI != 0xffffffff) {
+ spin_lock(&card->lock);
capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+ spin_unlock(&card->lock);
+ }
break;
case RECEIVE_START:
@@ -751,10 +755,10 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
spin_lock_irqsave(&card->lock, flags);
b1dma_reset(card);
- spin_unlock_irqrestore(&card->lock, flags);
memset(cinfo->version, 0, sizeof(cinfo->version));
capilib_release(&cinfo->ncci_head);
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(ctrl);
}
@@ -803,8 +807,11 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
avmcard *card = cinfo->card;
struct sk_buff *skb;
void *p;
+ unsigned long flags;
+ spin_lock_irqsave(&card->lock, flags);
capilib_release_appl(&cinfo->ncci_head, appl);
+ spin_unlock_irqrestore(&card->lock, flags);
skb = alloc_skb(7, GFP_ATOMIC);
if (!skb) {
@@ -832,10 +839,13 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u16 retval = CAPI_NOERROR;
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+ unsigned long flags;
+ spin_lock_irqsave(&card->lock, flags);
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
+ spin_unlock_irqrestore(&card->lock, flags);
}
if (retval == CAPI_NOERROR)
b1dma_queue_tx(card, skb);
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index 8710cf6214d..4bbbbe68807 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -678,7 +678,9 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
for (i=0; i < card->nr_controllers; i++) {
avmctrl_info *cinfo = &card->ctrlinfo[i];
memset(cinfo->version, 0, sizeof(cinfo->version));
+ spin_lock_irqsave(&card->lock, flags);
capilib_release(&cinfo->ncci_head);
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(&cinfo->capi_ctrl);
}
card->nlogcontr = 0;
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c
index c925020fe9b..6130724e46e 100644
--- a/drivers/isdn/hardware/avm/t1isa.c
+++ b/drivers/isdn/hardware/avm/t1isa.c
@@ -180,8 +180,8 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
ApplId = (unsigned) b1_get_word(card->port);
MsgLen = t1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
+ spin_unlock_irqrestore(&card->lock, flags);
printk(KERN_ERR "%s: incoming packet dropped\n",
card->name);
} else {
@@ -190,7 +190,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
-
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_handle_message(ctrl, ApplId, skb);
}
break;
@@ -200,21 +200,17 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr)
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
WindowSize = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case RECEIVE_FREE_NCCI:
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
if (NCCI != 0xffffffff)
capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;
case RECEIVE_START:
@@ -333,13 +329,16 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl)
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
unsigned int port = card->port;
+ unsigned long flags;
t1_disable_irq(port);
b1_reset(port);
b1_reset(port);
memset(cinfo->version, 0, sizeof(cinfo->version));
+ spin_lock_irqsave(&card->lock, flags);
capilib_release(&cinfo->ncci_head);
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(ctrl);
}
@@ -466,29 +465,26 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
u16 dlen, retval;
+ spin_lock_irqsave(&card->lock, flags);
if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
- if (retval != CAPI_NOERROR)
+ if (retval != CAPI_NOERROR) {
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
-
+ }
dlen = CAPIMSG_DATALEN(skb->data);
- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_DATA_B3_REQ);
t1_put_slice(port, skb->data, len);
t1_put_slice(port, skb->data + len, dlen);
- spin_unlock_irqrestore(&card->lock, flags);
} else {
-
- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_MESSAGE);
t1_put_slice(port, skb->data, len);
- spin_unlock_irqrestore(&card->lock, flags);
}
-
+ spin_unlock_irqrestore(&card->lock, flags);
dev_kfree_skb_any(skb);
return CAPI_NOERROR;
}
diff --git a/drivers/isdn/hardware/eicon/capifunc.c b/drivers/isdn/hardware/eicon/capifunc.c
index 82edc1c1db7..4d425c644d4 100644
--- a/drivers/isdn/hardware/eicon/capifunc.c
+++ b/drivers/isdn/hardware/eicon/capifunc.c
@@ -321,7 +321,7 @@ void sendf(APPL * appl, word command, dword Id, word Number, byte * format, ...)
DBG_BLK((((char *)(long)GET_DWORD(&msg.info.data_b3_ind.Data)) + i,
((dlength - i) < 256) ? (dlength - i) : 256))
if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
- break; /* not more if not explicitely requested */
+ break; /* not more if not explicitly requested */
}
}
break;
@@ -965,7 +965,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl,
((GET_WORD(&msg->info.data_b3_req.Data_Length) - j) <
256) ? (GET_WORD(&msg->info.data_b3_req.Data_Length) - j) : 256))
if (!(myDriverDebugHandle.dbgMask & DL_PRV0))
- break; /* not more if not explicitely requested */
+ break; /* not more if not explicitly requested */
}
}
#endif
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 3b19caeba25..c0d7036404a 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -767,7 +767,7 @@ Amd7930_init(struct IsdnCardState *cs)
/* read */
if (*ptr++ >= 0x100) {
if (cmd < 8)
- /* setzt Register zurck */
+ /* reset register */
rByteAMD(cs, cmd);
else {
wByteAMD(cs, 0x00, cmd);
diff --git a/drivers/isdn/hisax/enternow_pci.c b/drivers/isdn/hisax/enternow_pci.c
index b73027ff50e..39f421ed8de 100644
--- a/drivers/isdn/hisax/enternow_pci.c
+++ b/drivers/isdn/hisax/enternow_pci.c
@@ -75,16 +75,16 @@
static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
-/* fr PowerISDN PCI */
+/* for PowerISDN PCI */
#define TJ_AMD_IRQ 0x20
#define TJ_LED1 0x40
#define TJ_LED2 0x80
-/* Das Fenster zum AMD...
- * Ab Adresse hw.njet.base + TJ_AMD_PORT werden vom AMD jeweils 8 Bit in
- * den TigerJet i/o-Raum gemappt
- * -> 0x01 des AMD bei hw.njet.base + 0C4 */
+/* The window to [the] AMD [chip]...
+ * From address hw.njet.base + TJ_AMD_PORT onwards, the AMD
+ * maps [consecutive/multiple] 8 bits into the TigerJet I/O space
+ * -> 0x01 of the AMD at hw.njet.base + 0C4 */
#define TJ_AMD_PORT 0xC0
@@ -96,11 +96,11 @@ static const char *enternow_pci_rev = "$Revision: 1.1.4.5 $";
static unsigned char
ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
{
- /* direktes Register */
+ /* direct register */
if(offset < 8)
return (inb(cs->hw.njet.isac + 4*offset));
- /* indirektes Register */
+ /* indirect register */
else {
outb(offset, cs->hw.njet.isac + 4*AMD_CR);
return(inb(cs->hw.njet.isac + 4*AMD_DR));
@@ -111,11 +111,11 @@ ReadByteAmd7930(struct IsdnCardState *cs, unsigned char offset)
static void
WriteByteAmd7930(struct IsdnCardState *cs, unsigned char offset, unsigned char value)
{
- /* direktes Register */
+ /* direct register */
if(offset < 8)
outb(value, cs->hw.njet.isac + 4*offset);
- /* indirektes Register */
+ /* indirect register */
else {
outb(offset, cs->hw.njet.isac + 4*AMD_CR);
outb(value, cs->hw.njet.isac + 4*AMD_DR);
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 077080aca79..fba8b624ffc 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1,6 +1,6 @@
/* $Id: hfc_pci.c,v 1.48.2.4 2004/02/11 13:21:33 keil Exp $
*
- * low level driver for CCDs hfc-pci based cards
+ * low level driver for CCD's hfc-pci based cards
*
* Author Werner Cornelius
* based on existing driver for CCD hfc ISA cards
diff --git a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/hisax/isdnhdlc.c
index 268dced6c34..c69a77a8006 100644
--- a/drivers/isdn/hisax/isdnhdlc.c
+++ b/drivers/isdn/hisax/isdnhdlc.c
@@ -1,7 +1,7 @@
/*
* isdnhdlc.c -- General purpose ISDN HDLC decoder.
*
- *Copyright (C) 2002 Wolfgang Mes <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
* 2001 Frode Isaksen <fisaksen@bewan.com>
* 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
*
@@ -27,7 +27,7 @@
/*-------------------------------------------------------------------*/
-MODULE_AUTHOR("Wolfgang Mes <wolfgang@iksw-muees.de>, "
+MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
"Frode Isaksen <fisaksen@bewan.com>, "
"Kai Germaschewski <kai.germaschewski@gmx.de>");
MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
index 45167d2f8fb..cf0a95a2401 100644
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ b/drivers/isdn/hisax/isdnhdlc.h
@@ -5,7 +5,7 @@
* Neccessary because some ISDN devices don't have HDLC
* controllers. Also included: a bit reversal table.
*
- *Copyright (C) 2002 Wolfgang Mes <wolfgang@iksw-muees.de>
+ *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
* 2001 Frode Isaksen <fisaksen@bewan.com>
* 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
*
diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c
index 43d61d1bc5b..70840a710ac 100644
--- a/drivers/isdn/hisax/jade.c
+++ b/drivers/isdn/hisax/jade.c
@@ -304,7 +304,7 @@ initjade(struct IsdnCardState *cs)
cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00);
/* Setup host access to hdlc controller */
jade_write_indirect(cs, jade_HDLCCNTRACCESS, (jadeINDIRECT_HAH1|jadeINDIRECT_HAH2));
- /* Unmask HDLC int (dont forget DSP int later on)*/
+ /* Unmask HDLC int (don't forget DSP int later on)*/
cs->BC_Write_Reg(cs, -1,jade_INT, (jadeINT_HDLC1|jadeINT_HDLC2));
/* once again TRANSPARENT */
diff --git a/drivers/isdn/pcbit/capi.c b/drivers/isdn/pcbit/capi.c
index 7b55e151f1b..ac5a91ccde8 100644
--- a/drivers/isdn/pcbit/capi.c
+++ b/drivers/isdn/pcbit/capi.c
@@ -15,9 +15,9 @@
/*
* Documentation:
- * - "Common ISDN API - Perfil Portugus - Verso 2.1",
+ * - "Common ISDN API - Perfil Português - Versão 2.1",
* Telecom Portugal, Fev 1992.
- * - "Common ISDN API - Especificao de protocolos para
+ * - "Common ISDN API - Especificação de protocolos para
* acesso aos canais B", Inesc, Jan 1994.
*/
diff --git a/drivers/isdn/sc/debug.h b/drivers/isdn/sc/debug.h
deleted file mode 100644
index e9db96ede4b..00000000000
--- a/drivers/isdn/sc/debug.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $
- *
- * Copyright (C) 1996 SpellCaster Telecommunications Inc.
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- * For more information, please contact gpl-info@spellcast.com or write:
- *
- * SpellCaster Telecommunications Inc.
- * 5621 Finch Avenue East, Unit #3
- * Scarborough, Ontario Canada
- * M1B 2T9
- * +1 (416) 297-8565
- * +1 (416) 297-6433 Facsimile
- */
-
-#define REQUEST_IRQ(a,b,c,d,e) request_irq(a,b,c,d,e)
-#define FREE_IRQ(a,b) free_irq(a,b)
diff --git a/drivers/isdn/sc/includes.h b/drivers/isdn/sc/includes.h
index 5286e0c810a..4766e5b7737 100644
--- a/drivers/isdn/sc/includes.h
+++ b/drivers/isdn/sc/includes.h
@@ -14,4 +14,3 @@
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/isdnif.h>
-#include "debug.h"
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index 0bf76344a0d..d09c854cfac 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -404,7 +404,7 @@ static void __exit sc_exit(void)
/*
* Release the IRQ
*/
- FREE_IRQ(sc_adapter[i]->interrupt, NULL);
+ free_irq(sc_adapter[i]->interrupt, NULL);
/*
* Reset for a clean start
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index af2d288c881..07ae280e8fe 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -198,21 +198,15 @@ static void vcpu_put(struct kvm_vcpu *vcpu)
static void ack_flush(void *_completed)
{
- atomic_t *completed = _completed;
-
- atomic_inc(completed);
}
void kvm_flush_remote_tlbs(struct kvm *kvm)
{
- int i, cpu, needed;
+ int i, cpu;
cpumask_t cpus;
struct kvm_vcpu *vcpu;
- atomic_t completed;
- atomic_set(&completed, 0);
cpus_clear(cpus);
- needed = 0;
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
vcpu = kvm->vcpus[i];
if (!vcpu)
@@ -221,23 +215,9 @@ void kvm_flush_remote_tlbs(struct kvm *kvm)
continue;
cpu = vcpu->cpu;
if (cpu != -1 && cpu != raw_smp_processor_id())
- if (!cpu_isset(cpu, cpus)) {
- cpu_set(cpu, cpus);
- ++needed;
- }
- }
-
- /*
- * We really want smp_call_function_mask() here. But that's not
- * available, so ipi all cpus in parallel and wait for them
- * to complete.
- */
- for (cpu = first_cpu(cpus); cpu != NR_CPUS; cpu = next_cpu(cpu, cpus))
- smp_call_function_single(cpu, ack_flush, &completed, 1, 0);
- while (atomic_read(&completed) != needed) {
- cpu_relax();
- barrier();
+ cpu_set(cpu, cpus);
}
+ smp_call_function_mask(cpus, ack_flush, NULL, 1);
}
int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
@@ -2054,12 +2034,21 @@ again:
kvm_x86_ops->run(vcpu, kvm_run);
- kvm_guest_exit();
vcpu->guest_mode = 0;
local_irq_enable();
++vcpu->stat.exits;
+ /*
+ * We must have an instruction between local_irq_enable() and
+ * kvm_guest_exit(), so the timer interrupt isn't delayed by
+ * the interrupt shadow. The stat.exits increment will do nicely.
+ * But we need to prevent reordering, hence this barrier():
+ */
+ barrier();
+
+ kvm_guest_exit();
+
preempt_enable();
/*
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
index a190587cf6a..238fcad3cec 100644
--- a/drivers/kvm/lapic.c
+++ b/drivers/kvm/lapic.c
@@ -494,12 +494,19 @@ static void apic_send_ipi(struct kvm_lapic *apic)
static u32 apic_get_tmcct(struct kvm_lapic *apic)
{
- u32 counter_passed;
- ktime_t passed, now = apic->timer.dev.base->get_time();
- u32 tmcct = apic_get_reg(apic, APIC_TMICT);
+ u64 counter_passed;
+ ktime_t passed, now;
+ u32 tmcct;
ASSERT(apic != NULL);
+ now = apic->timer.dev.base->get_time();
+ tmcct = apic_get_reg(apic, APIC_TMICT);
+
+ /* if initial count is 0, current count should also be 0 */
+ if (tmcct == 0)
+ return 0;
+
if (unlikely(ktime_to_ns(now) <=
ktime_to_ns(apic->timer.last_update))) {
/* Wrap around */
@@ -514,15 +521,24 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic)
counter_passed = div64_64(ktime_to_ns(passed),
(APIC_BUS_CYCLE_NS * apic->timer.divide_count));
- tmcct -= counter_passed;
- if (tmcct <= 0) {
- if (unlikely(!apic_lvtt_period(apic)))
+ if (counter_passed > tmcct) {
+ if (unlikely(!apic_lvtt_period(apic))) {
+ /* one-shot timers stick at 0 until reset */
tmcct = 0;
- else
- do {
- tmcct += apic_get_reg(apic, APIC_TMICT);
- } while (tmcct <= 0);
+ } else {
+ /*
+ * periodic timers reset to APIC_TMICT when they
+ * hit 0. The while loop simulates this happening N
+ * times. (counter_passed %= tmcct) would also work,
+ * but might be slower or not work on 32-bit??
+ */
+ while (counter_passed > tmcct)
+ counter_passed -= tmcct;
+ tmcct -= counter_passed;
+ }
+ } else {
+ tmcct -= counter_passed;
}
return tmcct;
@@ -853,7 +869,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu)
apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
}
- apic->timer.divide_count = 0;
+ update_divide_count(apic);
atomic_set(&apic->timer.pending, 0);
if (vcpu->vcpu_id == 0)
vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index 6d84d30f5ed..feb5ac986c5 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -1049,6 +1049,7 @@ int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
destroy_kvm_mmu(vcpu);
return init_kvm_mmu(vcpu);
}
+EXPORT_SYMBOL_GPL(kvm_mmu_reset_context);
int kvm_mmu_load(struct kvm_vcpu *vcpu)
{
@@ -1088,7 +1089,7 @@ static void mmu_pte_write_zap_pte(struct kvm_vcpu *vcpu,
mmu_page_remove_parent_pte(child, spte);
}
}
- *spte = 0;
+ set_shadow_pte(spte, 0);
kvm_flush_remote_tlbs(vcpu->kvm);
}
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 4f115a8e45e..bb56ae3f89b 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -523,6 +523,8 @@ static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
{
+ if (vcpu->rmode.active)
+ rflags |= IOPL_MASK | X86_EFLAGS_VM;
vmcs_writel(GUEST_RFLAGS, rflags);
}
@@ -1128,6 +1130,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
+ kvm_mmu_reset_context(vcpu);
init_rmode_tss(vcpu->kvm);
}
@@ -1760,10 +1763,8 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
set_bit(irq / BITS_PER_LONG, &vcpu->irq_summary);
}
- if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */
- asm ("int $2");
- return 1;
- }
+ if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+ return 1; /* already handled by vmx_vcpu_run() */
if (is_no_device(intr_info)) {
vmx_fpu_activate(vcpu);
@@ -2196,6 +2197,7 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ u32 intr_info;
/*
* Loading guest fpu may have cleared host cr0.ts
@@ -2322,6 +2324,12 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
vmx->launched = 1;
+
+ intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+
+ /* We need to handle NMIs before interrupts are enabled */
+ if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */
+ asm("int $2");
}
static void vmx_inject_page_fault(struct kvm_vcpu *vcpu,
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 9737c3b2f48..a6ace302e0c 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -212,7 +212,8 @@ static u16 twobyte_table[256] = {
0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov,
DstReg | SrcMem16 | ModRM | Mov,
/* 0xC0 - 0xCF */
- 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, DstMem | SrcReg | ModRM | Mov, 0, 0, 0, ImplicitOps | ModRM,
+ 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xD0 - 0xDF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE0 - 0xEF */
@@ -596,11 +597,10 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
case 0xf0: /* LOCK */
lock_prefix = 1;
break;
+ case 0xf2: /* REPNE/REPNZ */
case 0xf3: /* REP/REPE/REPZ */
rep_prefix = 1;
break;
- case 0xf2: /* REPNE/REPNZ */
- break;
default:
goto done_prefixes;
}
@@ -825,6 +825,14 @@ done_prefixes:
if (twobyte && b == 0x01 && modrm_reg == 7)
break;
srcmem_common:
+ /*
+ * For instructions with a ModR/M byte, switch to register
+ * access if Mod = 3.
+ */
+ if ((d & ModRM) && modrm_mod == 3) {
+ src.type = OP_REG;
+ break;
+ }
src.type = OP_MEM;
src.ptr = (unsigned long *)cr2;
src.val = 0;
@@ -893,6 +901,14 @@ done_prefixes:
dst.ptr = (unsigned long *)cr2;
dst.bytes = (d & ByteOp) ? 1 : op_bytes;
dst.val = 0;
+ /*
+ * For instructions with a ModR/M byte, switch to register
+ * access if Mod = 3.
+ */
+ if ((d & ModRM) && modrm_mod == 3) {
+ dst.type = OP_REG;
+ break;
+ }
if (d & BitOp) {
unsigned long mask = ~(dst.bytes * 8 - 1);
@@ -1083,31 +1099,6 @@ push:
case 0xd2 ... 0xd3: /* Grp2 */
src.val = _regs[VCPU_REGS_RCX];
goto grp2;
- case 0xe8: /* call (near) */ {
- long int rel;
- switch (op_bytes) {
- case 2:
- rel = insn_fetch(s16, 2, _eip);
- break;
- case 4:
- rel = insn_fetch(s32, 4, _eip);
- break;
- case 8:
- rel = insn_fetch(s64, 8, _eip);
- break;
- default:
- DPRINTF("Call: Invalid op_bytes\n");
- goto cannot_emulate;
- }
- src.val = (unsigned long) _eip;
- JMP_REL(rel);
- goto push;
- }
- case 0xe9: /* jmp rel */
- case 0xeb: /* jmp rel short */
- JMP_REL(src.val);
- no_wb = 1; /* Disable writeback. */
- break;
case 0xf6 ... 0xf7: /* Grp3 */
switch (modrm_reg) {
case 0 ... 1: /* test */
@@ -1350,6 +1341,32 @@ special_insn:
case 0xae ... 0xaf: /* scas */
DPRINTF("Urk! I don't handle SCAS.\n");
goto cannot_emulate;
+ case 0xe8: /* call (near) */ {
+ long int rel;
+ switch (op_bytes) {
+ case 2:
+ rel = insn_fetch(s16, 2, _eip);
+ break;
+ case 4:
+ rel = insn_fetch(s32, 4, _eip);
+ break;
+ case 8:
+ rel = insn_fetch(s64, 8, _eip);
+ break;
+ default:
+ DPRINTF("Call: Invalid op_bytes\n");
+ goto cannot_emulate;
+ }
+ src.val = (unsigned long) _eip;
+ JMP_REL(rel);
+ goto push;
+ }
+ case 0xe9: /* jmp rel */
+ case 0xeb: /* jmp rel short */
+ JMP_REL(src.val);
+ no_wb = 1; /* Disable writeback. */
+ break;
+
}
goto writeback;
@@ -1501,6 +1518,10 @@ twobyte_insn:
dst.bytes = op_bytes;
dst.val = (d & ByteOp) ? (s8) src.val : (s16) src.val;
break;
+ case 0xc3: /* movnti */
+ dst.bytes = op_bytes;
+ dst.val = (op_bytes == 4) ? (u32) src.val : (u64) src.val;
+ break;
}
goto writeback;
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 50914439d86..0fd64075129 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -43,7 +43,7 @@ static void s3c24xx_led_set(struct led_classdev *led_cdev,
struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
struct s3c24xx_led_platdata *pd = led->pdata;
- /* there will be a sort delay between setting the output and
+ /* there will be a short delay between setting the output and
* going from output to input when using tristate. */
s3c2410_gpio_setpin(pd->gpio, (value ? 1 : 0) ^
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index 2766e4fc4ea..883da72b536 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -791,8 +791,10 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
if (hid->keycode[i])
set_bit(hid->keycode[i], input_dev->keybit);
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
- input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) |
+ BIT_MASK(EV_REP);
+ input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) |
+ BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML);
input_dev->event = adbhid_kbd_event;
input_dev->keycodemax = KEY_FN;
input_dev->keycodesize = sizeof(hid->keycode[0]);
@@ -801,16 +803,18 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
case ADB_MOUSE:
sprintf(hid->name, "ADB mouse");
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
break;
case ADB_MISC:
switch (original_handler_id) {
case 0x02: /* Adjustable keyboard button device */
sprintf(hid->name, "ADB adjustable keyboard buttons");
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+ BIT_MASK(EV_REP);
set_bit(KEY_SOUND, input_dev->keybit);
set_bit(KEY_MUTE, input_dev->keybit);
set_bit(KEY_VOLUMEUP, input_dev->keybit);
@@ -818,7 +822,8 @@ adbhid_input_register(int id, int default_id, int original_handler_id,
break;
case 0x1f: /* Powerbook button device */
sprintf(hid->name, "ADB Powerbook buttons");
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) |
+ BIT_MASK(EV_REP);
set_bit(KEY_MUTE, input_dev->keybit);
set_bit(KEY_VOLUMEUP, input_dev->keybit);
set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 33dee3a773e..89302309da9 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -117,9 +117,10 @@ static int emumousebtn_input_register(void)
emumousebtn->id.product = 0x0001;
emumousebtn->id.version = 0x0100;
- emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
- emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+ emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
+ emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
ret = input_register_device(emumousebtn);
if (ret)
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index c803d2bba65..48d647abea4 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -563,7 +563,7 @@ static void media_bay_step(int i)
ide_init_hwif_ports(&hw, (unsigned long) bay->cd_base, (unsigned long) 0, NULL);
hw.irq = bay->cd_irq;
hw.chipset = ide_pmac;
- bay->cd_index = ide_register_hw(&hw, 0, NULL);
+ bay->cd_index = ide_register_hw(&hw, NULL, 0, NULL);
pmu_resume();
}
if (bay->cd_index == -1) {
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index f7c509b7a8e..dc741d3a453 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -1521,7 +1521,7 @@ pmu_sr_intr(void)
req = current_req;
/*
* For PMU sleep and freq change requests, we lock the
- * PMU until it's explicitely unlocked. This avoids any
+ * PMU until it's explicitly unlocked. This avoids any
* spurrious event polling getting in
*/
current_req = req->next;
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 34a8c60a254..9b6fbf044fd 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -267,6 +267,12 @@ config DM_MULTIPATH_RDAC
---help---
Multipath support for LSI/Engenio RDAC.
+config DM_MULTIPATH_HP
+ tristate "HP MSA multipath support (EXPERIMENTAL)"
+ depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Multipath support for HP MSA (Active/Passive) series hardware.
+
config DM_DELAY
tristate "I/O delaying target (EXPERIMENTAL)"
depends on BLK_DEV_DM && EXPERIMENTAL
@@ -276,4 +282,10 @@ config DM_DELAY
If unsure, say N.
+config DM_UEVENT
+ bool "DM uevents (EXPERIMENTAL)"
+ depends on BLK_DEV_DM && EXPERIMENTAL
+ ---help---
+ Generate udev events for DM events.
+
endif # MD
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index c49366cdc05..d9aa7edb878 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -8,6 +8,7 @@ dm-multipath-objs := dm-hw-handler.o dm-path-selector.o dm-mpath.o
dm-snapshot-objs := dm-snap.o dm-exception-store.o
dm-mirror-objs := dm-log.o dm-raid1.o
dm-rdac-objs := dm-mpath-rdac.o
+dm-hp-sw-objs := dm-mpath-hp-sw.o
md-mod-objs := md.o bitmap.o
raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \
raid6int1.o raid6int2.o raid6int4.o \
@@ -35,6 +36,7 @@ obj-$(CONFIG_DM_CRYPT) += dm-crypt.o
obj-$(CONFIG_DM_DELAY) += dm-delay.o
obj-$(CONFIG_DM_MULTIPATH) += dm-multipath.o dm-round-robin.o
obj-$(CONFIG_DM_MULTIPATH_EMC) += dm-emc.o
+obj-$(CONFIG_DM_MULTIPATH_HP) += dm-hp-sw.o
obj-$(CONFIG_DM_MULTIPATH_RDAC) += dm-rdac.o
obj-$(CONFIG_DM_SNAPSHOT) += dm-snapshot.o
obj-$(CONFIG_DM_MIRROR) += dm-mirror.o
@@ -48,6 +50,10 @@ ifeq ($(CONFIG_ALTIVEC),y)
altivec_flags := -maltivec -mabi=altivec
endif
+ifeq ($(CONFIG_DM_UEVENT),y)
+dm-mod-objs += dm-uevent.o
+endif
+
targets += raid6int1.c
$(obj)/raid6int1.c: UNROLL := 1
$(obj)/raid6int1.c: $(src)/raid6int.uc $(src)/unroll.pl FORCE
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index 3f7b827649e..d4509be0fe6 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -21,11 +21,6 @@ static inline int bio_list_empty(const struct bio_list *bl)
return bl->head == NULL;
}
-#define BIO_LIST_INIT { .head = NULL, .tail = NULL }
-
-#define BIO_LIST(bl) \
- struct bio_list bl = BIO_LIST_INIT
-
static inline void bio_list_init(struct bio_list *bl)
{
bl->head = bl->tail = NULL;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 64fee90bb68..ac54f697c50 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -36,7 +36,6 @@ struct dm_crypt_io {
struct work_struct work;
atomic_t pending;
int error;
- int post_process;
};
/*
@@ -57,7 +56,7 @@ struct crypt_config;
struct crypt_iv_operations {
int (*ctr)(struct crypt_config *cc, struct dm_target *ti,
- const char *opts);
+ const char *opts);
void (*dtr)(struct crypt_config *cc);
const char *(*status)(struct crypt_config *cc);
int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
@@ -80,6 +79,8 @@ struct crypt_config {
mempool_t *page_pool;
struct bio_set *bs;
+ struct workqueue_struct *io_queue;
+ struct workqueue_struct *crypt_queue;
/*
* crypto related data
*/
@@ -112,7 +113,7 @@ static void clone_init(struct dm_crypt_io *, struct bio *);
* Different IV generation algorithms:
*
* plain: the initial vector is the 32-bit little-endian version of the sector
- * number, padded with zeros if neccessary.
+ * number, padded with zeros if necessary.
*
* essiv: "encrypted sector|salt initial vector", the sector number is
* encrypted with the bulk cipher using a salt as key. The salt
@@ -137,7 +138,7 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, sector_t sector)
}
static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
- const char *opts)
+ const char *opts)
{
struct crypto_cipher *essiv_tfm;
struct crypto_hash *hash_tfm;
@@ -175,6 +176,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
if (err) {
ti->error = "Error calculating hash in ESSIV";
+ kfree(salt);
return err;
}
@@ -188,7 +190,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
if (crypto_cipher_blocksize(essiv_tfm) !=
crypto_blkcipher_ivsize(cc->tfm)) {
ti->error = "Block size of ESSIV cipher does "
- "not match IV size of block cipher";
+ "not match IV size of block cipher";
crypto_free_cipher(essiv_tfm);
kfree(salt);
return -EINVAL;
@@ -319,10 +321,10 @@ crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out,
return r;
}
-static void
-crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx,
- struct bio *bio_out, struct bio *bio_in,
- sector_t sector, int write)
+static void crypt_convert_init(struct crypt_config *cc,
+ struct convert_context *ctx,
+ struct bio *bio_out, struct bio *bio_in,
+ sector_t sector, int write)
{
ctx->bio_in = bio_in;
ctx->bio_out = bio_out;
@@ -338,7 +340,7 @@ crypt_convert_init(struct crypt_config *cc, struct convert_context *ctx,
* Encrypt / decrypt data from one bio to another one (can be the same one)
*/
static int crypt_convert(struct crypt_config *cc,
- struct convert_context *ctx)
+ struct convert_context *ctx)
{
int r = 0;
@@ -346,16 +348,17 @@ static int crypt_convert(struct crypt_config *cc,
ctx->idx_out < ctx->bio_out->bi_vcnt) {
struct bio_vec *bv_in = bio_iovec_idx(ctx->bio_in, ctx->idx_in);
struct bio_vec *bv_out = bio_iovec_idx(ctx->bio_out, ctx->idx_out);
- struct scatterlist sg_in = {
- .page = bv_in->bv_page,
- .offset = bv_in->bv_offset + ctx->offset_in,
- .length = 1 << SECTOR_SHIFT
- };
- struct scatterlist sg_out = {
- .page = bv_out->bv_page,
- .offset = bv_out->bv_offset + ctx->offset_out,
- .length = 1 << SECTOR_SHIFT
- };
+ struct scatterlist sg_in, sg_out;
+
+ sg_init_table(&sg_in, 1);
+ sg_set_page(&sg_in, bv_in->bv_page);
+ sg_in.offset = bv_in->bv_offset + ctx->offset_in;
+ sg_in.length = 1 << SECTOR_SHIFT;
+
+ sg_init_table(&sg_out, 1);
+ sg_set_page(&sg_out, bv_out->bv_page);
+ sg_out.offset = bv_out->bv_offset + ctx->offset_out;
+ sg_out.length = 1 << SECTOR_SHIFT;
ctx->offset_in += sg_in.length;
if (ctx->offset_in >= bv_in->bv_len) {
@@ -370,7 +373,7 @@ static int crypt_convert(struct crypt_config *cc,
}
r = crypt_convert_scatterlist(cc, &sg_out, &sg_in, sg_in.length,
- ctx->write, ctx->sector);
+ ctx->write, ctx->sector);
if (r < 0)
break;
@@ -380,13 +383,13 @@ static int crypt_convert(struct crypt_config *cc,
return r;
}
- static void dm_crypt_bio_destructor(struct bio *bio)
- {
+static void dm_crypt_bio_destructor(struct bio *bio)
+{
struct dm_crypt_io *io = bio->bi_private;
struct crypt_config *cc = io->target->private;
bio_free(bio, cc->bs);
- }
+}
/*
* Generate a new unfragmented bio with the given size
@@ -458,7 +461,7 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
* One of the bios was finished. Check for completion of
* the whole request and correctly clean up the buffer.
*/
-static void dec_pending(struct dm_crypt_io *io, int error)
+static void crypt_dec_pending(struct dm_crypt_io *io, int error)
{
struct crypt_config *cc = (struct crypt_config *) io->target->private;
@@ -474,18 +477,36 @@ static void dec_pending(struct dm_crypt_io *io, int error)
}
/*
- * kcryptd:
+ * kcryptd/kcryptd_io:
*
* Needed because it would be very unwise to do decryption in an
* interrupt context.
+ *
+ * kcryptd performs the actual encryption or decryption.
+ *
+ * kcryptd_io performs the IO submission.
+ *
+ * They must be separated as otherwise the final stages could be
+ * starved by new requests which can block in the first stages due
+ * to memory allocation.
*/
-static struct workqueue_struct *_kcryptd_workqueue;
static void kcryptd_do_work(struct work_struct *work);
+static void kcryptd_do_crypt(struct work_struct *work);
static void kcryptd_queue_io(struct dm_crypt_io *io)
{
+ struct crypt_config *cc = io->target->private;
+
INIT_WORK(&io->work, kcryptd_do_work);
- queue_work(_kcryptd_workqueue, &io->work);
+ queue_work(cc->io_queue, &io->work);
+}
+
+static void kcryptd_queue_crypt(struct dm_crypt_io *io)
+{
+ struct crypt_config *cc = io->target->private;
+
+ INIT_WORK(&io->work, kcryptd_do_crypt);
+ queue_work(cc->crypt_queue, &io->work);
}
static void crypt_endio(struct bio *clone, int error)
@@ -508,13 +529,12 @@ static void crypt_endio(struct bio *clone, int error)
}
bio_put(clone);
- io->post_process = 1;
- kcryptd_queue_io(io);
+ kcryptd_queue_crypt(io);
return;
out:
bio_put(clone);
- dec_pending(io, error);
+ crypt_dec_pending(io, error);
}
static void clone_init(struct dm_crypt_io *io, struct bio *clone)
@@ -544,7 +564,7 @@ static void process_read(struct dm_crypt_io *io)
*/
clone = bio_alloc_bioset(GFP_NOIO, bio_segments(base_bio), cc->bs);
if (unlikely(!clone)) {
- dec_pending(io, -ENOMEM);
+ crypt_dec_pending(io, -ENOMEM);
return;
}
@@ -579,7 +599,7 @@ static void process_write(struct dm_crypt_io *io)
while (remaining) {
clone = crypt_alloc_buffer(io, remaining);
if (unlikely(!clone)) {
- dec_pending(io, -ENOMEM);
+ crypt_dec_pending(io, -ENOMEM);
return;
}
@@ -589,7 +609,7 @@ static void process_write(struct dm_crypt_io *io)
if (unlikely(crypt_convert(cc, &ctx) < 0)) {
crypt_free_buffer_pages(cc, clone);
bio_put(clone);
- dec_pending(io, -EIO);
+ crypt_dec_pending(io, -EIO);
return;
}
@@ -624,17 +644,23 @@ static void process_read_endio(struct dm_crypt_io *io)
crypt_convert_init(cc, &ctx, io->base_bio, io->base_bio,
io->base_bio->bi_sector - io->target->begin, 0);
- dec_pending(io, crypt_convert(cc, &ctx));
+ crypt_dec_pending(io, crypt_convert(cc, &ctx));
}
static void kcryptd_do_work(struct work_struct *work)
{
struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
- if (io->post_process)
- process_read_endio(io);
- else if (bio_data_dir(io->base_bio) == READ)
+ if (bio_data_dir(io->base_bio) == READ)
process_read(io);
+}
+
+static void kcryptd_do_crypt(struct work_struct *work)
+{
+ struct dm_crypt_io *io = container_of(work, struct dm_crypt_io, work);
+
+ if (bio_data_dir(io->base_bio) == READ)
+ process_read_endio(io);
else
process_write(io);
}
@@ -690,7 +716,7 @@ static int crypt_set_key(struct crypt_config *cc, char *key)
cc->key_size = key_size; /* initial settings */
if ((!key_size && strcmp(key, "-")) ||
- (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
+ (key_size && crypt_decode_key(cc->key, key, key_size) < 0))
return -EINVAL;
set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
@@ -746,7 +772,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (crypt_set_key(cc, argv[1])) {
ti->error = "Error decoding key";
- goto bad1;
+ goto bad_cipher;
}
/* Compatiblity mode for old dm-crypt cipher strings */
@@ -757,19 +783,19 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (strcmp(chainmode, "ecb") && !ivmode) {
ti->error = "This chaining mode requires an IV mechanism";
- goto bad1;
+ goto bad_cipher;
}
- if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)", chainmode,
- cipher) >= CRYPTO_MAX_ALG_NAME) {
+ if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
+ chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
ti->error = "Chain mode + cipher name is too long";
- goto bad1;
+ goto bad_cipher;
}
tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(tfm)) {
ti->error = "Error allocating crypto tfm";
- goto bad1;
+ goto bad_cipher;
}
strcpy(cc->cipher, cipher);
@@ -793,18 +819,18 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
cc->iv_gen_ops = &crypt_iv_null_ops;
else {
ti->error = "Invalid IV mode";
- goto bad2;
+ goto bad_ivmode;
}
if (cc->iv_gen_ops && cc->iv_gen_ops->ctr &&
cc->iv_gen_ops->ctr(cc, ti, ivopts) < 0)
- goto bad2;
+ goto bad_ivmode;
cc->iv_size = crypto_blkcipher_ivsize(tfm);
if (cc->iv_size)
/* at least a 64 bit sector number should fit in our buffer */
cc->iv_size = max(cc->iv_size,
- (unsigned int)(sizeof(u64) / sizeof(u8)));
+ (unsigned int)(sizeof(u64) / sizeof(u8)));
else {
if (cc->iv_gen_ops) {
DMWARN("Selected cipher does not support IVs");
@@ -817,13 +843,13 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
cc->io_pool = mempool_create_slab_pool(MIN_IOS, _crypt_io_pool);
if (!cc->io_pool) {
ti->error = "Cannot allocate crypt io mempool";
- goto bad3;
+ goto bad_slab_pool;
}
cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
if (!cc->page_pool) {
ti->error = "Cannot allocate page mempool";
- goto bad4;
+ goto bad_page_pool;
}
cc->bs = bioset_create(MIN_IOS, MIN_IOS);
@@ -834,25 +860,25 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (crypto_blkcipher_setkey(tfm, cc->key, key_size) < 0) {
ti->error = "Error setting key";
- goto bad5;
+ goto bad_device;
}
if (sscanf(argv[2], "%llu", &tmpll) != 1) {
ti->error = "Invalid iv_offset sector";
- goto bad5;
+ goto bad_device;
}
cc->iv_offset = tmpll;
if (sscanf(argv[4], "%llu", &tmpll) != 1) {
ti->error = "Invalid device sector";
- goto bad5;
+ goto bad_device;
}
cc->start = tmpll;
if (dm_get_device(ti, argv[3], cc->start, ti->len,
- dm_table_get_mode(ti->table), &cc->dev)) {
+ dm_table_get_mode(ti->table), &cc->dev)) {
ti->error = "Device lookup failed";
- goto bad5;
+ goto bad_device;
}
if (ivmode && cc->iv_gen_ops) {
@@ -861,27 +887,45 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
cc->iv_mode = kmalloc(strlen(ivmode) + 1, GFP_KERNEL);
if (!cc->iv_mode) {
ti->error = "Error kmallocing iv_mode string";
- goto bad5;
+ goto bad_ivmode_string;
}
strcpy(cc->iv_mode, ivmode);
} else
cc->iv_mode = NULL;
+ cc->io_queue = create_singlethread_workqueue("kcryptd_io");
+ if (!cc->io_queue) {
+ ti->error = "Couldn't create kcryptd io queue";
+ goto bad_io_queue;
+ }
+
+ cc->crypt_queue = create_singlethread_workqueue("kcryptd");
+ if (!cc->crypt_queue) {
+ ti->error = "Couldn't create kcryptd queue";
+ goto bad_crypt_queue;
+ }
+
ti->private = cc;
return 0;
-bad5:
+bad_crypt_queue:
+ destroy_workqueue(cc->io_queue);
+bad_io_queue:
+ kfree(cc->iv_mode);
+bad_ivmode_string:
+ dm_put_device(ti, cc->dev);
+bad_device:
bioset_free(cc->bs);
bad_bs:
mempool_destroy(cc->page_pool);
-bad4:
+bad_page_pool:
mempool_destroy(cc->io_pool);
-bad3:
+bad_slab_pool:
if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
cc->iv_gen_ops->dtr(cc);
-bad2:
+bad_ivmode:
crypto_free_blkcipher(tfm);
-bad1:
+bad_cipher:
/* Must zero key material before freeing */
memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
kfree(cc);
@@ -892,7 +936,8 @@ static void crypt_dtr(struct dm_target *ti)
{
struct crypt_config *cc = (struct crypt_config *) ti->private;
- flush_workqueue(_kcryptd_workqueue);
+ destroy_workqueue(cc->io_queue);
+ destroy_workqueue(cc->crypt_queue);
bioset_free(cc->bs);
mempool_destroy(cc->page_pool);
@@ -918,9 +963,13 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
io = mempool_alloc(cc->io_pool, GFP_NOIO);
io->target = ti;
io->base_bio = bio;
- io->error = io->post_process = 0;
+ io->error = 0;
atomic_set(&io->pending, 0);
- kcryptd_queue_io(io);
+
+ if (bio_data_dir(io->base_bio) == READ)
+ kcryptd_queue_io(io);
+ else
+ kcryptd_queue_crypt(io);
return DM_MAPIO_SUBMITTED;
}
@@ -1037,25 +1086,12 @@ static int __init dm_crypt_init(void)
if (!_crypt_io_pool)
return -ENOMEM;
- _kcryptd_workqueue = create_workqueue("kcryptd");
- if (!_kcryptd_workqueue) {
- r = -ENOMEM;
- DMERR("couldn't create kcryptd");
- goto bad1;
- }
-
r = dm_register_target(&crypt_target);
if (r < 0) {
DMERR("register failed %d", r);
- goto bad2;
+ kmem_cache_destroy(_crypt_io_pool);
}
- return 0;
-
-bad2:
- destroy_workqueue(_kcryptd_workqueue);
-bad1:
- kmem_cache_destroy(_crypt_io_pool);
return r;
}
@@ -1066,7 +1102,6 @@ static void __exit dm_crypt_exit(void)
if (r < 0)
DMERR("unregister failed %d", r);
- destroy_workqueue(_kcryptd_workqueue);
kmem_cache_destroy(_crypt_io_pool);
}
diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c
index 6928c136d3c..bdd37f881c4 100644
--- a/drivers/md/dm-delay.c
+++ b/drivers/md/dm-delay.c
@@ -83,7 +83,7 @@ static struct bio *flush_delayed_bios(struct delay_c *dc, int flush_all)
struct dm_delay_info *delayed, *next;
unsigned long next_expires = 0;
int start_timer = 0;
- BIO_LIST(flush_bios);
+ struct bio_list flush_bios = { };
mutex_lock(&delayed_bios_lock);
list_for_each_entry_safe(delayed, next, &dc->delayed_bios, list) {
@@ -163,34 +163,32 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv)
goto bad;
}
- if (argc == 3) {
- dc->dev_write = NULL;
+ dc->dev_write = NULL;
+ if (argc == 3)
goto out;
- }
if (sscanf(argv[4], "%llu", &tmpll) != 1) {
ti->error = "Invalid write device sector";
- goto bad;
+ goto bad_dev_read;
}
dc->start_write = tmpll;
if (sscanf(argv[5], "%u", &dc->write_delay) != 1) {
ti->error = "Invalid write delay";
- goto bad;
+ goto bad_dev_read;
}
if (dm_get_device(ti, argv[3], dc->start_write, ti->len,
dm_table_get_mode(ti->table), &dc->dev_write)) {
ti->error = "Write device lookup failed";
- dm_put_device(ti, dc->dev_read);
- goto bad;
+ goto bad_dev_read;
}
out:
dc->delayed_pool = mempool_create_slab_pool(128, delayed_cache);
if (!dc->delayed_pool) {
DMERR("Couldn't create delayed bio pool.");
- goto bad;
+ goto bad_dev_write;
}
setup_timer(&dc->delay_timer, handle_delayed_timer, (unsigned long)dc);
@@ -203,6 +201,11 @@ out:
ti->private = dc;
return 0;
+bad_dev_write:
+ if (dc->dev_write)
+ dm_put_device(ti, dc->dev_write);
+bad_dev_read:
+ dm_put_device(ti, dc->dev_read);
bad:
kfree(dc);
return -EINVAL;
@@ -305,7 +308,7 @@ static int delay_status(struct dm_target *ti, status_type_t type,
(unsigned long long) dc->start_read,
dc->read_delay);
if (dc->dev_write)
- DMEMIT("%s %llu %u", dc->dev_write->name,
+ DMEMIT(" %s %llu %u", dc->dev_write->name,
(unsigned long long) dc->start_write,
dc->write_delay);
break;
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c
index 342517261ec..6b91b9ab1d4 100644
--- a/drivers/md/dm-emc.c
+++ b/drivers/md/dm-emc.c
@@ -81,7 +81,7 @@ static struct bio *get_failover_bio(struct dm_path *path, unsigned data_size)
}
if (bio_add_page(bio, page, data_size, 0) != data_size) {
- DMERR("get_failover_bio: alloc_page() failed.");
+ DMERR("get_failover_bio: bio_add_page() failed.");
__free_page(page);
bio_put(bio);
return NULL;
@@ -211,12 +211,10 @@ fail_path:
static struct emc_handler *alloc_emc_handler(void)
{
- struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL);
+ struct emc_handler *h = kzalloc(sizeof(*h), GFP_KERNEL);
- if (h) {
- memset(h, 0, sizeof(*h));
+ if (h)
spin_lock_init(&h->lock);
- }
return h;
}
diff --git a/drivers/md/dm-hw-handler.c b/drivers/md/dm-hw-handler.c
index baafaaba4d4..2ee84d8aa0b 100644
--- a/drivers/md/dm-hw-handler.c
+++ b/drivers/md/dm-hw-handler.c
@@ -91,12 +91,10 @@ void dm_put_hw_handler(struct hw_handler_type *hwht)
static struct hwh_internal *_alloc_hw_handler(struct hw_handler_type *hwht)
{
- struct hwh_internal *hwhi = kmalloc(sizeof(*hwhi), GFP_KERNEL);
+ struct hwh_internal *hwhi = kzalloc(sizeof(*hwhi), GFP_KERNEL);
- if (hwhi) {
- memset(hwhi, 0, sizeof(*hwhi));
+ if (hwhi)
hwhi->hwht = *hwht;
- }
return hwhi;
}
diff --git a/drivers/md/dm-hw-handler.h b/drivers/md/dm-hw-handler.h
index e0832e6fcf3..46809dcb121 100644
--- a/drivers/md/dm-hw-handler.h
+++ b/drivers/md/dm-hw-handler.h
@@ -58,5 +58,6 @@ unsigned dm_scsi_err_handler(struct hw_handler *hwh, struct bio *bio);
#define MP_FAIL_PATH 1
#define MP_BYPASS_PG 2
#define MP_ERROR_IO 4 /* Don't retry this I/O */
+#define MP_RETRY 8
#endif
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index b441d82c338..138200bf5e0 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -700,7 +700,7 @@ static int dev_rename(struct dm_ioctl *param, size_t param_size)
int r;
char *new_name = (char *) param + param->data_start;
- if (new_name < (char *) (param + 1) ||
+ if (new_name < (char *) param->data ||
invalid_str(new_name, (void *) param + param_size)) {
DMWARN("Invalid new logical volume name supplied.");
return -EINVAL;
@@ -726,7 +726,7 @@ static int dev_set_geometry(struct dm_ioctl *param, size_t param_size)
if (!md)
return -ENXIO;
- if (geostr < (char *) (param + 1) ||
+ if (geostr < (char *) param->data ||
invalid_str(geostr, (void *) param + param_size)) {
DMWARN("Invalid geometry supplied.");
goto out;
@@ -1233,7 +1233,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size)
if (r)
goto out;
- if (tmsg < (struct dm_target_msg *) (param + 1) ||
+ if (tmsg < (struct dm_target_msg *) param->data ||
invalid_str(tmsg->message, (void *) param + param_size)) {
DMWARN("Invalid target message parameters.");
r = -EINVAL;
@@ -1358,7 +1358,7 @@ static int copy_params(struct dm_ioctl __user *user, struct dm_ioctl **param)
if (tmp.data_size < sizeof(tmp))
return -EINVAL;
- dmi = (struct dm_ioctl *) vmalloc(tmp.data_size);
+ dmi = vmalloc(tmp.data_size);
if (!dmi)
return -ENOMEM;
@@ -1515,3 +1515,35 @@ void dm_interface_exit(void)
dm_hash_exit();
}
+
+/**
+ * dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers
+ * @md: Pointer to mapped_device
+ * @name: Buffer (size DM_NAME_LEN) for name
+ * @uuid: Buffer (size DM_UUID_LEN) for uuid or empty string if uuid not defined
+ */
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid)
+{
+ int r = 0;
+ struct hash_cell *hc;
+
+ if (!md)
+ return -ENXIO;
+
+ dm_get(md);
+ down_read(&_hash_lock);
+ hc = dm_get_mdptr(md);
+ if (!hc || hc->md != md) {
+ r = -ENXIO;
+ goto out;
+ }
+
+ strcpy(name, hc->name);
+ strcpy(uuid, hc->uuid ? : "");
+
+out:
+ up_read(&_hash_lock);
+ dm_put(md);
+
+ return r;
+}
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index a66428d860f..072ee4353ea 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -696,7 +696,7 @@ static struct dirty_log_type _disk_type = {
.module = THIS_MODULE,
.ctr = disk_ctr,
.dtr = disk_dtr,
- .suspend = disk_flush,
+ .postsuspend = disk_flush,
.resume = disk_resume,
.get_region_size = core_get_region_size,
.is_clean = core_is_clean,
diff --git a/drivers/md/dm-log.h b/drivers/md/dm-log.h
index 86a301c8daf..3fae87eb596 100644
--- a/drivers/md/dm-log.h
+++ b/drivers/md/dm-log.h
@@ -32,7 +32,8 @@ struct dirty_log_type {
* There are times when we don't want the log to touch
* the disk.
*/
- int (*suspend)(struct dirty_log *log);
+ int (*presuspend)(struct dirty_log *log);
+ int (*postsuspend)(struct dirty_log *log);
int (*resume)(struct dirty_log *log);
/*
diff --git a/drivers/md/dm-mpath-hp-sw.c b/drivers/md/dm-mpath-hp-sw.c
new file mode 100644
index 00000000000..204bf42c944
--- /dev/null
+++ b/drivers/md/dm-mpath-hp-sw.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2005 Mike Christie, All rights reserved.
+ * Copyright (C) 2007 Red Hat, Inc. All rights reserved.
+ * Authors: Mike Christie
+ * Dave Wysochanski
+ *
+ * This file is released under the GPL.
+ *
+ * This module implements the specific path activation code for
+ * HP StorageWorks and FSC FibreCat Asymmetric (Active/Passive)
+ * storage arrays.
+ * These storage arrays have controller-based failover, not
+ * LUN-based failover. However, LUN-based failover is the design
+ * of dm-multipath. Thus, this module is written for LUN-based failover.
+ */
+#include <linux/blkdev.h>
+#include <linux/list.h>
+#include <linux/types.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_dbg.h>
+
+#include "dm.h"
+#include "dm-hw-handler.h"
+
+#define DM_MSG_PREFIX "multipath hp-sw"
+#define DM_HP_HWH_NAME "hp-sw"
+#define DM_HP_HWH_VER "1.0.0"
+
+struct hp_sw_context {
+ unsigned char sense[SCSI_SENSE_BUFFERSIZE];
+};
+
+/*
+ * hp_sw_error_is_retryable - Is an HP-specific check condition retryable?
+ * @req: path activation request
+ *
+ * Examine error codes of request and determine whether the error is retryable.
+ * Some error codes are already retried by scsi-ml (see
+ * scsi_decide_disposition), but some HP specific codes are not.
+ * The intent of this routine is to supply the logic for the HP specific
+ * check conditions.
+ *
+ * Returns:
+ * 1 - command completed with retryable error
+ * 0 - command completed with non-retryable error
+ *
+ * Possible optimizations
+ * 1. More hardware-specific error codes
+ */
+static int hp_sw_error_is_retryable(struct request *req)
+{
+ /*
+ * NOT_READY is known to be retryable
+ * For now we just dump out the sense data and call it retryable
+ */
+ if (status_byte(req->errors) == CHECK_CONDITION)
+ __scsi_print_sense(DM_HP_HWH_NAME, req->sense, req->sense_len);
+
+ /*
+ * At this point we don't have complete information about all the error
+ * codes from this hardware, so we are just conservative and retry
+ * when in doubt.
+ */
+ return 1;
+}
+
+/*
+ * hp_sw_end_io - Completion handler for HP path activation.
+ * @req: path activation request
+ * @error: scsi-ml error
+ *
+ * Check sense data, free request structure, and notify dm that
+ * pg initialization has completed.
+ *
+ * Context: scsi-ml softirq
+ *
+ */
+static void hp_sw_end_io(struct request *req, int error)
+{
+ struct dm_path *path = req->end_io_data;
+ unsigned err_flags = 0;
+
+ if (!error) {
+ DMDEBUG("%s path activation command - success",
+ path->dev->name);
+ goto out;
+ }
+
+ if (hp_sw_error_is_retryable(req)) {
+ DMDEBUG("%s path activation command - retry",
+ path->dev->name);
+ err_flags = MP_RETRY;
+ goto out;
+ }
+
+ DMWARN("%s path activation fail - error=0x%x",
+ path->dev->name, error);
+ err_flags = MP_FAIL_PATH;
+
+out:
+ req->end_io_data = NULL;
+ __blk_put_request(req->q, req);
+ dm_pg_init_complete(path, err_flags);
+}
+
+/*
+ * hp_sw_get_request - Allocate an HP specific path activation request
+ * @path: path on which request will be sent (needed for request queue)
+ *
+ * The START command is used for path activation request.
+ * These arrays are controller-based failover, not LUN based.
+ * One START command issued to a single path will fail over all
+ * LUNs for the same controller.
+ *
+ * Possible optimizations
+ * 1. Make timeout configurable
+ * 2. Preallocate request
+ */
+static struct request *hp_sw_get_request(struct dm_path *path)
+{
+ struct request *req;
+ struct block_device *bdev = path->dev->bdev;
+ struct request_queue *q = bdev_get_queue(bdev);
+ struct hp_sw_context *h = path->hwhcontext;
+
+ req = blk_get_request(q, WRITE, GFP_NOIO);
+ if (!req)
+ goto out;
+
+ req->timeout = 60 * HZ;
+
+ req->errors = 0;
+ req->cmd_type = REQ_TYPE_BLOCK_PC;
+ req->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+ req->end_io_data = path;
+ req->sense = h->sense;
+ memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE);
+
+ memset(&req->cmd, 0, BLK_MAX_CDB);
+ req->cmd[0] = START_STOP;
+ req->cmd[4] = 1;
+ req->cmd_len = COMMAND_SIZE(req->cmd[0]);
+
+out:
+ return req;
+}
+
+/*
+ * hp_sw_pg_init - HP path activation implementation.
+ * @hwh: hardware handler specific data
+ * @bypassed: unused; is the path group bypassed? (see dm-mpath.c)
+ * @path: path to send initialization command
+ *
+ * Send an HP-specific path activation command on 'path'.
+ * Do not try to optimize in any way, just send the activation command.
+ * More than one path activation command may be sent to the same controller.
+ * This seems to work fine for basic failover support.
+ *
+ * Possible optimizations
+ * 1. Detect an in-progress activation request and avoid submitting another one
+ * 2. Model the controller and only send a single activation request at a time
+ * 3. Determine the state of a path before sending an activation request
+ *
+ * Context: kmpathd (see process_queued_ios() in dm-mpath.c)
+ */
+static void hp_sw_pg_init(struct hw_handler *hwh, unsigned bypassed,
+ struct dm_path *path)
+{
+ struct request *req;
+ struct hp_sw_context *h;
+
+ path->hwhcontext = hwh->context;
+ h = hwh->context;
+
+ req = hp_sw_get_request(path);
+ if (!req) {
+ DMERR("%s path activation command - allocation fail",
+ path->dev->name);
+ goto retry;
+ }
+
+ DMDEBUG("%s path activation command - sent", path->dev->name);
+
+ blk_execute_rq_nowait(req->q, NULL, req, 1, hp_sw_end_io);
+ return;
+
+retry:
+ dm_pg_init_complete(path, MP_RETRY);
+}
+
+static int hp_sw_create(struct hw_handler *hwh, unsigned argc, char **argv)
+{
+ struct hp_sw_context *h;
+
+ h = kmalloc(sizeof(*h), GFP_KERNEL);
+ if (!h)
+ return -ENOMEM;
+
+ hwh->context = h;
+
+ return 0;
+}
+
+static void hp_sw_destroy(struct hw_handler *hwh)
+{
+ struct hp_sw_context *h = hwh->context;
+
+ kfree(h);
+}
+
+static struct hw_handler_type hp_sw_hwh = {
+ .name = DM_HP_HWH_NAME,
+ .module = THIS_MODULE,
+ .create = hp_sw_create,
+ .destroy = hp_sw_destroy,
+ .pg_init = hp_sw_pg_init,
+};
+
+static int __init hp_sw_init(void)
+{
+ int r;
+
+ r = dm_register_hw_handler(&hp_sw_hwh);
+ if (r < 0)
+ DMERR("register failed %d", r);
+ else
+ DMINFO("version " DM_HP_HWH_VER " loaded");
+
+ return r;
+}
+
+static void __exit hp_sw_exit(void)
+{
+ int r;
+
+ r = dm_unregister_hw_handler(&hp_sw_hwh);
+ if (r < 0)
+ DMERR("unregister failed %d", r);
+}
+
+module_init(hp_sw_init);
+module_exit(hp_sw_exit);
+
+MODULE_DESCRIPTION("DM Multipath HP StorageWorks / FSC FibreCat (A/P) support");
+MODULE_AUTHOR("Mike Christie, Dave Wysochanski <dm-devel@redhat.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DM_HP_HWH_VER);
diff --git a/drivers/md/dm-mpath-rdac.c b/drivers/md/dm-mpath-rdac.c
index 16b16134577..e04eb5c697f 100644
--- a/drivers/md/dm-mpath-rdac.c
+++ b/drivers/md/dm-mpath-rdac.c
@@ -664,20 +664,21 @@ static struct hw_handler_type rdac_handler = {
static int __init rdac_init(void)
{
- int r = dm_register_hw_handler(&rdac_handler);
-
- if (r < 0) {
- DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
- return r;
- }
+ int r;
rdac_wkqd = create_singlethread_workqueue("rdac_wkqd");
if (!rdac_wkqd) {
DMERR("Failed to create workqueue rdac_wkqd.");
- dm_unregister_hw_handler(&rdac_handler);
return -ENOMEM;
}
+ r = dm_register_hw_handler(&rdac_handler);
+ if (r < 0) {
+ DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r);
+ destroy_workqueue(rdac_wkqd);
+ return r;
+ }
+
DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER);
return 0;
}
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 31056abca89..24b2b1e32fa 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -10,6 +10,7 @@
#include "dm-hw-handler.h"
#include "dm-bio-list.h"
#include "dm-bio-record.h"
+#include "dm-uevent.h"
#include <linux/ctype.h>
#include <linux/init.h>
@@ -75,6 +76,8 @@ struct multipath {
unsigned queue_io; /* Must we queue all I/O? */
unsigned queue_if_no_path; /* Queue I/O if last path fails? */
unsigned saved_queue_if_no_path;/* Saved state during suspension */
+ unsigned pg_init_retries; /* Number of times to retry pg_init */
+ unsigned pg_init_count; /* Number of times pg_init called */
struct work_struct process_queued_ios;
struct bio_list queued_ios;
@@ -225,6 +228,8 @@ static void __switch_pg(struct multipath *m, struct pgpath *pgpath)
m->pg_init_required = 0;
m->queue_io = 0;
}
+
+ m->pg_init_count = 0;
}
static int __choose_path_in_pg(struct multipath *m, struct priority_group *pg)
@@ -424,6 +429,7 @@ static void process_queued_ios(struct work_struct *work)
must_queue = 0;
if (m->pg_init_required && !m->pg_init_in_progress) {
+ m->pg_init_count++;
m->pg_init_required = 0;
m->pg_init_in_progress = 1;
init_required = 1;
@@ -689,9 +695,11 @@ static int parse_features(struct arg_set *as, struct multipath *m)
int r;
unsigned argc;
struct dm_target *ti = m->ti;
+ const char *param_name;
static struct param _params[] = {
- {0, 1, "invalid number of feature args"},
+ {0, 3, "invalid number of feature args"},
+ {1, 50, "pg_init_retries must be between 1 and 50"},
};
r = read_param(_params, shift(as), &argc, &ti->error);
@@ -701,12 +709,28 @@ static int parse_features(struct arg_set *as, struct multipath *m)
if (!argc)
return 0;
- if (!strnicmp(shift(as), MESG_STR("queue_if_no_path")))
- return queue_if_no_path(m, 1, 0);
- else {
+ do {
+ param_name = shift(as);
+ argc--;
+
+ if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) {
+ r = queue_if_no_path(m, 1, 0);
+ continue;
+ }
+
+ if (!strnicmp(param_name, MESG_STR("pg_init_retries")) &&
+ (argc >= 1)) {
+ r = read_param(_params + 1, shift(as),
+ &m->pg_init_retries, &ti->error);
+ argc--;
+ continue;
+ }
+
ti->error = "Unrecognised multipath feature request";
- return -EINVAL;
- }
+ r = -EINVAL;
+ } while (argc && !r);
+
+ return r;
}
static int multipath_ctr(struct dm_target *ti, unsigned int argc,
@@ -834,6 +858,9 @@ static int fail_path(struct pgpath *pgpath)
if (pgpath == m->current_pgpath)
m->current_pgpath = NULL;
+ dm_path_uevent(DM_UEVENT_PATH_FAILED, m->ti,
+ pgpath->path.dev->name, m->nr_valid_paths);
+
queue_work(kmultipathd, &m->trigger_event);
out:
@@ -873,6 +900,9 @@ static int reinstate_path(struct pgpath *pgpath)
if (!m->nr_valid_paths++ && m->queue_size)
queue_work(kmultipathd, &m->process_queued_ios);
+ dm_path_uevent(DM_UEVENT_PATH_REINSTATED, m->ti,
+ pgpath->path.dev->name, m->nr_valid_paths);
+
queue_work(kmultipathd, &m->trigger_event);
out:
@@ -976,6 +1006,26 @@ static int bypass_pg_num(struct multipath *m, const char *pgstr, int bypassed)
}
/*
+ * Should we retry pg_init immediately?
+ */
+static int pg_init_limit_reached(struct multipath *m, struct pgpath *pgpath)
+{
+ unsigned long flags;
+ int limit_reached = 0;
+
+ spin_lock_irqsave(&m->lock, flags);
+
+ if (m->pg_init_count <= m->pg_init_retries)
+ m->pg_init_required = 1;
+ else
+ limit_reached = 1;
+
+ spin_unlock_irqrestore(&m->lock, flags);
+
+ return limit_reached;
+}
+
+/*
* pg_init must call this when it has completed its initialisation
*/
void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
@@ -985,8 +1035,14 @@ void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
struct multipath *m = pg->m;
unsigned long flags;
- /* We insist on failing the path if the PG is already bypassed. */
- if (err_flags && pg->bypassed)
+ /*
+ * If requested, retry pg_init until maximum number of retries exceeded.
+ * If retry not requested and PG already bypassed, always fail the path.
+ */
+ if (err_flags & MP_RETRY) {
+ if (pg_init_limit_reached(m, pgpath))
+ err_flags |= MP_FAIL_PATH;
+ } else if (err_flags && pg->bypassed)
err_flags |= MP_FAIL_PATH;
if (err_flags & MP_FAIL_PATH)
@@ -996,7 +1052,7 @@ void dm_pg_init_complete(struct dm_path *path, unsigned err_flags)
bypass_pg(m, pg, 1);
spin_lock_irqsave(&m->lock, flags);
- if (err_flags) {
+ if (err_flags & ~MP_RETRY) {
m->current_pgpath = NULL;
m->current_pg = NULL;
} else if (!m->pg_init_required)
@@ -1148,11 +1204,15 @@ static int multipath_status(struct dm_target *ti, status_type_t type,
/* Features */
if (type == STATUSTYPE_INFO)
- DMEMIT("1 %u ", m->queue_size);
- else if (m->queue_if_no_path)
- DMEMIT("1 queue_if_no_path ");
- else
- DMEMIT("0 ");
+ DMEMIT("2 %u %u ", m->queue_size, m->pg_init_count);
+ else {
+ DMEMIT("%u ", m->queue_if_no_path +
+ (m->pg_init_retries > 0) * 2);
+ if (m->queue_if_no_path)
+ DMEMIT("queue_if_no_path ");
+ if (m->pg_init_retries)
+ DMEMIT("pg_init_retries %u ", m->pg_init_retries);
+ }
if (hwh->type && hwh->type->status)
sz += hwh->type->status(hwh, type, result + sz, maxlen - sz);
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index f10a0c89b3f..ca1bb636a3e 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -94,12 +94,10 @@ out:
static struct ps_internal *_alloc_path_selector(struct path_selector_type *pst)
{
- struct ps_internal *psi = kmalloc(sizeof(*psi), GFP_KERNEL);
+ struct ps_internal *psi = kzalloc(sizeof(*psi), GFP_KERNEL);
- if (psi) {
- memset(psi, 0, sizeof(*psi));
+ if (psi)
psi->pst = *pst;
- }
return psi;
}
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index d09ff15490a..31123d4a6b9 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -19,6 +19,7 @@
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
+#include <linux/log2.h>
#define DM_MSG_PREFIX "raid1"
#define DM_IO_PAGES 64
@@ -113,6 +114,7 @@ struct region {
* Mirror set structures.
*---------------------------------------------------------------*/
struct mirror {
+ struct mirror_set *ms;
atomic_t error_count;
struct dm_dev *dev;
sector_t offset;
@@ -974,6 +976,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
ti->error = "Error creating dirty region hash";
+ dm_io_client_destroy(ms->io_client);
kfree(ms);
return NULL;
}
@@ -994,7 +997,7 @@ static void free_context(struct mirror_set *ms, struct dm_target *ti,
static inline int _check_region_size(struct dm_target *ti, uint32_t size)
{
- return !(size % (PAGE_SIZE >> 9) || (size & (size - 1)) ||
+ return !(size % (PAGE_SIZE >> 9) || !is_power_of_2(size) ||
size > ti->len);
}
@@ -1015,6 +1018,7 @@ static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
return -ENXIO;
}
+ ms->mirror[mirror].ms = ms;
ms->mirror[mirror].offset = offset;
return 0;
@@ -1163,16 +1167,14 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
if (!ms->kmirrord_wq) {
DMERR("couldn't start kmirrord");
- free_context(ms, ti, m);
- return -ENOMEM;
+ r = -ENOMEM;
+ goto err_free_context;
}
INIT_WORK(&ms->kmirrord_work, do_mirror);
r = parse_features(ms, argc, argv, &args_used);
- if (r) {
- free_context(ms, ti, ms->nr_mirrors);
- return r;
- }
+ if (r)
+ goto err_destroy_wq;
argv += args_used;
argc -= args_used;
@@ -1188,19 +1190,22 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
if (argc) {
ti->error = "Too many mirror arguments";
- free_context(ms, ti, ms->nr_mirrors);
- return -EINVAL;
+ r = -EINVAL;
+ goto err_destroy_wq;
}
r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
- if (r) {
- destroy_workqueue(ms->kmirrord_wq);
- free_context(ms, ti, ms->nr_mirrors);
- return r;
- }
+ if (r)
+ goto err_destroy_wq;
wake(ms);
return 0;
+
+err_destroy_wq:
+ destroy_workqueue(ms->kmirrord_wq);
+err_free_context:
+ free_context(ms, ti, ms->nr_mirrors);
+ return r;
}
static void mirror_dtr(struct dm_target *ti)
@@ -1302,7 +1307,7 @@ static void mirror_postsuspend(struct dm_target *ti)
wait_event(_kmirrord_recovery_stopped,
!atomic_read(&ms->rh.recovery_in_flight));
- if (log->type->suspend && log->type->suspend(log))
+ if (log->type->postsuspend && log->type->postsuspend(log))
/* FIXME: need better error handling */
DMWARN("log suspend failed");
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 98a633f3d6b..cee16fadd9e 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/log2.h>
#include "dm-snap.h"
#include "dm-bio-list.h"
@@ -415,7 +416,7 @@ static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
/* Check chunk_size is a power of 2 */
- if (chunk_size & (chunk_size - 1)) {
+ if (!is_power_of_2(chunk_size)) {
*error = "Chunk size is not a power of 2";
return -EINVAL;
}
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 51f5e076001..969944a8aba 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -11,6 +11,7 @@
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/slab.h>
+#include <linux/log2.h>
#define DM_MSG_PREFIX "striped"
@@ -99,7 +100,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
/*
* chunk_size is a power of two
*/
- if (!chunk_size || (chunk_size & (chunk_size - 1)) ||
+ if (!is_power_of_2(chunk_size) ||
(chunk_size < (PAGE_SIZE >> SECTOR_SHIFT))) {
ti->error = "Invalid chunk size";
return -EINVAL;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index fbe477bb2c6..8939e610508 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -213,12 +213,11 @@ static int alloc_targets(struct dm_table *t, unsigned int num)
int dm_table_create(struct dm_table **result, int mode,
unsigned num_targets, struct mapped_device *md)
{
- struct dm_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
+ struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL);
if (!t)
return -ENOMEM;
- memset(t, 0, sizeof(*t));
INIT_LIST_HEAD(&t->devices);
atomic_set(&t->holders, 1);
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 477a041a41c..835cf95b857 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -88,12 +88,10 @@ void dm_put_target_type(struct target_type *t)
static struct tt_internal *alloc_target(struct target_type *t)
{
- struct tt_internal *ti = kmalloc(sizeof(*ti), GFP_KERNEL);
+ struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
- if (ti) {
- memset(ti, 0, sizeof(*ti));
+ if (ti)
ti->tt = *t;
- }
return ti;
}
diff --git a/drivers/md/dm-uevent.c b/drivers/md/dm-uevent.c
new file mode 100644
index 00000000000..50377e5dc2a
--- /dev/null
+++ b/drivers/md/dm-uevent.c
@@ -0,0 +1,222 @@
+/*
+ * Device Mapper Uevent Support (dm-uevent)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ * Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/kobject.h>
+#include <linux/dm-ioctl.h>
+
+#include "dm.h"
+#include "dm-uevent.h"
+
+#define DM_MSG_PREFIX "uevent"
+
+static const struct {
+ enum dm_uevent_type type;
+ enum kobject_action action;
+ char *name;
+} _dm_uevent_type_names[] = {
+ {DM_UEVENT_PATH_FAILED, KOBJ_CHANGE, "PATH_FAILED"},
+ {DM_UEVENT_PATH_REINSTATED, KOBJ_CHANGE, "PATH_REINSTATED"},
+};
+
+static struct kmem_cache *_dm_event_cache;
+
+struct dm_uevent {
+ struct mapped_device *md;
+ enum kobject_action action;
+ struct kobj_uevent_env ku_env;
+ struct list_head elist;
+ char name[DM_NAME_LEN];
+ char uuid[DM_UUID_LEN];
+};
+
+static void dm_uevent_free(struct dm_uevent *event)
+{
+ kmem_cache_free(_dm_event_cache, event);
+}
+
+static struct dm_uevent *dm_uevent_alloc(struct mapped_device *md)
+{
+ struct dm_uevent *event;
+
+ event = kmem_cache_zalloc(_dm_event_cache, GFP_ATOMIC);
+ if (!event)
+ return NULL;
+
+ INIT_LIST_HEAD(&event->elist);
+ event->md = md;
+
+ return event;
+}
+
+static struct dm_uevent *dm_build_path_uevent(struct mapped_device *md,
+ struct dm_target *ti,
+ enum kobject_action action,
+ const char *dm_action,
+ const char *path,
+ unsigned nr_valid_paths)
+{
+ struct dm_uevent *event;
+
+ event = dm_uevent_alloc(md);
+ if (!event) {
+ DMERR("%s: dm_uevent_alloc() failed", __FUNCTION__);
+ goto err_nomem;
+ }
+
+ event->action = action;
+
+ if (add_uevent_var(&event->ku_env, "DM_TARGET=%s", ti->type->name)) {
+ DMERR("%s: add_uevent_var() for DM_TARGET failed",
+ __FUNCTION__);
+ goto err_add;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_ACTION=%s", dm_action)) {
+ DMERR("%s: add_uevent_var() for DM_ACTION failed",
+ __FUNCTION__);
+ goto err_add;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_SEQNUM=%u",
+ dm_next_uevent_seq(md))) {
+ DMERR("%s: add_uevent_var() for DM_SEQNUM failed",
+ __FUNCTION__);
+ goto err_add;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_PATH=%s", path)) {
+ DMERR("%s: add_uevent_var() for DM_PATH failed", __FUNCTION__);
+ goto err_add;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_NR_VALID_PATHS=%d",
+ nr_valid_paths)) {
+ DMERR("%s: add_uevent_var() for DM_NR_VALID_PATHS failed",
+ __FUNCTION__);
+ goto err_add;
+ }
+
+ return event;
+
+err_add:
+ dm_uevent_free(event);
+err_nomem:
+ return ERR_PTR(-ENOMEM);
+}
+
+/**
+ * dm_send_uevents - send uevents for given list
+ *
+ * @events: list of events to send
+ * @kobj: kobject generating event
+ *
+ */
+void dm_send_uevents(struct list_head *events, struct kobject *kobj)
+{
+ int r;
+ struct dm_uevent *event, *next;
+
+ list_for_each_entry_safe(event, next, events, elist) {
+ list_del_init(&event->elist);
+
+ /*
+ * Need to call dm_copy_name_and_uuid from here for now.
+ * Context of previous var adds and locking used for
+ * hash_cell not compatable.
+ */
+ if (dm_copy_name_and_uuid(event->md, event->name,
+ event->uuid)) {
+ DMERR("%s: dm_copy_name_and_uuid() failed",
+ __FUNCTION__);
+ goto uevent_free;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_NAME=%s", event->name)) {
+ DMERR("%s: add_uevent_var() for DM_NAME failed",
+ __FUNCTION__);
+ goto uevent_free;
+ }
+
+ if (add_uevent_var(&event->ku_env, "DM_UUID=%s", event->uuid)) {
+ DMERR("%s: add_uevent_var() for DM_UUID failed",
+ __FUNCTION__);
+ goto uevent_free;
+ }
+
+ r = kobject_uevent_env(kobj, event->action, event->ku_env.envp);
+ if (r)
+ DMERR("%s: kobject_uevent_env failed", __FUNCTION__);
+uevent_free:
+ dm_uevent_free(event);
+ }
+}
+EXPORT_SYMBOL_GPL(dm_send_uevents);
+
+/**
+ * dm_path_uevent - called to create a new path event and queue it
+ *
+ * @event_type: path event type enum
+ * @ti: pointer to a dm_target
+ * @path: string containing pathname
+ * @nr_valid_paths: number of valid paths remaining
+ *
+ */
+void dm_path_uevent(enum dm_uevent_type event_type, struct dm_target *ti,
+ const char *path, unsigned nr_valid_paths)
+{
+ struct mapped_device *md = dm_table_get_md(ti->table);
+ struct dm_uevent *event;
+
+ if (event_type >= ARRAY_SIZE(_dm_uevent_type_names)) {
+ DMERR("%s: Invalid event_type %d", __FUNCTION__, event_type);
+ goto out;
+ }
+
+ event = dm_build_path_uevent(md, ti,
+ _dm_uevent_type_names[event_type].action,
+ _dm_uevent_type_names[event_type].name,
+ path, nr_valid_paths);
+ if (IS_ERR(event))
+ goto out;
+
+ dm_uevent_add(md, &event->elist);
+
+out:
+ dm_put(md);
+}
+EXPORT_SYMBOL_GPL(dm_path_uevent);
+
+int dm_uevent_init(void)
+{
+ _dm_event_cache = KMEM_CACHE(dm_uevent, 0);
+ if (!_dm_event_cache)
+ return -ENOMEM;
+
+ DMINFO("version 1.0.3");
+
+ return 0;
+}
+
+void dm_uevent_exit(void)
+{
+ kmem_cache_destroy(_dm_event_cache);
+}
diff --git a/drivers/md/dm-uevent.h b/drivers/md/dm-uevent.h
new file mode 100644
index 00000000000..2eccc8bd671
--- /dev/null
+++ b/drivers/md/dm-uevent.h
@@ -0,0 +1,59 @@
+/*
+ * Device Mapper Uevent Support
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright IBM Corporation, 2007
+ * Author: Mike Anderson <andmike@linux.vnet.ibm.com>
+ */
+#ifndef DM_UEVENT_H
+#define DM_UEVENT_H
+
+enum dm_uevent_type {
+ DM_UEVENT_PATH_FAILED,
+ DM_UEVENT_PATH_REINSTATED,
+};
+
+#ifdef CONFIG_DM_UEVENT
+
+extern int dm_uevent_init(void);
+extern void dm_uevent_exit(void);
+extern void dm_send_uevents(struct list_head *events, struct kobject *kobj);
+extern void dm_path_uevent(enum dm_uevent_type event_type,
+ struct dm_target *ti, const char *path,
+ unsigned nr_valid_paths);
+
+#else
+
+static inline int dm_uevent_init(void)
+{
+ return 0;
+}
+static inline void dm_uevent_exit(void)
+{
+}
+static inline void dm_send_uevents(struct list_head *events,
+ struct kobject *kobj)
+{
+}
+static inline void dm_path_uevent(enum dm_uevent_type event_type,
+ struct dm_target *ti, const char *path,
+ unsigned nr_valid_paths)
+{
+}
+
+#endif /* CONFIG_DM_UEVENT */
+
+#endif /* DM_UEVENT_H */
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index d837d37f620..07cbbb8eb3e 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -7,6 +7,7 @@
#include "dm.h"
#include "dm-bio-list.h"
+#include "dm-uevent.h"
#include <linux/init.h>
#include <linux/module.h>
@@ -112,6 +113,9 @@ struct mapped_device {
*/
atomic_t event_nr;
wait_queue_head_t eventq;
+ atomic_t uevent_seq;
+ struct list_head uevent_list;
+ spinlock_t uevent_lock; /* Protect access to uevent_list */
/*
* freeze/thaw support require holding onto a super block
@@ -143,11 +147,19 @@ static int __init local_init(void)
return -ENOMEM;
}
+ r = dm_uevent_init();
+ if (r) {
+ kmem_cache_destroy(_tio_cache);
+ kmem_cache_destroy(_io_cache);
+ return r;
+ }
+
_major = major;
r = register_blkdev(_major, _name);
if (r < 0) {
kmem_cache_destroy(_tio_cache);
kmem_cache_destroy(_io_cache);
+ dm_uevent_exit();
return r;
}
@@ -162,6 +174,7 @@ static void local_exit(void)
kmem_cache_destroy(_tio_cache);
kmem_cache_destroy(_io_cache);
unregister_blkdev(_major, _name);
+ dm_uevent_exit();
_major = 0;
@@ -751,15 +764,13 @@ static void __clone_and_map(struct clone_info *ci)
/*
* Split the bio into several clones.
*/
-static void __split_bio(struct mapped_device *md, struct bio *bio)
+static int __split_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
ci.map = dm_get_table(md);
- if (!ci.map) {
- bio_io_error(bio);
- return;
- }
+ if (unlikely(!ci.map))
+ return -EIO;
ci.md = md;
ci.bio = bio;
@@ -779,6 +790,8 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
/* drop the extra reference count */
dec_pending(ci.io, 0);
dm_table_put(ci.map);
+
+ return 0;
}
/*-----------------------------------------------------------------
* CRUD END
@@ -790,7 +803,7 @@ static void __split_bio(struct mapped_device *md, struct bio *bio)
*/
static int dm_request(struct request_queue *q, struct bio *bio)
{
- int r;
+ int r = -EIO;
int rw = bio_data_dir(bio);
struct mapped_device *md = q->queuedata;
@@ -815,18 +828,11 @@ static int dm_request(struct request_queue *q, struct bio *bio)
while (test_bit(DMF_BLOCK_IO, &md->flags)) {
up_read(&md->io_lock);
- if (bio_rw(bio) == READA) {
- bio_io_error(bio);
- return 0;
- }
-
- r = queue_io(md, bio);
- if (r < 0) {
- bio_io_error(bio);
- return 0;
+ if (bio_rw(bio) != READA)
+ r = queue_io(md, bio);
- } else if (r == 0)
- return 0; /* deferred successfully */
+ if (r <= 0)
+ goto out_req;
/*
* We're in a while loop, because someone could suspend
@@ -835,8 +841,13 @@ static int dm_request(struct request_queue *q, struct bio *bio)
down_read(&md->io_lock);
}
- __split_bio(md, bio);
+ r = __split_bio(md, bio);
up_read(&md->io_lock);
+
+out_req:
+ if (r < 0)
+ bio_io_error(bio);
+
return 0;
}
@@ -977,6 +988,9 @@ static struct mapped_device *alloc_dev(int minor)
atomic_set(&md->holders, 1);
atomic_set(&md->open_count, 0);
atomic_set(&md->event_nr, 0);
+ atomic_set(&md->uevent_seq, 0);
+ INIT_LIST_HEAD(&md->uevent_list);
+ spin_lock_init(&md->uevent_lock);
md->queue = blk_alloc_queue(GFP_KERNEL);
if (!md->queue)
@@ -1044,12 +1058,14 @@ static struct mapped_device *alloc_dev(int minor)
return NULL;
}
+static void unlock_fs(struct mapped_device *md);
+
static void free_dev(struct mapped_device *md)
{
int minor = md->disk->first_minor;
if (md->suspended_bdev) {
- thaw_bdev(md->suspended_bdev, NULL);
+ unlock_fs(md);
bdput(md->suspended_bdev);
}
mempool_destroy(md->tio_pool);
@@ -1073,8 +1089,16 @@ static void free_dev(struct mapped_device *md)
*/
static void event_callback(void *context)
{
+ unsigned long flags;
+ LIST_HEAD(uevents);
struct mapped_device *md = (struct mapped_device *) context;
+ spin_lock_irqsave(&md->uevent_lock, flags);
+ list_splice_init(&md->uevent_list, &uevents);
+ spin_unlock_irqrestore(&md->uevent_lock, flags);
+
+ dm_send_uevents(&uevents, &md->disk->kobj);
+
atomic_inc(&md->event_nr);
wake_up(&md->eventq);
}
@@ -1233,7 +1257,8 @@ static void __flush_deferred_io(struct mapped_device *md, struct bio *c)
while (c) {
n = c->bi_next;
c->bi_next = NULL;
- __split_bio(md, c);
+ if (__split_bio(md, c))
+ bio_io_error(c);
c = n;
}
}
@@ -1491,6 +1516,11 @@ out:
/*-----------------------------------------------------------------
* Event notification.
*---------------------------------------------------------------*/
+uint32_t dm_next_uevent_seq(struct mapped_device *md)
+{
+ return atomic_add_return(1, &md->uevent_seq);
+}
+
uint32_t dm_get_event_nr(struct mapped_device *md)
{
return atomic_read(&md->event_nr);
@@ -1502,6 +1532,15 @@ int dm_wait_event(struct mapped_device *md, int event_nr)
(event_nr != atomic_read(&md->event_nr)));
}
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&md->uevent_lock, flags);
+ list_add(elist, &md->uevent_list);
+ spin_unlock_irqrestore(&md->uevent_lock, flags);
+}
+
/*
* The gendisk is only valid as long as you have a reference
* count on 'md'.
diff --git a/drivers/md/kcopyd.c b/drivers/md/kcopyd.c
index 7e052378c47..f3831f31223 100644
--- a/drivers/md/kcopyd.c
+++ b/drivers/md/kcopyd.c
@@ -198,7 +198,7 @@ struct kcopyd_job {
* These fields are only used if the job has been split
* into more manageable parts.
*/
- struct semaphore lock;
+ struct mutex lock;
atomic_t sub_jobs;
sector_t progress;
};
@@ -456,7 +456,7 @@ static void segment_complete(int read_err,
sector_t count = 0;
struct kcopyd_job *job = (struct kcopyd_job *) context;
- down(&job->lock);
+ mutex_lock(&job->lock);
/* update the error */
if (read_err)
@@ -480,7 +480,7 @@ static void segment_complete(int read_err,
job->progress += count;
}
}
- up(&job->lock);
+ mutex_unlock(&job->lock);
if (count) {
int i;
@@ -562,7 +562,7 @@ int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
dispatch_job(job);
else {
- init_MUTEX(&job->lock);
+ mutex_init(&job->lock);
job->progress = 0;
split_job(job);
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c059ae6f37e..808cd954945 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4717,7 +4717,7 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
void md_unregister_thread(mdk_thread_t *thread)
{
- dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid);
+ dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
kthread_stop(thread->tsk);
kfree(thread);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 16775a0df7f..85478d6a9c1 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -9,7 +9,7 @@
*
* Better read-balancing code written by Mika Kuoppala <miku@iki.fi>, 2000
*
- * Fixes to reconstruction by Jakob stergaard" <jakob@ostenfeld.dk>
+ * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
* Various fixes by Neil Brown <neilb@cse.unsw.edu.au>
*
* Changes by Peter T. Breuer <ptb@it.uc3m.es> 31/1/2003 to support
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index aefcf28da1c..185e8a860c1 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1074,41 +1074,41 @@ EXPORT_SYMBOL_GPL(ir_codes_manli);
/* Mike Baikov <mike@baikov.com> */
IR_KEYTAB_TYPE ir_codes_gotview7135[IR_KEYTAB_SIZE] = {
- [ 0x21 ] = KEY_POWER,
- [ 0x69 ] = KEY_TV,
- [ 0x33 ] = KEY_0,
- [ 0x51 ] = KEY_1,
- [ 0x31 ] = KEY_2,
- [ 0x71 ] = KEY_3,
- [ 0x3b ] = KEY_4,
- [ 0x58 ] = KEY_5,
- [ 0x41 ] = KEY_6,
- [ 0x48 ] = KEY_7,
- [ 0x30 ] = KEY_8,
- [ 0x53 ] = KEY_9,
- [ 0x73 ] = KEY_AGAIN, /* LOOP */
- [ 0x0a ] = KEY_AUDIO,
- [ 0x61 ] = KEY_PRINT, /* PREVIEW */
- [ 0x7a ] = KEY_VIDEO,
- [ 0x20 ] = KEY_CHANNELUP,
- [ 0x40 ] = KEY_CHANNELDOWN,
- [ 0x18 ] = KEY_VOLUMEDOWN,
- [ 0x50 ] = KEY_VOLUMEUP,
- [ 0x10 ] = KEY_MUTE,
- [ 0x4a ] = KEY_SEARCH,
- [ 0x7b ] = KEY_SHUFFLE, /* SNAPSHOT */
- [ 0x22 ] = KEY_RECORD,
- [ 0x62 ] = KEY_STOP,
- [ 0x78 ] = KEY_PLAY,
- [ 0x39 ] = KEY_REWIND,
- [ 0x59 ] = KEY_PAUSE,
- [ 0x19 ] = KEY_FORWARD,
- [ 0x09 ] = KEY_ZOOM,
-
- [ 0x52 ] = KEY_F21, /* LIVE TIMESHIFT */
- [ 0x1a ] = KEY_F22, /* MIN TIMESHIFT */
- [ 0x3a ] = KEY_F23, /* TIMESHIFT */
- [ 0x70 ] = KEY_F24, /* NORMAL TIMESHIFT */
+ [ 0x11 ] = KEY_POWER,
+ [ 0x35 ] = KEY_TV,
+ [ 0x1b ] = KEY_0,
+ [ 0x29 ] = KEY_1,
+ [ 0x19 ] = KEY_2,
+ [ 0x39 ] = KEY_3,
+ [ 0x1f ] = KEY_4,
+ [ 0x2c ] = KEY_5,
+ [ 0x21 ] = KEY_6,
+ [ 0x24 ] = KEY_7,
+ [ 0x18 ] = KEY_8,
+ [ 0x2b ] = KEY_9,
+ [ 0x3b ] = KEY_AGAIN, /* LOOP */
+ [ 0x06 ] = KEY_AUDIO,
+ [ 0x31 ] = KEY_PRINT, /* PREVIEW */
+ [ 0x3e ] = KEY_VIDEO,
+ [ 0x10 ] = KEY_CHANNELUP,
+ [ 0x20 ] = KEY_CHANNELDOWN,
+ [ 0x0c ] = KEY_VOLUMEDOWN,
+ [ 0x28 ] = KEY_VOLUMEUP,
+ [ 0x08 ] = KEY_MUTE,
+ [ 0x26 ] = KEY_SEARCH, /*SCAN*/
+ [ 0x3f ] = KEY_SHUFFLE, /* SNAPSHOT */
+ [ 0x12 ] = KEY_RECORD,
+ [ 0x32 ] = KEY_STOP,
+ [ 0x3c ] = KEY_PLAY,
+ [ 0x1d ] = KEY_REWIND,
+ [ 0x2d ] = KEY_PAUSE,
+ [ 0x0d ] = KEY_FORWARD,
+ [ 0x05 ] = KEY_ZOOM, /*FULL*/
+
+ [ 0x2a ] = KEY_F21, /* LIVE TIMESHIFT */
+ [ 0x0e ] = KEY_F22, /* MIN TIMESHIFT */
+ [ 0x1e ] = KEY_F23, /* TIMESHIFT */
+ [ 0x38 ] = KEY_F24, /* NORMAL TIMESHIFT */
};
EXPORT_SYMBOL_GPL(ir_codes_gotview7135);
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index 365a22118a0..2b1f8b4be00 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -112,12 +112,13 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
+ sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
if (NULL == pg)
goto err;
BUG_ON(PageHighMem(pg));
- sglist[i].page = pg;
+ sg_set_page(&sglist[i], pg);
sglist[i].length = PAGE_SIZE;
}
return sglist;
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c
index d2905720eb7..9c905399a23 100644
--- a/drivers/media/common/saa7146_hlp.c
+++ b/drivers/media/common/saa7146_hlp.c
@@ -312,7 +312,7 @@ static int sort_and_eliminate(u32* values, int* count)
return -EINVAL;
}
- /* bubble sort the first count items of the array values */
+ /* bubble sort the first @count items of the array @values */
for( top = *count; top > 0; top--) {
for( low = 0, high = 1; high < top; low++, high++) {
if( values[low] > values[high] ) {
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c
index eca602d9b3d..85e36a1d6d7 100644
--- a/drivers/media/dvb/bt8xx/bt878.c
+++ b/drivers/media/dvb/bt8xx/bt878.c
@@ -280,7 +280,7 @@ static irqreturn_t bt878_irq(int irq, void *dev_id)
if (!(astat = (stat & mask)))
return IRQ_NONE; /* this interrupt is not for me */
/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */
- btwrite(astat, BT878_AINT_STAT); /* try to clear interupt condition */
+ btwrite(astat, BT878_AINT_STAT); /* try to clear interrupt condition */
if (astat & (BT878_ASCERR | BT878_AOCERR)) {
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 5a12b567955..db08b0a8888 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -1,5 +1,5 @@
/*
- * TerraTec Cinergy T/qanu USB2 DVB-T adapter.
+ * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
*
* Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
* Holger Waechtler <holger@qanu.de>
@@ -345,7 +345,9 @@ static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
struct dvb_demux *demux = dvbdmxfeed->demux;
struct cinergyt2 *cinergyt2 = demux->priv;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending)
+ return -EAGAIN;
+ if (mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (cinergyt2->streaming == 0)
@@ -361,7 +363,9 @@ static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
struct dvb_demux *demux = dvbdmxfeed->demux;
struct cinergyt2 *cinergyt2 = demux->priv;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending)
+ return -EAGAIN;
+ if (mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
if (--cinergyt2->streaming == 0)
@@ -481,12 +485,16 @@ static int cinergyt2_open (struct inode *inode, struct file *file)
{
struct dvb_device *dvbdev = file->private_data;
struct cinergyt2 *cinergyt2 = dvbdev->priv;
- int err = -ERESTARTSYS;
+ int err = -EAGAIN;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+ if (cinergyt2->disconnect_pending)
+ goto out;
+ err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+ if (err)
goto out;
- if (mutex_lock_interruptible(&cinergyt2->sem))
+ err = mutex_lock_interruptible(&cinergyt2->sem);
+ if (err)
goto out_unlock1;
if ((err = dvb_generic_open(inode, file)))
@@ -550,7 +558,9 @@ static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct
struct cinergyt2 *cinergyt2 = dvbdev->priv;
unsigned int mask = 0;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending)
+ return -EAGAIN;
+ if (mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
poll_wait(file, &cinergyt2->poll_wq, wait);
@@ -625,7 +635,9 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file,
if (copy_from_user(&p, (void __user*) arg, sizeof(p)))
return -EFAULT;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem))
+ if (cinergyt2->disconnect_pending)
+ return -EAGAIN;
+ if (mutex_lock_interruptible(&cinergyt2->sem))
return -ERESTARTSYS;
param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
@@ -820,7 +832,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
input_dev->name = DRIVER_NAME " remote control";
input_dev->phys = cinergyt2->phys;
- input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3)
set_bit(rc_keys[i + 2], input_dev->keybit);
input_dev->keycodesize = 0;
@@ -996,7 +1008,9 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
{
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+ if (cinergyt2->disconnect_pending)
+ return -EAGAIN;
+ if (mutex_lock_interruptible(&cinergyt2->wq_sem))
return -ERESTARTSYS;
cinergyt2_suspend_rc(cinergyt2);
@@ -1017,16 +1031,18 @@ static int cinergyt2_resume (struct usb_interface *intf)
{
struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
struct dvbt_set_parameters_msg *param = &cinergyt2->param;
- int err = -ERESTARTSYS;
+ int err = -EAGAIN;
- if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->wq_sem))
+ if (cinergyt2->disconnect_pending)
+ goto out;
+ err = mutex_lock_interruptible(&cinergyt2->wq_sem);
+ if (err)
goto out;
- if (mutex_lock_interruptible(&cinergyt2->sem))
+ err = mutex_lock_interruptible(&cinergyt2->sem);
+ if (err)
goto out_unlock1;
- err = 0;
-
if (!cinergyt2->sleeping) {
cinergyt2_sleep(cinergyt2, 0);
cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 084a508a03d..89437fdab8b 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -972,7 +972,7 @@ static int dvb_ca_en50221_thread(void *data)
/* main loop */
while (!kthread_should_stop()) {
/* sleep for a bit */
- while (!ca->wakeup) {
+ if (!ca->wakeup) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(ca->delay);
if (kthread_should_stop())
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index e8c4a869453..58452b52002 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -828,7 +828,7 @@ MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
#define DIB0700_DEFAULT_DEVICE_PROPERTIES \
.caps = DVB_USB_IS_AN_I2C_ADAPTER, \
.usb_ctrl = DEVICE_SPECIFIC, \
- .firmware = "dvb-usb-dib0700-03-pre1.fw", \
+ .firmware = "dvb-usb-dib0700-1.10.fw", \
.download_firmware = dib0700_download_firmware, \
.no_reconnect = 1, \
.size_of_priv = sizeof(struct dib0700_state), \
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index 7b9f35bfb4f..c0c2c22ddd8 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -106,7 +106,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
if (!input_dev)
return -ENOMEM;
- input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->name = "IR-receiver inside an USB DVB receiver";
input_dev->phys = d->rc_phys;
usb_to_input_id(d->udev, &input_dev->id);
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 5d19c402dad..a283e1de83f 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -27,7 +27,7 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include "av7110.h"
#include "av7110_hw.h"
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 288e79f2cb0..7902ae1d9a1 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -128,7 +128,7 @@ struct ttusb {
struct dvb_frontend* fe;
};
-/* ugly workaround ... don't know why it's neccessary to read */
+/* ugly workaround ... don't know why it's necessary to read */
/* all result codes. */
#define DEBUG 0
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 5e691fd7990..1ec981d98b9 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec)
input_dev->name = "ttusb_dec remote control";
input_dev->phys = dec->rc_phys;
- input_dev->evbit[0] = BIT(EV_KEY);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
input_dev->keycodesize = sizeof(u16);
input_dev->keycodemax = 0x1a;
input_dev->keycode = rc_keys;
diff --git a/drivers/media/radio/miropcm20-radio.c b/drivers/media/radio/miropcm20-radio.c
index c7c9d1dc069..3ae56fef8c9 100644
--- a/drivers/media/radio/miropcm20-radio.c
+++ b/drivers/media/radio/miropcm20-radio.c
@@ -229,7 +229,6 @@ static struct video_device pcm20_radio = {
.owner = THIS_MODULE,
.name = "Miro PCM 20 radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_RTRACK,
.fops = &pcm20_fops,
.priv = &pcm20_unit
};
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 0c963db0361..5e4b9ddb23c 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -554,7 +554,6 @@ static struct video_device gemtek_radio = {
.owner = THIS_MODULE,
.name = "GemTek Radio card",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_GEMTEK,
.fops = &gemtek_fops,
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c
index 19e9929ffa0..c94a4d0f280 100644
--- a/drivers/media/video/arv.c
+++ b/drivers/media/video/arv.c
@@ -755,7 +755,6 @@ static struct video_device ar_template = {
.owner = THIS_MODULE,
.name = "Colour AR VGA",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_ARV,
.fops = &ar_fops,
.release = ar_release,
.minor = -1,
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index dd6a7d68b07..3abd9fa54d2 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -1259,7 +1259,7 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
},
[BTTV_BOARD_LIFETEC_9415] = {
- /* Tim Rstermundt <rosterm@uni-muenster.de>
+ /* Tim Röstermundt <rosterm@uni-muenster.de>
in de.comp.os.unix.linux.hardware:
options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
@@ -2824,7 +2824,7 @@ struct tvcard bttv_tvcards[] = {
},
/* ---- card 0x8b ---------------------------------- */
[BTTV_BOARD_PV_M4900] = {
- /* Srgio Fortier <sergiofortier@yahoo.com.br> */
+ /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
.name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
.video_inputs = 3,
.audio_inputs = 1,
@@ -4709,18 +4709,18 @@ adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
*
* The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
* GPIO pins are wired as:
- * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
- * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
- * GPIO[7] - DATA (xpoint) - P1[7] (microcontroler)
- * GPIO[8] - - P3[5] (microcontroler)
- * GPIO[9] - RESET (xpoint) - P3[6] (microcontroler)
- * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroler)
- * GPINTR - - P3[4] (microcontroler)
+ * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroller)
+ * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroller)
+ * GPIO[7] - DATA (xpoint) - P1[7] (microcontroller)
+ * GPIO[8] - - P3[5] (microcontroller)
+ * GPIO[9] - RESET (xpoint) - P3[6] (microcontroller)
+ * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroller)
+ * GPINTR - - P3[4] (microcontroller)
*
- * The microcontroler is a 80C32 like. It should be possible to change xpoint
- * configuration either directly (as we are doing) or using the microcontroler
+ * The microcontroller is a 80C32 like. It should be possible to change xpoint
+ * configuration either directly (as we are doing) or using the microcontroller
* which is also wired to I2C interface. I have no further info on the
- * microcontroler features, one would need to disassembly the firmware.
+ * microcontroller features, one would need to disassembly the firmware.
* note: the vendor refused to give any information on this product, all
* that stuff was found using a multimeter! :)
*/
@@ -4788,7 +4788,7 @@ static void tibetCS16_init(struct bttv *btv)
* The analog switch is controlled by the "master", but the detection order
* of the four BT878A chips is in an order which I just don't understand.
* The "master" is actually the second controller to be detected. The
- * logic on the board uses logical numbers for the 4 controlers, but
+ * logic on the board uses logical numbers for the 4 controllers, but
* those numbers are different from the detection sequence. When working
* with the analog switch, we need to "map" from the detection sequence
* over to the board's logical controller number. This mapping sequence
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 7a332b3efe5..9feeb636ff9 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3877,7 +3877,6 @@ static struct video_device bttv_video_template =
.name = "UNSET",
.type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
VID_TYPE_CLIPPING|VID_TYPE_SCALES,
- .hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops,
.minor = -1,
};
@@ -3886,7 +3885,6 @@ static struct video_device bttv_vbi_template =
{
.name = "bt848/878 vbi",
.type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
- .hardware = VID_HARDWARE_BT848,
.fops = &bttv_fops,
.minor = -1,
};
@@ -4034,7 +4032,6 @@ static struct video_device radio_template =
{
.name = "bt848/878 radio",
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_BT848,
.fops = &radio_fops,
.minor = -1,
};
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
index 7f7e3d3398d..58423525591 100644
--- a/drivers/media/video/bw-qcam.c
+++ b/drivers/media/video/bw-qcam.c
@@ -899,7 +899,6 @@ static struct video_device qcam_template=
.owner = THIS_MODULE,
.name = "Connectix Quickcam",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_QCAM_BW,
.fops = &qcam_fops,
};
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index f76c6a6c376..cf1546b5a7f 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -699,7 +699,6 @@ static struct video_device qcam_template=
.owner = THIS_MODULE,
.name = "Colour QuickCam",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_QCAM_C,
.fops = &qcam_fops,
};
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index a1d02e5ce0f..7c630f5ee72 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -65,10 +65,6 @@ MODULE_PARM_DESC(colorspace_conv,
#define ABOUT "V4L-Driver for Vision CPiA based cameras"
-#ifndef VID_HARDWARE_CPIA
-#define VID_HARDWARE_CPIA 24 /* FIXME -> from linux/videodev.h */
-#endif
-
#define CPIA_MODULE_CPIA (0<<5)
#define CPIA_MODULE_SYSTEM (1<<5)
#define CPIA_MODULE_VP_CTRL (5<<5)
@@ -3804,7 +3800,6 @@ static struct video_device cpia_template = {
.owner = THIS_MODULE,
.name = "CPiA Camera",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_CPIA,
.fops = &cpia_fops,
};
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index e3aaba1e0e0..e378abec806 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -86,10 +86,6 @@ MODULE_LICENSE("GPL");
#define ABOUT "V4L-Driver for Vision CPiA2 based cameras"
-#ifndef VID_HARDWARE_CPIA2
-#error "VID_HARDWARE_CPIA2 should have been defined in linux/videodev.h"
-#endif
-
struct control_menu_info {
int value;
char name[32];
@@ -1942,7 +1938,6 @@ static struct video_device cpia2_template = {
.type= VID_TYPE_CAPTURE,
.type2 = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING,
- .hardware= VID_HARDWARE_CPIA2,
.minor= -1,
.fops= &fops_template,
.release= video_device_release,
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index af16505bd2e..3cdd136477e 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -793,7 +793,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
dev->pci->subsystem_device);
cx23885_devcount--;
- goto fail_free;
+ return -ENODEV;
}
/* PCIe stuff */
@@ -835,10 +835,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
}
return 0;
-
-fail_free:
- kfree(dev);
- return -ENODEV;
}
void cx23885_dev_unregister(struct cx23885_dev *dev)
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 141dadf7cf1..40ffd7a5579 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -39,6 +39,7 @@
#include <sound/pcm_params.h>
#include <sound/control.h>
#include <sound/initval.h>
+#include <sound/tlv.h>
#include "cx88.h"
#include "cx88-reg.h"
@@ -82,6 +83,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
+
/****************************************************************************
Module global static vars
****************************************************************************/
@@ -545,8 +547,8 @@ static int __devinit snd_cx88_pcm(snd_cx88_card_t *chip, int device, char *name)
/****************************************************************************
CONTROL INTERFACE
****************************************************************************/
-static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *info)
+static int snd_cx88_volume_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *info)
{
info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
info->count = 2;
@@ -556,9 +558,8 @@ static int snd_cx88_capture_volume_info(struct snd_kcontrol *kcontrol,
return 0;
}
-/* OK - TODO: test it */
-static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
{
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
struct cx88_core *core=chip->core;
@@ -573,8 +574,8 @@ static int snd_cx88_capture_volume_get(struct snd_kcontrol *kcontrol,
}
/* OK - TODO: test it */
-static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *value)
+static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
{
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
struct cx88_core *core=chip->core;
@@ -605,14 +606,67 @@ static int snd_cx88_capture_volume_put(struct snd_kcontrol *kcontrol,
return changed;
}
-static struct snd_kcontrol_new snd_cx88_capture_volume = {
+static const DECLARE_TLV_DB_SCALE(snd_cx88_db_scale, -6300, 100, 0);
+
+static struct snd_kcontrol_new snd_cx88_volume = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
+ SNDRV_CTL_ELEM_ACCESS_TLV_READ,
+ .name = "Playback Volume",
+ .info = snd_cx88_volume_info,
+ .get = snd_cx88_volume_get,
+ .put = snd_cx88_volume_put,
+ .tlv.p = snd_cx88_db_scale,
+};
+
+static int snd_cx88_switch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
+{
+ snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+ struct cx88_core *core = chip->core;
+ u32 bit = kcontrol->private_value;
+
+ value->value.integer.value[0] = !(cx_read(AUD_VOL_CTL) & bit);
+ return 0;
+}
+
+static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *value)
+{
+ snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
+ struct cx88_core *core = chip->core;
+ u32 bit = kcontrol->private_value;
+ int ret = 0;
+ u32 vol;
+
+ spin_lock_irq(&chip->reg_lock);
+ vol = cx_read(AUD_VOL_CTL);
+ if (value->value.integer.value[0] != !(vol & bit)) {
+ vol ^= bit;
+ cx_write(AUD_VOL_CTL, vol);
+ ret = 1;
+ }
+ spin_unlock_irq(&chip->reg_lock);
+ return ret;
+}
+
+static struct snd_kcontrol_new snd_cx88_dac_switch = {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
- .name = "Capture Volume",
- .info = snd_cx88_capture_volume_info,
- .get = snd_cx88_capture_volume_get,
- .put = snd_cx88_capture_volume_put,
+ .name = "Playback Switch",
+ .info = snd_ctl_boolean_mono_info,
+ .get = snd_cx88_switch_get,
+ .put = snd_cx88_switch_put,
+ .private_value = (1<<8),
};
+static struct snd_kcontrol_new snd_cx88_source_switch = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Capture Switch",
+ .info = snd_ctl_boolean_mono_info,
+ .get = snd_cx88_switch_get,
+ .put = snd_cx88_switch_put,
+ .private_value = (1<<6),
+};
/****************************************************************************
Basic Flow for Sound Devices
@@ -762,7 +816,13 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
if (err < 0)
goto error;
- err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_capture_volume, chip));
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_volume, chip));
+ if (err < 0)
+ goto error;
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_dac_switch, chip));
+ if (err < 0)
+ goto error;
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cx88_source_switch, chip));
if (err < 0)
goto error;
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 6d6f5048d76..f33f0b47142 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -527,44 +527,6 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params);
}
-static struct v4l2_mpeg_compression default_mpeg_params = {
- .st_type = V4L2_MPEG_PS_2,
- .st_bitrate = {
- .mode = V4L2_BITRATE_CBR,
- .min = 0,
- .target = 0,
- .max = 0
- },
- .ts_pid_pmt = 16,
- .ts_pid_audio = 260,
- .ts_pid_video = 256,
- .ts_pid_pcr = 259,
- .ps_size = 0,
- .au_type = V4L2_MPEG_AU_2_II,
- .au_bitrate = {
- .mode = V4L2_BITRATE_CBR,
- .min = 224,
- .target = 224,
- .max = 224
- },
- .au_sample_rate = 48000,
- .au_pesid = 0,
- .vi_type = V4L2_MPEG_VI_2,
- .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
- .vi_bitrate = {
- .mode = V4L2_BITRATE_CBR,
- .min = 4000,
- .target = 4500,
- .max = 6000
- },
- .vi_frame_rate = 25,
- .vi_frames_per_gop = 12,
- .vi_bframes_count = 2,
- .vi_pesid = 0,
- .closed_gops = 1,
- .pulldown = 0
-};
-
static int blackbird_initialize_codec(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
@@ -852,23 +814,6 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
return videobuf_streamoff(&fh->mpegq);
}
-static int vidioc_g_mpegcomp (struct file *file, void *fh,
- struct v4l2_mpeg_compression *f)
-{
- printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
- "Replace with VIDIOC_G_EXT_CTRLS!");
- memcpy(f,&default_mpeg_params,sizeof(*f));
- return 0;
-}
-
-static int vidioc_s_mpegcomp (struct file *file, void *fh,
- struct v4l2_mpeg_compression *f)
-{
- printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
- "Replace with VIDIOC_S_EXT_CTRLS!");
- return 0;
-}
-
static int vidioc_g_ext_ctrls (struct file *file, void *priv,
struct v4l2_ext_controls *f)
{
@@ -1216,8 +1161,6 @@ static struct video_device cx8802_mpeg_template =
.vidioc_dqbuf = vidioc_dqbuf,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
- .vidioc_g_mpegcomp = vidioc_g_mpegcomp,
- .vidioc_s_mpegcomp = vidioc_s_mpegcomp,
.vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index d16e5c6d21c..fce19caf9d0 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -475,8 +475,9 @@ static int dvb_register(struct cx8802_dev *dev)
break;
case CX88_BOARD_DNTV_LIVE_DVB_T_PRO:
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
+ /* MT352 is on a secondary I2C bus made from some GPIO lines */
dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
- &((struct vp3054_i2c_state *)dev->card_priv)->adap);
+ &dev->vp3054->adap);
if (dev->dvb.frontend != NULL) {
dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
&dev->core->i2c_adap, DVB_PLL_FMD1216ME);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index a652f294d23..448c6738094 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -79,7 +79,8 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
{
struct cx88_core *core = dev->core;
- dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n", dev->width, dev->height, buf->vb.field);
+ dprintk(1, "cx8802_start_dma w: %d, h: %d, f: %d\n",
+ buf->vb.width, buf->vb.height, buf->vb.field);
/* setup fifo + format */
cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28],
@@ -177,7 +178,6 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
struct cx88_dmaqueue *q)
{
struct cx88_buffer *buf;
- struct list_head *item;
dprintk( 1, "cx8802_restart_queue\n" );
if (list_empty(&q->active))
@@ -223,10 +223,8 @@ static int cx8802_restart_queue(struct cx8802_dev *dev,
dprintk(2,"restart_queue [%p/%d]: restart dma\n",
buf, buf->vb.i);
cx8802_start_dma(dev, q, buf);
- list_for_each(item,&q->active) {
- buf = list_entry(item, struct cx88_buffer, vb.queue);
+ list_for_each_entry(buf, &q->active, vb.queue)
buf->count = q->count++;
- }
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
return 0;
}
@@ -572,42 +570,29 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
return 0;
}
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+ defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
struct cx8802_dev * cx8802_get_device(struct inode *inode)
{
int minor = iminor(inode);
- struct cx8802_dev *h = NULL;
- struct list_head *list;
+ struct cx8802_dev *dev;
- list_for_each(list,&cx8802_devlist) {
- h = list_entry(list, struct cx8802_dev, devlist);
- if (h->mpeg_dev && h->mpeg_dev->minor == minor)
- return h;
- }
+ list_for_each_entry(dev, &cx8802_devlist, devlist)
+ if (dev->mpeg_dev && dev->mpeg_dev->minor == minor)
+ return dev;
return NULL;
}
+EXPORT_SYMBOL(cx8802_get_device);
+#endif
struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype)
{
- struct cx8802_dev *h = NULL;
- struct cx8802_driver *d = NULL;
- struct list_head *list;
- struct list_head *list2;
-
- list_for_each(list,&cx8802_devlist) {
- h = list_entry(list, struct cx8802_dev, devlist);
- if (h != dev)
- continue;
-
- list_for_each(list2, &h->drvlist.devlist) {
- d = list_entry(list2, struct cx8802_driver, devlist);
+ struct cx8802_driver *d;
- /* only unregister the correct driver type */
- if (d->type_id == btype) {
- return d;
- }
- }
- }
+ list_for_each_entry(d, &dev->drvlist, drvlist)
+ if (d->type_id == btype)
+ return d;
return NULL;
}
@@ -671,10 +656,9 @@ static int cx8802_check_driver(struct cx8802_driver *drv)
int cx8802_register_driver(struct cx8802_driver *drv)
{
- struct cx8802_dev *h;
+ struct cx8802_dev *dev;
struct cx8802_driver *driver;
- struct list_head *list;
- int err = 0, i = 0;
+ int err, i = 0;
printk(KERN_INFO
"cx88/2: registering cx8802 driver, type: %s access: %s\n",
@@ -686,14 +670,12 @@ int cx8802_register_driver(struct cx8802_driver *drv)
return err;
}
- list_for_each(list,&cx8802_devlist) {
- h = list_entry(list, struct cx8802_dev, devlist);
-
+ list_for_each_entry(dev, &cx8802_devlist, devlist) {
printk(KERN_INFO
"%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
- h->core->name, h->pci->subsystem_vendor,
- h->pci->subsystem_device, h->core->board.name,
- h->core->boardnr);
+ dev->core->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device, dev->core->board.name,
+ dev->core->boardnr);
/* Bring up a new struct for each driver instance */
driver = kzalloc(sizeof(*drv),GFP_KERNEL);
@@ -701,7 +683,7 @@ int cx8802_register_driver(struct cx8802_driver *drv)
return -ENOMEM;
/* Snapshot of the driver registration data */
- drv->core = h->core;
+ drv->core = dev->core;
drv->suspend = cx8802_suspend_common;
drv->resume = cx8802_resume_common;
drv->request_acquire = cx8802_request_acquire;
@@ -712,49 +694,38 @@ int cx8802_register_driver(struct cx8802_driver *drv)
if (err == 0) {
i++;
mutex_lock(&drv->core->lock);
- list_add_tail(&driver->devlist,&h->drvlist.devlist);
+ list_add_tail(&driver->drvlist, &dev->drvlist);
mutex_unlock(&drv->core->lock);
} else {
printk(KERN_ERR
"%s/2: cx8802 probe failed, err = %d\n",
- h->core->name, err);
+ dev->core->name, err);
}
}
- if (i == 0)
- err = -ENODEV;
- else
- err = 0;
- return err;
+ return i ? 0 : -ENODEV;
}
int cx8802_unregister_driver(struct cx8802_driver *drv)
{
- struct cx8802_dev *h;
- struct cx8802_driver *d;
- struct list_head *list;
- struct list_head *list2, *q;
- int err = 0, i = 0;
+ struct cx8802_dev *dev;
+ struct cx8802_driver *d, *dtmp;
+ int err = 0;
printk(KERN_INFO
"cx88/2: unregistering cx8802 driver, type: %s access: %s\n",
drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
- list_for_each(list,&cx8802_devlist) {
- i++;
- h = list_entry(list, struct cx8802_dev, devlist);
-
+ list_for_each_entry(dev, &cx8802_devlist, devlist) {
printk(KERN_INFO
"%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
- h->core->name, h->pci->subsystem_vendor,
- h->pci->subsystem_device, h->core->board.name,
- h->core->boardnr);
-
- list_for_each_safe(list2, q, &h->drvlist.devlist) {
- d = list_entry(list2, struct cx8802_driver, devlist);
+ dev->core->name, dev->pci->subsystem_vendor,
+ dev->pci->subsystem_device, dev->core->board.name,
+ dev->core->boardnr);
+ list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
/* only unregister the correct driver type */
if (d->type_id != drv->type_id)
continue;
@@ -762,12 +733,12 @@ int cx8802_unregister_driver(struct cx8802_driver *drv)
err = d->remove(d);
if (err == 0) {
mutex_lock(&drv->core->lock);
- list_del(list2);
+ list_del(&d->drvlist);
mutex_unlock(&drv->core->lock);
+ kfree(d);
} else
printk(KERN_ERR "%s/2: cx8802 driver remove "
- "failed (%d)\n", h->core->name, err);
-
+ "failed (%d)\n", dev->core->name, err);
}
}
@@ -805,7 +776,7 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
if (err != 0)
goto fail_free;
- INIT_LIST_HEAD(&dev->drvlist.devlist);
+ INIT_LIST_HEAD(&dev->drvlist);
list_add_tail(&dev->devlist,&cx8802_devlist);
/* Maintain a reference so cx88-video can query the 8802 device. */
@@ -825,23 +796,30 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
static void __devexit cx8802_remove(struct pci_dev *pci_dev)
{
struct cx8802_dev *dev;
- struct cx8802_driver *h;
- struct list_head *list;
dev = pci_get_drvdata(pci_dev);
dprintk( 1, "%s\n", __FUNCTION__);
- list_for_each(list,&dev->drvlist.devlist) {
- h = list_entry(list, struct cx8802_driver, devlist);
- dprintk( 1, " ->driver\n");
- if (h->remove == NULL) {
- printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
- continue;
+ if (!list_empty(&dev->drvlist)) {
+ struct cx8802_driver *drv, *tmp;
+ int err;
+
+ printk(KERN_WARNING "%s/2: Trying to remove cx8802 driver "
+ "while cx8802 sub-drivers still loaded?!\n",
+ dev->core->name);
+
+ list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
+ err = drv->remove(drv);
+ if (err == 0) {
+ mutex_lock(&drv->core->lock);
+ list_del(&drv->drvlist);
+ mutex_unlock(&drv->core->lock);
+ } else
+ printk(KERN_ERR "%s/2: cx8802 driver remove "
+ "failed (%d)\n", dev->core->name, err);
+ kfree(drv);
}
- printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
- cx8802_unregister_driver(h);
- list_del(&dev->drvlist.devlist);
}
/* Destroy any 8802 reference. */
@@ -901,7 +879,6 @@ EXPORT_SYMBOL(cx8802_fini_common);
EXPORT_SYMBOL(cx8802_register_driver);
EXPORT_SYMBOL(cx8802_unregister_driver);
-EXPORT_SYMBOL(cx8802_get_device);
EXPORT_SYMBOL(cx8802_get_driver);
/* ----------------------------------------------------------- */
/*
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 231ae6c4dd2..5ee05f8f3fa 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1675,7 +1675,6 @@ static struct video_device cx8800_radio_template =
{
.name = "cx8800-radio",
.type = VID_TYPE_TUNER,
- .hardware = 0,
.fops = &radio_fops,
.minor = -1,
.vidioc_querycap = radio_querycap,
diff --git a/drivers/media/video/cx88/cx88-vp3054-i2c.c b/drivers/media/video/cx88/cx88-vp3054-i2c.c
index 77c37889232..6ce5af48847 100644
--- a/drivers/media/video/cx88/cx88-vp3054-i2c.c
+++ b/drivers/media/video/cx88/cx88-vp3054-i2c.c
@@ -41,7 +41,7 @@ static void vp3054_bit_setscl(void *data, int state)
{
struct cx8802_dev *dev = data;
struct cx88_core *core = dev->core;
- struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+ struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
if (state) {
vp3054_i2c->state |= 0x0001; /* SCL high */
@@ -58,7 +58,7 @@ static void vp3054_bit_setsda(void *data, int state)
{
struct cx8802_dev *dev = data;
struct cx88_core *core = dev->core;
- struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+ struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
if (state) {
vp3054_i2c->state |= 0x0002; /* SDA high */
@@ -113,10 +113,10 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
return 0;
- dev->card_priv = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
- if (dev->card_priv == NULL)
+ vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL);
+ if (vp3054_i2c == NULL)
return -ENOMEM;
- vp3054_i2c = dev->card_priv;
+ dev->vp3054 = vp3054_i2c;
memcpy(&vp3054_i2c->algo, &vp3054_i2c_algo_template,
sizeof(vp3054_i2c->algo));
@@ -139,8 +139,8 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
if (0 != rc) {
printk("%s: vp3054_i2c register FAILED\n", core->name);
- kfree(dev->card_priv);
- dev->card_priv = NULL;
+ kfree(dev->vp3054);
+ dev->vp3054 = NULL;
}
return rc;
@@ -148,7 +148,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev)
void vp3054_i2c_remove(struct cx8802_dev *dev)
{
- struct vp3054_i2c_state *vp3054_i2c = dev->card_priv;
+ struct vp3054_i2c_state *vp3054_i2c = dev->vp3054;
if (vp3054_i2c == NULL ||
dev->core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO)
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 42e0a9b8c55..eb296bdecb1 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -412,7 +412,9 @@ struct cx8802_suspend_state {
struct cx8802_driver {
struct cx88_core *core;
- struct list_head devlist;
+
+ /* List of drivers attached to device */
+ struct list_head drvlist;
/* Type of driver and access required */
enum cx88_board_type type_id;
@@ -453,27 +455,33 @@ struct cx8802_dev {
/* for blackbird only */
struct list_head devlist;
+#if defined(CONFIG_VIDEO_CX88_BLACKBIRD) || \
+ defined(CONFIG_VIDEO_CX88_BLACKBIRD_MODULE)
struct video_device *mpeg_dev;
u32 mailbox;
int width;
int height;
+ /* mpeg params */
+ struct cx2341x_mpeg_params params;
+#endif
+
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
/* for dvb only */
struct videobuf_dvb dvb;
+#endif
- void *card_priv;
+#if defined(CONFIG_VIDEO_CX88_VP3054) || \
+ defined(CONFIG_VIDEO_CX88_VP3054_MODULE)
+ /* For VP3045 secondary I2C bus support */
+ struct vp3054_i2c_state *vp3054;
#endif
/* for switching modulation types */
unsigned char ts_gen_cntrl;
- /* mpeg params */
- struct cx2341x_mpeg_params params;
-
/* List of attached drivers */
- struct cx8802_driver drvlist;
- struct work_struct request_module_wk;
-
+ struct list_head drvlist;
+ struct work_struct request_module_wk;
};
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index d3282ec62c5..d56484f2046 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -648,7 +648,7 @@ void em28xx_uninit_isoc(struct em28xx *dev)
*/
int em28xx_init_isoc(struct em28xx *dev)
{
- /* change interface to 3 which allowes the biggest packet sizes */
+ /* change interface to 3 which allows the biggest packet sizes */
int i, errCode;
const int sb_size = EM28XX_NUM_PACKETS * dev->max_pkt_size;
@@ -673,6 +673,7 @@ int em28xx_init_isoc(struct em28xx *dev)
("unable to allocate %i bytes for transfer buffer %i\n",
sb_size, i);
em28xx_uninit_isoc(dev);
+ usb_free_urb(urb);
return -ENOMEM;
}
memset(dev->transfer_buffer[i], 0, sb_size);
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index b8d5327c438..a4c2a907124 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -907,7 +907,7 @@ static int em28xx_set_fmt(struct em28xx *dev, unsigned int cmd, struct v4l2_form
/* stop io in case it is already in progress */
if (dev->stream == STREAM_ON) {
- em28xx_videodbg("VIDIOC_SET_FMT: interupting stream\n");
+ em28xx_videodbg("VIDIOC_SET_FMT: interrupting stream\n");
if ((ret = em28xx_stream_interrupt(dev)))
return ret;
}
@@ -1617,7 +1617,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* Fills VBI device info */
dev->vbi_dev->type = VFL_TYPE_VBI;
- dev->vbi_dev->hardware = 0;
dev->vbi_dev->fops = &em28xx_v4l_fops;
dev->vbi_dev->minor = -1;
dev->vbi_dev->dev = &dev->udev->dev;
@@ -1629,7 +1628,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->vdev->type = VID_TYPE_CAPTURE;
if (dev->has_tuner)
dev->vdev->type |= VID_TYPE_TUNER;
- dev->vdev->hardware = 0;
dev->vdev->fops = &em28xx_v4l_fops;
dev->vdev->minor = -1;
dev->vdev->dev = &dev->udev->dev;
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index d5fef4c01c8..d19d73b81ed 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -2585,7 +2585,6 @@ et61x251_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "ET61X[12]51 PC Camera");
cam->v4ldev->owner = THIS_MODULE;
cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
- cam->v4ldev->hardware = 0;
cam->v4ldev->fops = &et61x251_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index d98dd0d1e37..29779d8bf7f 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -528,6 +528,7 @@ static int ir_probe(struct i2c_adapter *adap)
break;
case I2C_HW_B_CX2388x:
probe = probe_cx88;
+ break;
case I2C_HW_B_CX23885:
probe = probe_cx23885;
break;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index fd7a932e1d3..6d2dd8764f8 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1003,8 +1003,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
- mutex_lock(&itv->serialize_lock);
-
/* PCI Device Setup */
if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
if (retval == -EIO)
@@ -1064,7 +1062,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("activating i2c...\n");
if (init_ivtv_i2c(itv)) {
IVTV_ERR("Could not initialize i2c\n");
- goto free_irq;
+ goto free_io;
}
IVTV_DEBUG_INFO("Active card count: %d.\n", ivtv_cards_active);
@@ -1176,7 +1174,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_ERR("Failed to register irq %d\n", retval);
goto free_streams;
}
- mutex_unlock(&itv->serialize_lock);
+ retval = ivtv_streams_register(itv);
+ if (retval) {
+ IVTV_ERR("Error %d registering devices\n", retval);
+ goto free_irq;
+ }
IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name);
return 0;
@@ -1195,7 +1197,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
free_workqueue:
destroy_workqueue(itv->irq_work_queues);
- mutex_unlock(&itv->serialize_lock);
err:
if (retval == 0)
retval = -ENODEV;
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index da50fa4a72a..a200a8a95a2 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -822,6 +822,11 @@ int ivtv_v4l2_close(struct inode *inode, struct file *filp)
crystal_freq.flags = 0;
ivtv_saa7115(itv, VIDIOC_INT_S_CRYSTAL_FREQ, &crystal_freq);
}
+ if (atomic_read(&itv->capturing) > 0) {
+ /* Undo video mute */
+ ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+ itv->params.video_mute | (itv->params.video_mute_yuv << 8));
+ }
/* Done! Unmute and continue. */
ivtv_unmute(itv);
ivtv_release_stream(s);
@@ -892,6 +897,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
if (atomic_read(&itv->capturing) > 0) {
/* switching to radio while capture is
in progress is not polite */
+ ivtv_release_stream(s);
kfree(item);
return -EBUSY;
}
@@ -947,7 +953,7 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
if (itv == NULL) {
/* Couldn't find a device registered
on that minor, shouldn't happen! */
- IVTV_WARN("No ivtv device found on minor %d\n", minor);
+ printk(KERN_WARNING "No ivtv device found on minor %d\n", minor);
return -ENXIO;
}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 206eee7542d..fd6826f472e 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -555,6 +555,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
/* set window size */
if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ struct cx2341x_mpeg_params *p = &itv->params;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
@@ -566,17 +567,19 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
- if (!set_fmt || (itv->params.width == w && itv->params.height == h))
+ if (!set_fmt || (p->width == w && p->height == h))
return 0;
if (atomic_read(&itv->capturing) > 0)
return -EBUSY;
- itv->params.width = w;
- itv->params.height = h;
+ p->width = w;
+ p->height = h;
if (w != 720 || h != (itv->is_50hz ? 576 : 480))
- itv->params.video_temporal_filter = 0;
+ p->video_temporal_filter = 0;
else
- itv->params.video_temporal_filter = 8;
+ p->video_temporal_filter = 8;
+ if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
+ fmt->fmt.pix.width /= 2;
itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
return ivtv_get_fmt(itv, streamtype, fmt);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index fd135985e70..aa03e61ef31 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -166,10 +166,9 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
ivtv_queue_init(&s->q_io);
}
-static int ivtv_reg_dev(struct ivtv *itv, int type)
+static int ivtv_prep_dev(struct ivtv *itv, int type)
{
struct ivtv_stream *s = &itv->streams[type];
- int vfl_type = ivtv_stream_info[type].vfl_type;
int minor_offset = ivtv_stream_info[type].minor_offset;
int minor;
@@ -187,15 +186,12 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
if (type >= IVTV_DEC_STREAM_TYPE_MPG && !(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
return 0;
- if (minor_offset >= 0)
- /* card number + user defined offset + device offset */
- minor = itv->num + ivtv_first_minor + minor_offset;
- else
- minor = -1;
+ /* card number + user defined offset + device offset */
+ minor = itv->num + ivtv_first_minor + minor_offset;
/* User explicitly selected 0 buffers for these streams, so don't
create them. */
- if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
+ if (ivtv_stream_info[type].dma != PCI_DMA_NONE &&
itv->options.kilobytes[type] == 0) {
IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
return 0;
@@ -223,21 +219,53 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
s->v4l2dev->fops = ivtv_stream_info[type].fops;
s->v4l2dev->release = video_device_release;
- if (minor >= 0) {
- /* Register device. First try the desired minor, then any free one. */
- if (video_register_device(s->v4l2dev, vfl_type, minor) &&
- video_register_device(s->v4l2dev, vfl_type, -1)) {
- IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
- s->name, minor);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
- return -ENOMEM;
- }
+ return 0;
+}
+
+/* Initialize v4l2 variables and prepare v4l2 devices */
+int ivtv_streams_setup(struct ivtv *itv)
+{
+ int type;
+
+ /* Setup V4L2 Devices */
+ for (type = 0; type < IVTV_MAX_STREAMS; type++) {
+ /* Prepare device */
+ if (ivtv_prep_dev(itv, type))
+ break;
+
+ if (itv->streams[type].v4l2dev == NULL)
+ continue;
+
+ /* Allocate Stream */
+ if (ivtv_stream_alloc(&itv->streams[type]))
+ break;
}
- else {
- /* Don't register a 'hidden' stream (OSD) */
- IVTV_INFO("Created framebuffer stream for %s\n", s->name);
+ if (type == IVTV_MAX_STREAMS)
return 0;
+
+ /* One or more streams could not be initialized. Clean 'em all up. */
+ ivtv_streams_cleanup(itv);
+ return -ENOMEM;
+}
+
+static int ivtv_reg_dev(struct ivtv *itv, int type)
+{
+ struct ivtv_stream *s = &itv->streams[type];
+ int vfl_type = ivtv_stream_info[type].vfl_type;
+ int minor;
+
+ if (s->v4l2dev == NULL)
+ return 0;
+
+ minor = s->v4l2dev->minor;
+ /* Register device. First try the desired minor, then any free one. */
+ if (video_register_device(s->v4l2dev, vfl_type, minor) &&
+ video_register_device(s->v4l2dev, vfl_type, -1)) {
+ IVTV_ERR("Couldn't register v4l2 device for %s minor %d\n",
+ s->name, minor);
+ video_device_release(s->v4l2dev);
+ s->v4l2dev = NULL;
+ return -ENOMEM;
}
switch (vfl_type) {
@@ -262,27 +290,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
return 0;
}
-/* Initialize v4l2 variables and register v4l2 devices */
-int ivtv_streams_setup(struct ivtv *itv)
+/* Register v4l2 devices */
+int ivtv_streams_register(struct ivtv *itv)
{
int type;
+ int err = 0;
- /* Setup V4L2 Devices */
- for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- /* Register Device */
- if (ivtv_reg_dev(itv, type))
- break;
-
- if (itv->streams[type].v4l2dev == NULL)
- continue;
+ /* Register V4L2 devices */
+ for (type = 0; type < IVTV_MAX_STREAMS; type++)
+ err |= ivtv_reg_dev(itv, type);
- /* Allocate Stream */
- if (ivtv_stream_alloc(&itv->streams[type]))
- break;
- }
- if (type == IVTV_MAX_STREAMS) {
+ if (err == 0)
return 0;
- }
/* One or more streams could not be initialized. Clean 'em all up. */
ivtv_streams_cleanup(itv);
@@ -303,11 +322,8 @@ void ivtv_streams_cleanup(struct ivtv *itv)
continue;
ivtv_stream_free(&itv->streams[type]);
- /* Free Device */
- if (vdev->minor == -1) /* 'Hidden' never registered stream (OSD) */
- video_device_release(vdev);
- else /* All others, just unregister. */
- video_unregister_device(vdev);
+ /* Unregister device */
+ video_unregister_device(vdev);
}
}
@@ -425,6 +441,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
{
u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv *itv = s->itv;
+ struct cx2341x_mpeg_params *p = &itv->params;
int captype = 0, subtype = 0;
int enable_passthrough = 0;
@@ -445,7 +462,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
}
itv->mpg_data_received = itv->vbi_data_inserted = 0;
itv->dualwatch_jiffies = jiffies;
- itv->dualwatch_stereo_mode = itv->params.audio_properties & 0x0300;
+ itv->dualwatch_stereo_mode = p->audio_properties & 0x0300;
itv->search_pack_header = 0;
break;
@@ -477,9 +494,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
s->subtype = subtype;
s->buffers_stolen = 0;
- /* mute/unmute video */
- ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? 1 : 0);
-
/* Clear Streamoff flags in case left from last capture */
clear_bit(IVTV_F_S_STREAMOFF, &s->s_flags);
@@ -536,7 +550,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
itv->pgm_info_offset, itv->pgm_info_num);
/* Setup API for Stream */
- cx2341x_update(itv, ivtv_api_func, NULL, &itv->params);
+ cx2341x_update(itv, ivtv_api_func, NULL, p);
+
+ /* mute if capturing radio */
+ if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
+ ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
+ 1 | (p->video_mute_yuv << 8));
}
/* Vsync Setup */
@@ -585,6 +604,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
{
u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv *itv = s->itv;
+ struct cx2341x_mpeg_params *p = &itv->params;
int datatype;
if (s->v4l2dev == NULL)
@@ -623,7 +643,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
break;
}
if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
- itv->params.width, itv->params.height, itv->params.audio_properties)) {
+ p->width, p->height, p->audio_properties)) {
IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
}
return 0;
diff --git a/drivers/media/video/ivtv/ivtv-streams.h b/drivers/media/video/ivtv/ivtv-streams.h
index 8f5f5b1c7c8..3d76a415fbd 100644
--- a/drivers/media/video/ivtv/ivtv-streams.h
+++ b/drivers/media/video/ivtv/ivtv-streams.h
@@ -22,6 +22,7 @@
#define IVTV_STREAMS_H
int ivtv_streams_setup(struct ivtv *itv);
+int ivtv_streams_register(struct ivtv *itv);
void ivtv_streams_cleanup(struct ivtv *itv);
/* Capture related */
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index c4626d1cdf4..912b424e520 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -63,10 +63,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
kunmap_atomic(src, KM_BOUNCE_READ);
local_irq_restore(flags);
- dma->SGlist[map_offset].page = dma->bouncemap[map_offset];
+ sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
}
else {
- dma->SGlist[map_offset].page = dma->map[map_offset];
+ sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
}
offset = 0;
map_offset++;
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index e2288f224ab..9091c4837bb 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -710,7 +710,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
/* If there's nothing to safe to display, we may as well stop now */
if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
- return 0;
+ return IVTV_YUV_UPDATE_INVALID;
}
/* Ensure video remains inside OSD area */
@@ -791,7 +791,7 @@ static u32 ivtv_yuv_window_setup (struct ivtv *itv, struct yuv_frame_info *windo
/* Check again. If there's nothing to safe to display, stop now */
if ((int)window->dst_w <= 2 || (int)window->dst_h <= 2 || (int)window->src_w <= 2 || (int)window->src_h <= 2) {
- return 0;
+ return IVTV_YUV_UPDATE_INVALID;
}
/* Both x offset & width are linked, so they have to be done together */
@@ -840,110 +840,118 @@ void ivtv_yuv_work_handler (struct ivtv *itv)
if (!(yuv_update = ivtv_yuv_window_setup (itv, &window)))
return;
- /* Update horizontal settings */
- if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
- ivtv_yuv_handle_horizontal(itv, &window);
+ if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
+ write_reg(0x01008080, 0x2898);
+ } else if (yuv_update) {
+ write_reg(0x00108080, 0x2898);
- if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
- ivtv_yuv_handle_vertical(itv, &window);
+ if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
+ ivtv_yuv_handle_horizontal(itv, &window);
+
+ if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
+ ivtv_yuv_handle_vertical(itv, &window);
+ }
memcpy(&itv->yuv_info.old_frame_info, &window, sizeof (itv->yuv_info.old_frame_info));
}
static void ivtv_yuv_init (struct ivtv *itv)
{
+ struct yuv_playback_info *yi = &itv->yuv_info;
+
IVTV_DEBUG_YUV("ivtv_yuv_init\n");
/* Take a snapshot of the current register settings */
- itv->yuv_info.reg_2834 = read_reg(0x02834);
- itv->yuv_info.reg_2838 = read_reg(0x02838);
- itv->yuv_info.reg_283c = read_reg(0x0283c);
- itv->yuv_info.reg_2840 = read_reg(0x02840);
- itv->yuv_info.reg_2844 = read_reg(0x02844);
- itv->yuv_info.reg_2848 = read_reg(0x02848);
- itv->yuv_info.reg_2854 = read_reg(0x02854);
- itv->yuv_info.reg_285c = read_reg(0x0285c);
- itv->yuv_info.reg_2864 = read_reg(0x02864);
- itv->yuv_info.reg_2870 = read_reg(0x02870);
- itv->yuv_info.reg_2874 = read_reg(0x02874);
- itv->yuv_info.reg_2898 = read_reg(0x02898);
- itv->yuv_info.reg_2890 = read_reg(0x02890);
-
- itv->yuv_info.reg_289c = read_reg(0x0289c);
- itv->yuv_info.reg_2918 = read_reg(0x02918);
- itv->yuv_info.reg_291c = read_reg(0x0291c);
- itv->yuv_info.reg_2920 = read_reg(0x02920);
- itv->yuv_info.reg_2924 = read_reg(0x02924);
- itv->yuv_info.reg_2928 = read_reg(0x02928);
- itv->yuv_info.reg_292c = read_reg(0x0292c);
- itv->yuv_info.reg_2930 = read_reg(0x02930);
- itv->yuv_info.reg_2934 = read_reg(0x02934);
- itv->yuv_info.reg_2938 = read_reg(0x02938);
- itv->yuv_info.reg_293c = read_reg(0x0293c);
- itv->yuv_info.reg_2940 = read_reg(0x02940);
- itv->yuv_info.reg_2944 = read_reg(0x02944);
- itv->yuv_info.reg_2948 = read_reg(0x02948);
- itv->yuv_info.reg_294c = read_reg(0x0294c);
- itv->yuv_info.reg_2950 = read_reg(0x02950);
- itv->yuv_info.reg_2954 = read_reg(0x02954);
- itv->yuv_info.reg_2958 = read_reg(0x02958);
- itv->yuv_info.reg_295c = read_reg(0x0295c);
- itv->yuv_info.reg_2960 = read_reg(0x02960);
- itv->yuv_info.reg_2964 = read_reg(0x02964);
- itv->yuv_info.reg_2968 = read_reg(0x02968);
- itv->yuv_info.reg_296c = read_reg(0x0296c);
- itv->yuv_info.reg_2970 = read_reg(0x02970);
-
- itv->yuv_info.v_filter_1 = -1;
- itv->yuv_info.v_filter_2 = -1;
- itv->yuv_info.h_filter = -1;
+ yi->reg_2834 = read_reg(0x02834);
+ yi->reg_2838 = read_reg(0x02838);
+ yi->reg_283c = read_reg(0x0283c);
+ yi->reg_2840 = read_reg(0x02840);
+ yi->reg_2844 = read_reg(0x02844);
+ yi->reg_2848 = read_reg(0x02848);
+ yi->reg_2854 = read_reg(0x02854);
+ yi->reg_285c = read_reg(0x0285c);
+ yi->reg_2864 = read_reg(0x02864);
+ yi->reg_2870 = read_reg(0x02870);
+ yi->reg_2874 = read_reg(0x02874);
+ yi->reg_2898 = read_reg(0x02898);
+ yi->reg_2890 = read_reg(0x02890);
+
+ yi->reg_289c = read_reg(0x0289c);
+ yi->reg_2918 = read_reg(0x02918);
+ yi->reg_291c = read_reg(0x0291c);
+ yi->reg_2920 = read_reg(0x02920);
+ yi->reg_2924 = read_reg(0x02924);
+ yi->reg_2928 = read_reg(0x02928);
+ yi->reg_292c = read_reg(0x0292c);
+ yi->reg_2930 = read_reg(0x02930);
+ yi->reg_2934 = read_reg(0x02934);
+ yi->reg_2938 = read_reg(0x02938);
+ yi->reg_293c = read_reg(0x0293c);
+ yi->reg_2940 = read_reg(0x02940);
+ yi->reg_2944 = read_reg(0x02944);
+ yi->reg_2948 = read_reg(0x02948);
+ yi->reg_294c = read_reg(0x0294c);
+ yi->reg_2950 = read_reg(0x02950);
+ yi->reg_2954 = read_reg(0x02954);
+ yi->reg_2958 = read_reg(0x02958);
+ yi->reg_295c = read_reg(0x0295c);
+ yi->reg_2960 = read_reg(0x02960);
+ yi->reg_2964 = read_reg(0x02964);
+ yi->reg_2968 = read_reg(0x02968);
+ yi->reg_296c = read_reg(0x0296c);
+ yi->reg_2970 = read_reg(0x02970);
+
+ yi->v_filter_1 = -1;
+ yi->v_filter_2 = -1;
+ yi->h_filter = -1;
/* Set some valid size info */
- itv->yuv_info.osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
- itv->yuv_info.osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
+ yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
+ yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
/* Bit 2 of reg 2878 indicates current decoder output format
0 : NTSC 1 : PAL */
if (read_reg(0x2878) & 4)
- itv->yuv_info.decode_height = 576;
+ yi->decode_height = 576;
else
- itv->yuv_info.decode_height = 480;
+ yi->decode_height = 480;
- /* If no visible size set, assume full size */
- if (!itv->yuv_info.osd_vis_w)
- itv->yuv_info.osd_vis_w = 720 - itv->yuv_info.osd_x_offset;
-
- if (!itv->yuv_info.osd_vis_h) {
- itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+ if (!itv->osd_info) {
+ yi->osd_vis_w = 720 - yi->osd_x_offset;
+ yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
} else {
- /* If output video standard has changed, requested height may
- not be legal */
- if (itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset > itv->yuv_info.decode_height) {
- IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
- itv->yuv_info.osd_vis_h + itv->yuv_info.osd_y_offset,
- itv->yuv_info.decode_height);
- itv->yuv_info.osd_vis_h = itv->yuv_info.decode_height - itv->yuv_info.osd_y_offset;
+ /* If no visible size set, assume full size */
+ if (!yi->osd_vis_w)
+ yi->osd_vis_w = 720 - yi->osd_x_offset;
+
+ if (!yi->osd_vis_h)
+ yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+ else {
+ /* If output video standard has changed, requested height may
+ not be legal */
+ if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
+ IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
+ yi->osd_vis_h + yi->osd_y_offset,
+ yi->decode_height);
+ yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
+ }
}
}
/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
- itv->yuv_info.blanking_ptr = kzalloc(720*16,GFP_KERNEL);
- if (itv->yuv_info.blanking_ptr) {
- itv->yuv_info.blanking_dmaptr = pci_map_single(itv->dev, itv->yuv_info.blanking_ptr, 720*16, PCI_DMA_TODEVICE);
- }
+ yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL);
+ if (yi->blanking_ptr)
+ yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
else {
- itv->yuv_info.blanking_dmaptr = 0;
- IVTV_DEBUG_WARN ("Failed to allocate yuv blanking buffer\n");
+ yi->blanking_dmaptr = 0;
+ IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
}
- IVTV_DEBUG_WARN("Enable video output\n");
- write_reg_sync(0x00108080, 0x2898);
-
/* Enable YUV decoder output */
write_reg_sync(0x01, IVTV_REG_VDM);
set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
- atomic_set(&itv->yuv_info.next_dma_frame,0);
+ atomic_set(&yi->next_dma_frame, 0);
}
int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.h b/drivers/media/video/ivtv/ivtv-yuv.h
index f7215eeca01..3b966f0a204 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.h
+++ b/drivers/media/video/ivtv/ivtv-yuv.h
@@ -34,6 +34,7 @@
#define IVTV_YUV_UPDATE_HORIZONTAL 0x01
#define IVTV_YUV_UPDATE_VERTICAL 0x02
+#define IVTV_YUV_UPDATE_INVALID 0x04
extern const u32 yuv_offset[4];
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 9684048fe56..52ffd154a3d 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -55,7 +55,6 @@
static int ivtvfb_card_id = -1;
static int ivtvfb_debug = 0;
static int osd_laced;
-static int osd_compat;
static int osd_depth;
static int osd_upper;
static int osd_left;
@@ -65,7 +64,6 @@ static int osd_xres;
module_param(ivtvfb_card_id, int, 0444);
module_param_named(debug,ivtvfb_debug, int, 0644);
module_param(osd_laced, bool, 0444);
-module_param(osd_compat, bool, 0444);
module_param(osd_depth, int, 0444);
module_param(osd_upper, int, 0444);
module_param(osd_left, int, 0444);
@@ -80,12 +78,6 @@ MODULE_PARM_DESC(debug,
"Debug level (bitmask). Default: errors only\n"
"\t\t\t(debug = 3 gives full debugging)");
-MODULE_PARM_DESC(osd_compat,
- "Compatibility mode - Display size is locked (use for old X drivers)\n"
- "\t\t\t0=off\n"
- "\t\t\t1=on\n"
- "\t\t\tdefault off");
-
/* Why upper, left, xres, yres, depth, laced ? To match terminology used
by fbset.
Why start at 1 for left & upper coordinate ? Because X doesn't allow 0 */
@@ -166,9 +158,6 @@ struct osd_info {
unsigned long fb_end_aligned_physaddr;
#endif
- /* Current osd mode */
- int osd_mode;
-
/* Store the buffer offset */
int set_osd_coords_x;
int set_osd_coords_y;
@@ -470,13 +459,11 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
IVTVFB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
}
- /* Change osd mode if needed.
- Although rare, things can go wrong. The extra mode
- change seems to help... */
- if (osd_mode != -1 && osd_mode != oi->osd_mode) {
+ /* Set video mode. Although rare, the display can become scrambled even
+ if we don't change mode. Always 'bounce' to osd_mode via mode 0 */
+ if (osd_mode != -1) {
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
- oi->osd_mode = osd_mode;
}
oi->bits_per_pixel = var->bits_per_pixel;
@@ -579,14 +566,6 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
osd_height_limit = 480;
}
- /* Check the bits per pixel */
- if (osd_compat) {
- if (var->bits_per_pixel != 32) {
- IVTVFB_DEBUG_WARN("Invalid colour mode: %d\n", var->bits_per_pixel);
- return -EINVAL;
- }
- }
-
if (var->bits_per_pixel == 8 || var->bits_per_pixel == 32) {
var->transp.offset = 24;
var->transp.length = 8;
@@ -638,32 +617,20 @@ static int _ivtvfb_check_var(struct fb_var_screeninfo *var, struct ivtv *itv)
}
/* Check the resolution */
- if (osd_compat) {
- if (var->xres != oi->ivtvfb_defined.xres ||
- var->yres != oi->ivtvfb_defined.yres ||
- var->xres_virtual != oi->ivtvfb_defined.xres_virtual ||
- var->yres_virtual != oi->ivtvfb_defined.yres_virtual) {
- IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d (virtual %dx%d)\n",
- var->xres, var->yres, var->xres_virtual, var->yres_virtual);
- return -EINVAL;
- }
+ if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
+ IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
+ var->xres, var->yres);
+ return -EINVAL;
}
- else {
- if (var->xres > IVTV_OSD_MAX_WIDTH || var->yres > osd_height_limit) {
- IVTVFB_DEBUG_WARN("Invalid resolution: %dx%d\n",
- var->xres, var->yres);
- return -EINVAL;
- }
- /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
- if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
- var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
- var->xres_virtual < var->xres ||
- var->yres_virtual < var->yres) {
- IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
- var->xres_virtual, var->yres_virtual);
- return -EINVAL;
- }
+ /* Max horizontal size is 1023 @ 32bpp, 2046 & 16bpp, 4092 @ 8bpp */
+ if (var->xres_virtual > 4095 / (var->bits_per_pixel / 8) ||
+ var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8) > oi->video_buffer_size ||
+ var->xres_virtual < var->xres ||
+ var->yres_virtual < var->yres) {
+ IVTVFB_DEBUG_WARN("Invalid virtual resolution: %dx%d\n",
+ var->xres_virtual, var->yres_virtual);
+ return -EINVAL;
}
/* Some extra checks if in 8 bit mode */
@@ -877,17 +844,15 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
/* Color mode */
- if (osd_compat) osd_depth = 32;
- if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32) osd_depth = 8;
+ if (osd_depth != 8 && osd_depth != 16 && osd_depth != 32)
+ osd_depth = 8;
oi->bits_per_pixel = osd_depth;
oi->bytes_per_pixel = oi->bits_per_pixel / 8;
- /* Invalidate current osd mode to force a mode switch later */
- oi->osd_mode = -1;
-
/* Horizontal size & position */
- if (osd_xres > 720) osd_xres = 720;
+ if (osd_xres > 720)
+ osd_xres = 720;
/* Must be a multiple of 4 for 8bpp & 2 for 16bpp */
if (osd_depth == 8)
@@ -895,10 +860,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
else if (osd_depth == 16)
osd_xres &= ~1;
- if (osd_xres)
- start_window.width = osd_xres;
- else
- start_window.width = osd_compat ? 720: 640;
+ start_window.width = osd_xres ? osd_xres : 640;
/* Check horizontal start (osd_left). */
if (osd_left && osd_left + start_window.width > 721) {
@@ -921,10 +883,7 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
if (osd_yres > max_height)
osd_yres = max_height;
- if (osd_yres)
- start_window.height = osd_yres;
- else
- start_window.height = osd_compat ? max_height : (itv->is_50hz ? 480 : 400);
+ start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
/* Check vertical start (osd_upper). */
if (osd_upper + start_window.height > max_height + 1) {
@@ -1127,10 +1086,6 @@ static int ivtvfb_init_card(struct ivtv *itv)
/* Enable the osd */
ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
- /* Note if we're running in compatibility mode */
- if (osd_compat)
- IVTVFB_INFO("Running in compatibility mode. Display resize & mode change disabled\n");
-
/* Allocate DMA */
ivtv_udma_alloc(itv);
return 0;
@@ -1177,9 +1132,12 @@ static void ivtvfb_cleanup(void)
for (i = 0; i < ivtv_cards_active; i++) {
itv = ivtv_cards[i];
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) && itv->osd_info) {
+ if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
+ IVTVFB_WARN("Framebuffer %d is in use, cannot unload\n", i);
+ return;
+ }
IVTVFB_DEBUG_INFO("Unregister framebuffer %d\n", i);
ivtvfb_blank(FB_BLANK_POWERDOWN, &itv->osd_info->ivtvfb_info);
- unregister_framebuffer(&itv->osd_info->ivtvfb_info);
ivtvfb_release_buffers(itv);
itv->osd_video_pbase = 0;
}
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 7533fc20331..c3116329043 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
*
- * Copyright (C) 2001-2002 Alcve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
*
* Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
*
@@ -1762,7 +1762,6 @@ static struct video_device meye_template = {
.owner = THIS_MODULE,
.name = "meye",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_MEYE,
.fops = &meye_fops,
.release = video_device_release,
.minor = -1,
diff --git a/drivers/media/video/meye.h b/drivers/media/video/meye.h
index 323d0074120..d535748df44 100644
--- a/drivers/media/video/meye.h
+++ b/drivers/media/video/meye.h
@@ -3,7 +3,7 @@
*
* Copyright (C) 2001-2004 Stelian Pop <stelian@popies.net>
*
- * Copyright (C) 2001-2002 Alcve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
*
* Copyright (C) 2000 Andrew Tridgell <tridge@valinux.com>
*
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index b8d4ac0d938..d55d5800efb 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -4668,7 +4668,6 @@ static struct video_device vdev_template = {
.owner = THIS_MODULE,
.name = "OV511 USB Camera",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_OV511,
.fops = &ov511_fops,
.release = video_device_release,
.minor = -1,
diff --git a/drivers/media/video/planb.c b/drivers/media/video/planb.c
index 0ef73d9d584..ce4b2f9791e 100644
--- a/drivers/media/video/planb.c
+++ b/drivers/media/video/planb.c
@@ -2013,7 +2013,6 @@ static struct video_device planb_template=
.owner = THIS_MODULE,
.name = PLANB_DEVICE_NAME,
.type = VID_TYPE_OVERLAY,
- .hardware = VID_HARDWARE_PLANB,
.open = planb_open,
.close = planb_close,
.read = planb_read,
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c
index b5a67f0dd19..6820c2aabd3 100644
--- a/drivers/media/video/pms.c
+++ b/drivers/media/video/pms.c
@@ -895,7 +895,6 @@ static struct video_device pms_template=
.owner = THIS_MODULE,
.name = "Mediavision PMS",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_PMS,
.fops = &pms_fops,
};
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 20b614436d2..205087a3e13 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -209,6 +209,11 @@ static int pvr2_encoder_cmd(void *ctxt,
LOCK_TAKE(hdw->ctl_lock); do {
+ if (!hdw->flag_encoder_ok) {
+ ret = -EIO;
+ break;
+ }
+
retry_flag = 0;
try_count++;
ret = 0;
@@ -273,6 +278,7 @@ static int pvr2_encoder_cmd(void *ctxt,
ret = -EBUSY;
}
if (ret) {
+ hdw->flag_encoder_ok = 0;
pvr2_trace(
PVR2_TRACE_ERROR_LEGS,
"Giving up on command."
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 985d9ae7f5e..f873994b088 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -225,11 +225,12 @@ struct pvr2_hdw {
unsigned int cmd_debug_write_len; //
unsigned int cmd_debug_read_len; //
- int flag_ok; // device in known good state
- int flag_disconnected; // flag_ok == 0 due to disconnect
- int flag_init_ok; // true if structure is fully initialized
- int flag_streaming_enabled; // true if streaming should be on
- int fw1_state; // current situation with fw1
+ int flag_ok; /* device in known good state */
+ int flag_disconnected; /* flag_ok == 0 due to disconnect */
+ int flag_init_ok; /* true if structure is fully initialized */
+ int flag_streaming_enabled; /* true if streaming should be on */
+ int fw1_state; /* current situation with fw1 */
+ int flag_encoder_ok; /* True if encoder is healthy */
int flag_decoder_is_tuned;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 27b12b4b5c8..402c5948825 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -1248,6 +1248,8 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
time we configure the encoder, then we'll fully configure it. */
hdw->enc_cur_valid = 0;
+ hdw->flag_encoder_ok = 0;
+
/* First prepare firmware loading */
ret |= pvr2_write_register(hdw, 0x0048, 0xffffffff); /*interrupt mask*/
ret |= pvr2_hdw_gpio_chg_dir(hdw,0xffffffff,0x00000088); /*gpio dir*/
@@ -1346,6 +1348,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw)
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
"firmware2 upload post-proc failure");
} else {
+ hdw->flag_encoder_ok = !0;
hdw->subsys_enabled_mask |= (1<<PVR2_SUBSYS_B_ENC_FIRMWARE);
}
return ret;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 4563b3df8a0..7a596ea7cfe 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -1121,15 +1121,12 @@ static const struct file_operations vdev_fops = {
};
-#define VID_HARDWARE_PVRUSB2 38 /* FIXME : need a good value */
-
static struct video_device vdev_template = {
.owner = THIS_MODULE,
.type = VID_TYPE_CAPTURE | VID_TYPE_TUNER,
.type2 = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE
| V4L2_CAP_TUNER | V4L2_CAP_AUDIO
| V4L2_CAP_READWRITE),
- .hardware = VID_HARDWARE_PVRUSB2,
.fops = &vdev_fops,
};
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 950da254214..7300ace8f44 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -166,7 +166,6 @@ static struct video_device pwc_template = {
.owner = THIS_MODULE,
.name = "Philips Webcam", /* Filled in later */
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_PWC,
.release = video_device_release,
.fops = &pwc_fops,
.minor = -1,
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e20aa3612a7..ad0232935df 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -196,10 +196,10 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
return i2c_sendbuf(t, buf[0], ct-1, buf+1);
}
-/* Get count number of bytes from IC-device at address adr, store them in buf.
+/* Get count number of bytes from I²C-device at address adr, store them in buf.
* Start & stop handshaking is done by this routine, ack will be sent after the
* last byte to inhibit further sending of data. If uaccess is 'true', data is
- * written to user-space with put_user. Returns -1 if IC-device didn't send
+ * written to user-space with put_user. Returns -1 if I²C-device didn't send
* acknowledge, 0 otherwise
*/
static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index 17f1e2e9a66..94bb59a32b1 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -291,10 +291,10 @@ static int i2c_senddata(struct saa5249_device *t, ...)
return i2c_sendbuf(t, buf[0], ct-1, buf+1);
}
-/* Get count number of bytes from IC-device at address adr, store them in buf. Start & stop
+/* Get count number of bytes from I²C-device at address adr, store them in buf. Start & stop
* handshaking is done by this routine, ack will be sent after the last byte to inhibit further
* sending of data. If uaccess is 'true', data is written to user-space with put_user.
- * Returns -1 if IC-device didn't send acknowledge, 0 otherwise
+ * Returns -1 if I²C-device didn't send acknowledge, 0 otherwise
*/
static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 57f1f5d409e..002e70a33a4 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -71,7 +71,6 @@ static const struct v4l2_format v4l2_format_table[] =
struct saa6752hs_state {
struct i2c_client client;
- struct v4l2_mpeg_compression old_params;
struct saa6752hs_mpeg_params params;
enum saa6752hs_videoformat video_format;
v4l2_std_id standard;
@@ -161,35 +160,6 @@ static struct saa6752hs_mpeg_params param_defaults =
.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K,
};
-static struct v4l2_mpeg_compression old_param_defaults =
-{
- .st_type = V4L2_MPEG_TS_2,
- .st_bitrate = {
- .mode = V4L2_BITRATE_CBR,
- .target = 7000,
- },
-
- .ts_pid_pmt = 16,
- .ts_pid_video = 260,
- .ts_pid_audio = 256,
- .ts_pid_pcr = 259,
-
- .vi_type = V4L2_MPEG_VI_2,
- .vi_aspect_ratio = V4L2_MPEG_ASPECT_4_3,
- .vi_bitrate = {
- .mode = V4L2_BITRATE_VBR,
- .target = 4000,
- .max = 6000,
- },
-
- .au_type = V4L2_MPEG_AU_2_II,
- .au_bitrate = {
- .mode = V4L2_BITRATE_CBR,
- .target = 256,
- },
-
-};
-
/* ---------------------------------------------------------------------- */
static int saa6752hs_chip_command(struct i2c_client* client,
@@ -362,74 +332,6 @@ static void saa6752hs_set_subsampling(struct i2c_client* client,
}
-static void saa6752hs_old_set_params(struct i2c_client* client,
- struct v4l2_mpeg_compression* params)
-{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
-
- /* check PIDs */
- if (params->ts_pid_pmt <= MPEG_PID_MAX) {
- h->old_params.ts_pid_pmt = params->ts_pid_pmt;
- h->params.ts_pid_pmt = params->ts_pid_pmt;
- }
- if (params->ts_pid_pcr <= MPEG_PID_MAX) {
- h->old_params.ts_pid_pcr = params->ts_pid_pcr;
- h->params.ts_pid_pcr = params->ts_pid_pcr;
- }
- if (params->ts_pid_video <= MPEG_PID_MAX) {
- h->old_params.ts_pid_video = params->ts_pid_video;
- h->params.ts_pid_video = params->ts_pid_video;
- }
- if (params->ts_pid_audio <= MPEG_PID_MAX) {
- h->old_params.ts_pid_audio = params->ts_pid_audio;
- h->params.ts_pid_audio = params->ts_pid_audio;
- }
-
- /* check bitrate parameters */
- if ((params->vi_bitrate.mode == V4L2_BITRATE_CBR) ||
- (params->vi_bitrate.mode == V4L2_BITRATE_VBR)) {
- h->old_params.vi_bitrate.mode = params->vi_bitrate.mode;
- h->params.vi_bitrate_mode = (params->vi_bitrate.mode == V4L2_BITRATE_VBR) ?
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR : V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
- }
- if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
- h->old_params.st_bitrate.target = params->st_bitrate.target;
- if (params->vi_bitrate.mode != V4L2_BITRATE_NONE)
- h->old_params.vi_bitrate.target = params->vi_bitrate.target;
- if (params->vi_bitrate.mode == V4L2_BITRATE_VBR)
- h->old_params.vi_bitrate.max = params->vi_bitrate.max;
- if (params->au_bitrate.mode != V4L2_BITRATE_NONE)
- h->old_params.au_bitrate.target = params->au_bitrate.target;
-
- /* aspect ratio */
- if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3 ||
- params->vi_aspect_ratio == V4L2_MPEG_ASPECT_16_9) {
- h->old_params.vi_aspect_ratio = params->vi_aspect_ratio;
- if (params->vi_aspect_ratio == V4L2_MPEG_ASPECT_4_3)
- h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3;
- else
- h->params.vi_aspect = V4L2_MPEG_VIDEO_ASPECT_16x9;
- }
-
- /* range checks */
- if (h->old_params.st_bitrate.target > MPEG_TOTAL_TARGET_BITRATE_MAX)
- h->old_params.st_bitrate.target = MPEG_TOTAL_TARGET_BITRATE_MAX;
- if (h->old_params.vi_bitrate.target > MPEG_VIDEO_TARGET_BITRATE_MAX)
- h->old_params.vi_bitrate.target = MPEG_VIDEO_TARGET_BITRATE_MAX;
- if (h->old_params.vi_bitrate.max > MPEG_VIDEO_MAX_BITRATE_MAX)
- h->old_params.vi_bitrate.max = MPEG_VIDEO_MAX_BITRATE_MAX;
- h->params.vi_bitrate = params->vi_bitrate.target;
- h->params.vi_bitrate_peak = params->vi_bitrate.max;
- if (h->old_params.au_bitrate.target <= 256) {
- h->old_params.au_bitrate.target = 256;
- h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- }
- else {
- h->old_params.au_bitrate.target = 384;
- h->params.au_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- }
-}
-
static int handle_ctrl(struct saa6752hs_mpeg_params *params,
struct v4l2_ext_control *ctrl, unsigned int cmd)
{
@@ -697,7 +599,6 @@ static int saa6752hs_attach(struct i2c_adapter *adap, int addr, int kind)
return -ENOMEM;
h->client = client_template;
h->params = param_defaults;
- h->old_params = old_param_defaults;
h->client.adapter = adap;
h->client.addr = addr;
@@ -734,23 +635,11 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
struct saa6752hs_state *h = i2c_get_clientdata(client);
struct v4l2_ext_controls *ctrls = arg;
- struct v4l2_mpeg_compression *old_params = arg;
struct saa6752hs_mpeg_params params;
int err = 0;
int i;
switch (cmd) {
- case VIDIOC_S_MPEGCOMP:
- if (NULL == old_params) {
- /* apply settings and start encoder */
- saa6752hs_init(client);
- break;
- }
- saa6752hs_old_set_params(client, old_params);
- /* fall through */
- case VIDIOC_G_MPEGCOMP:
- *old_params = h->old_params;
- break;
case VIDIOC_S_EXT_CTRLS:
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 1a4a24471f2..a499eea379e 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -429,7 +429,7 @@ int saa7134_set_dmabits(struct saa7134_dev *dev)
assert_spin_locked(&dev->slock);
- if (dev->inresume)
+ if (dev->insuspend)
return 0;
/* video capture -- dma 0 + video task A */
@@ -563,6 +563,9 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id)
unsigned long report,status;
int loop, handled = 0;
+ if (dev->insuspend)
+ goto out;
+
for (loop = 0; loop < 10; loop++) {
report = saa_readl(SAA7134_IRQ_REPORT);
status = saa_readl(SAA7134_IRQ_STATUS);
@@ -1163,6 +1166,7 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
kfree(dev);
}
+#ifdef CONFIG_PM
static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
{
@@ -1176,6 +1180,19 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
saa_writel(SAA7134_IRQ2, 0);
saa_writel(SAA7134_MAIN_CTRL, 0);
+ synchronize_irq(pci_dev->irq);
+ dev->insuspend = 1;
+
+ /* Disable timeout timers - if we have active buffers, we will
+ fill them on resume*/
+
+ del_timer(&dev->video_q.timeout);
+ del_timer(&dev->vbi_q.timeout);
+ del_timer(&dev->ts_q.timeout);
+
+ if (dev->remote)
+ saa7134_ir_stop(dev);
+
pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
pci_save_state(pci_dev);
@@ -1194,24 +1211,27 @@ static int saa7134_resume(struct pci_dev *pci_dev)
/* Do things that are done in saa7134_initdev ,
except of initializing memory structures.*/
- dev->inresume = 1;
saa7134_board_init1(dev);
+ /* saa7134_hwinit1 */
if (saa7134_boards[dev->board].video_out)
saa7134_videoport_init(dev);
-
if (card_has_mpeg(dev))
saa7134_ts_init_hw(dev);
-
+ if (dev->remote)
+ saa7134_ir_start(dev, dev->remote);
saa7134_hw_enable1(dev);
- saa7134_set_decoder(dev);
- saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+
+
saa7134_board_init2(dev);
- saa7134_hw_enable2(dev);
+ /*saa7134_hwinit2*/
+ saa7134_set_tvnorm_hw(dev);
saa7134_tvaudio_setmute(dev);
saa7134_tvaudio_setvolume(dev, dev->ctl_volume);
+ saa7134_tvaudio_do_scan(dev);
saa7134_enable_i2s(dev);
+ saa7134_hw_enable2(dev);
/*resume unfinished buffer(s)*/
spin_lock_irqsave(&dev->slock, flags);
@@ -1219,13 +1239,19 @@ static int saa7134_resume(struct pci_dev *pci_dev)
saa7134_buffer_requeue(dev, &dev->vbi_q);
saa7134_buffer_requeue(dev, &dev->ts_q);
+ /* FIXME: Disable DMA audio sound - temporary till proper support
+ is implemented*/
+
+ dev->dmasound.dma_running = 0;
+
/* start DMA now*/
- dev->inresume = 0;
+ dev->insuspend = 0;
saa7134_set_dmabits(dev);
spin_unlock_irqrestore(&dev->slock, flags);
return 0;
}
+#endif
/* ----------------------------------------------------------- */
@@ -1262,8 +1288,10 @@ static struct pci_driver saa7134_pci_driver = {
.id_table = saa7134_pci_tbl,
.probe = saa7134_initdev,
.remove = __devexit_p(saa7134_finidev),
+#ifdef CONFIG_PM
.suspend = saa7134_suspend,
.resume = saa7134_resume
+#endif
};
static int saa7134_init(void)
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 34ca874dd7f..75d0c5bf46d 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -284,17 +284,6 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_S_CTRL:
return saa7134_common_ioctl(dev, cmd, arg);
- case VIDIOC_S_MPEGCOMP:
- printk(KERN_WARNING "VIDIOC_S_MPEGCOMP is obsolete. "
- "Replace with VIDIOC_S_EXT_CTRLS!");
- saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
- ts_init_encoder(dev);
- return 0;
- case VIDIOC_G_MPEGCOMP:
- printk(KERN_WARNING "VIDIOC_G_MPEGCOMP is obsolete. "
- "Replace with VIDIOC_G_EXT_CTRLS!");
- saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
- return 0;
case VIDIOC_S_EXT_CTRLS:
/* count == 0 is abused in saa6752hs.c, so that special
case is handled here explicitly. */
@@ -342,7 +331,6 @@ static struct video_device saa7134_empress_template =
.name = "saa7134-empress",
.type = 0 /* FIXME */,
.type2 = 0 /* FIXME */,
- .hardware = 0,
.fops = &ts_fops,
.minor = -1,
};
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 80d2644f765..3abaa1b8ac9 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -44,6 +44,14 @@ module_param(ir_rc5_remote_gap, int, 0644);
static int ir_rc5_key_timeout = 115;
module_param(ir_rc5_key_timeout, int, 0644);
+static int repeat_delay = 500;
+module_param(repeat_delay, int, 0644);
+MODULE_PARM_DESC(repeat_delay, "delay before key repeat started");
+static int repeat_period = 33;
+module_param(repeat_period, int, 0644);
+MODULE_PARM_DESC(repeat_period, "repeat period between"
+ "keypresses when key is down");
+
#define dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
#define i2cdprintk(fmt, arg...) if (ir_debug) \
@@ -59,6 +67,13 @@ static int build_key(struct saa7134_dev *dev)
struct card_ir *ir = dev->remote;
u32 gpio, data;
+ /* here comes the additional handshake steps for some cards */
+ switch (dev->board) {
+ case SAA7134_BOARD_GOTVIEW_7135:
+ saa_setb(SAA7134_GPIO_GPSTATUS1, 0x80);
+ saa_clearb(SAA7134_GPIO_GPSTATUS1, 0x80);
+ break;
+ }
/* rising SAA7134_GPIO_GPRESCAN reads the status */
saa_clearb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
saa_setb(SAA7134_GPIO_GPMODE3,SAA7134_GPIO_GPRESCAN);
@@ -159,7 +174,7 @@ static void saa7134_input_timer(unsigned long data)
mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
}
-static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
{
if (ir->polling) {
setup_timer(&ir->timer, saa7134_input_timer,
@@ -182,7 +197,7 @@ static void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir)
}
}
-static void saa7134_ir_stop(struct saa7134_dev *dev)
+void saa7134_ir_stop(struct saa7134_dev *dev)
{
if (dev->remote->polling)
del_timer_sync(&dev->remote->timer);
@@ -285,10 +300,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_GOTVIEW_7135:
ir_codes = ir_codes_gotview7135;
- mask_keycode = 0x0003EC;
- mask_keyup = 0x008000;
+ mask_keycode = 0x0003CC;
mask_keydown = 0x000010;
- polling = 50; // ms
+ polling = 5; /* ms */
+ saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
break;
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -386,6 +401,10 @@ int saa7134_input_init1(struct saa7134_dev *dev)
if (err)
goto err_out_stop;
+ /* the remote isn't as bouncy as a keyboard */
+ ir->dev->rep[REP_DELAY] = repeat_delay;
+ ir->dev->rep[REP_PERIOD] = repeat_period;
+
return 0;
err_out_stop:
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index 1b9e39a5ea4..f8e304c7623 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -27,6 +27,7 @@
#include <linux/kthread.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/freezer.h>
#include <asm/div64.h>
#include "saa7134-reg.h"
@@ -231,7 +232,7 @@ static void mute_input_7134(struct saa7134_dev *dev)
}
if (dev->hw_mute == mute &&
- dev->hw_input == in && !dev->inresume) {
+ dev->hw_input == in && !dev->insuspend) {
dprintk("mute/input: nothing to do [mute=%d,input=%s]\n",
mute,in->name);
return;
@@ -502,13 +503,17 @@ static int tvaudio_thread(void *data)
unsigned int i, audio, nscan;
int max1,max2,carrier,rx,mode,lastmode,default_carrier;
- allow_signal(SIGTERM);
+
+ set_freezable();
+
for (;;) {
tvaudio_sleep(dev,-1);
- if (kthread_should_stop() || signal_pending(current))
+ if (kthread_should_stop())
goto done;
restart:
+ try_to_freeze();
+
dev->thread.scan1 = dev->thread.scan2;
dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
dev->tvaudio = NULL;
@@ -612,9 +617,12 @@ static int tvaudio_thread(void *data)
lastmode = 42;
for (;;) {
+
+ try_to_freeze();
+
if (tvaudio_sleep(dev,5000))
goto restart;
- if (kthread_should_stop() || signal_pending(current))
+ if (kthread_should_stop())
break;
if (UNSET == dev->thread.mode) {
rx = tvaudio_getstereo(dev,&tvaudio[i]);
@@ -630,6 +638,7 @@ static int tvaudio_thread(void *data)
}
done:
+ dev->thread.stopped = 1;
return 0;
}
@@ -777,7 +786,8 @@ static int tvaudio_thread_ddep(void *data)
struct saa7134_dev *dev = data;
u32 value, norms, clock;
- allow_signal(SIGTERM);
+
+ set_freezable();
clock = saa7134_boards[dev->board].audio_clock;
if (UNSET != audio_clock_override)
@@ -790,10 +800,13 @@ static int tvaudio_thread_ddep(void *data)
for (;;) {
tvaudio_sleep(dev,-1);
- if (kthread_should_stop() || signal_pending(current))
+ if (kthread_should_stop())
goto done;
restart:
+
+ try_to_freeze();
+
dev->thread.scan1 = dev->thread.scan2;
dprintk("tvaudio thread scan start [%d]\n",dev->thread.scan1);
@@ -870,6 +883,7 @@ static int tvaudio_thread_ddep(void *data)
}
done:
+ dev->thread.stopped = 1;
return 0;
}
@@ -997,7 +1011,7 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
int saa7134_tvaudio_fini(struct saa7134_dev *dev)
{
/* shutdown tvaudio thread */
- if (dev->thread.thread)
+ if (dev->thread.thread && !dev->thread.stopped)
kthread_stop(dev->thread.thread);
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x07, 0x00); /* LINE1 */
@@ -1013,7 +1027,9 @@ int saa7134_tvaudio_do_scan(struct saa7134_dev *dev)
} else if (dev->thread.thread) {
dev->thread.mode = UNSET;
dev->thread.scan2++;
- wake_up_process(dev->thread.thread);
+
+ if (!dev->insuspend && !dev->thread.stopped)
+ wake_up_process(dev->thread.thread);
} else {
dev->automute = 0;
saa7134_tvaudio_setmute(dev);
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index 471b92793c1..3b9ffb4b648 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -560,15 +560,8 @@ void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
dev->crop_current = dev->crop_defrect;
- saa7134_set_decoder(dev);
+ saa7134_set_tvnorm_hw(dev);
- if (card_in(dev, dev->ctl_input).tv) {
- if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
- && ((card(dev).tuner_config == 1)
- || (card(dev).tuner_config == 2)))
- saa7134_set_gpio(dev, 22, 5);
- saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &norm->id);
- }
}
static void video_mux(struct saa7134_dev *dev, int input)
@@ -579,7 +572,8 @@ static void video_mux(struct saa7134_dev *dev, int input)
saa7134_tvaudio_setinput(dev, &card_in(dev, input));
}
-void saa7134_set_decoder(struct saa7134_dev *dev)
+
+static void saa7134_set_decoder(struct saa7134_dev *dev)
{
int luma_control, sync_control, mux;
@@ -630,6 +624,19 @@ void saa7134_set_decoder(struct saa7134_dev *dev)
saa_writeb(SAA7134_RAW_DATA_OFFSET, 0x80);
}
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
+{
+ saa7134_set_decoder(dev);
+
+ if (card_in(dev, dev->ctl_input).tv) {
+ if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
+ && ((card(dev).tuner_config == 1)
+ || (card(dev).tuner_config == 2)))
+ saa7134_set_gpio(dev, 22, 5);
+ saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ }
+}
+
static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
{
static const struct {
@@ -2352,7 +2359,6 @@ struct video_device saa7134_video_template =
.name = "saa7134-video",
.type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
VID_TYPE_CLIPPING|VID_TYPE_SCALES,
- .hardware = 0,
.fops = &video_fops,
.minor = -1,
};
@@ -2361,7 +2367,6 @@ struct video_device saa7134_vbi_template =
{
.name = "saa7134-vbi",
.type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
- .hardware = 0,
.fops = &video_fops,
.minor = -1,
};
@@ -2370,7 +2375,6 @@ struct video_device saa7134_radio_template =
{
.name = "saa7134-radio",
.type = VID_TYPE_TUNER,
- .hardware = 0,
.fops = &radio_fops,
.minor = -1,
};
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 28ec6804bd5..66a390c321a 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -333,6 +333,7 @@ struct saa7134_thread {
unsigned int scan1;
unsigned int scan2;
unsigned int mode;
+ unsigned int stopped;
};
/* buffer for one video/vbi/ts frame */
@@ -524,7 +525,7 @@ struct saa7134_dev {
unsigned int hw_mute;
int last_carrier;
int nosignal;
- unsigned int inresume;
+ unsigned int insuspend;
/* SAA7134_MPEG_* */
struct saa7134_ts ts;
@@ -632,7 +633,7 @@ extern struct video_device saa7134_radio_template;
void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm);
int saa7134_videoport_init(struct saa7134_dev *dev);
-void saa7134_set_decoder(struct saa7134_dev *dev);
+void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);
int saa7134_common_ioctl(struct saa7134_dev *dev,
unsigned int cmd, void *arg);
@@ -706,6 +707,8 @@ int saa7134_input_init1(struct saa7134_dev *dev);
void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(struct saa7134_dev *dev);
void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
+void saa7134_ir_stop(struct saa7134_dev *dev);
/*
diff --git a/drivers/media/video/se401.c b/drivers/media/video/se401.c
index 93fb04ed99a..d5d7d6cf734 100644
--- a/drivers/media/video/se401.c
+++ b/drivers/media/video/se401.c
@@ -1231,7 +1231,6 @@ static struct video_device se401_template = {
.owner = THIS_MODULE,
.name = "se401 USB camera",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_SE401,
.fops = &se401_fops,
};
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 6991e06f765..511847912c4 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -3319,7 +3319,6 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "SN9C1xx PC Camera");
cam->v4ldev->owner = THIS_MODULE;
cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
- cam->v4ldev->hardware = 0;
cam->v4ldev->fops = &sn9c102_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c
index eb220461ac7..3fb85af5d1f 100644
--- a/drivers/media/video/stradis.c
+++ b/drivers/media/video/stradis.c
@@ -1917,7 +1917,6 @@ static const struct file_operations saa_fops = {
static struct video_device saa_template = {
.name = "SAA7146A",
.type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY,
- .hardware = VID_HARDWARE_SAA7146,
.fops = &saa_fops,
.minor = -1,
};
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
index 9e009a7ab86..afc32aa56fd 100644
--- a/drivers/media/video/stv680.c
+++ b/drivers/media/video/stv680.c
@@ -1398,7 +1398,6 @@ static struct video_device stv680_template = {
.owner = THIS_MODULE,
.name = "STV0680 USB camera",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_SE401,
.fops = &stv680_fops,
.release = video_device_release,
.minor = -1,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 94843086cda..6a777604f07 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -113,7 +113,7 @@ static void fe_standby(struct tuner *t)
static int fe_has_signal(struct tuner *t)
{
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- u16 strength;
+ u16 strength = 0;
if (fe_tuner_ops->get_rf_strength)
fe_tuner_ops->get_rf_strength(&t->fe, &strength);
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index 491505d6fde..3e93f805877 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -238,8 +238,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
usb_to_input_id(dev, &input_dev->id);
input_dev->dev.parent = &dev->dev;
- input_dev->evbit[0] = BIT(EV_KEY);
- input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
input_dev->private = cam;
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index dd1a6d6bbc9..d847273eeba 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -102,8 +102,8 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
usb_to_input_id(dev, &input_dev->id);
input_dev->dev.parent = &dev->dev;
- input_dev->evbit[0] = BIT(EV_KEY);
- input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY);
+ input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
input_dev->private = cam;
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 37ce36b9e58..fb434b5602a 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -952,7 +952,6 @@ static const struct file_operations usbvideo_fops = {
static const struct video_device usbvideo_template = {
.owner = THIS_MODULE,
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_CPIA,
.fops = &usbvideo_fops,
};
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index ff555129c82..da1ba021110 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -955,7 +955,7 @@ read_frame(struct vicam_camera *cam, int framenum)
request[7] = realShutter >> 8;
}
- // Per John Markus Bjrndalen, byte at index 8 causes problems if it isn't 0
+ // Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0
request[8] = 0;
// bytes 9-15 do not seem to affect exposure or image quality
@@ -1074,7 +1074,6 @@ static struct video_device vicam_template = {
.owner = THIS_MODULE,
.name = "ViCam-based USB Camera",
.type = VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_VICAM,
.fops = &vicam_fops,
.minor = -1,
};
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index e2f3c01cfa1..36e689fa16c 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -1400,7 +1400,6 @@ static const struct file_operations usbvision_fops = {
static struct video_device usbvision_video_template = {
.owner = THIS_MODULE,
.type = VID_TYPE_TUNER | VID_TYPE_CAPTURE,
- .hardware = VID_HARDWARE_USBVISION,
.fops = &usbvision_fops,
.name = "usbvision-video",
.release = video_device_release,
@@ -1455,7 +1454,6 @@ static struct video_device usbvision_radio_template=
{
.owner = THIS_MODULE,
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_USBVISION,
.fops = &usbvision_radio_fops,
.name = "usbvision-radio",
.release = video_device_release,
@@ -1492,7 +1490,6 @@ static struct video_device usbvision_vbi_template=
{
.owner = THIS_MODULE,
.type = VID_TYPE_TUNER,
- .hardware = VID_HARDWARE_USBVISION,
.fops = &usbvision_vbi_fops,
.release = video_device_release,
.name = "usbvision-vbi",
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index c3440b280d2..1141b4bf41c 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -37,7 +37,7 @@
* Video4linux 1/2 integration by Justin Schoeman
* <justin@suntiger.ee.up.ac.za>
* 2.4 PROCFS support ported from 2.4 kernels by
- * Iaki Garca Etxebarria <garetxe@euskalnet.net>
+ * Iñaki García Etxebarria <garetxe@euskalnet.net>
* Makefile fix by "W. Michael Petullo" <mike@flyn.org>
* 2.4 devfs support ported from 2.4 kernels by
* Dan Merillat <dan@merillat.org>
@@ -317,8 +317,6 @@ static const char *v4l2_ioctls[] = {
[_IOC_NR(VIDIOC_ENUM_FMT)] = "VIDIOC_ENUM_FMT",
[_IOC_NR(VIDIOC_G_FMT)] = "VIDIOC_G_FMT",
[_IOC_NR(VIDIOC_S_FMT)] = "VIDIOC_S_FMT",
- [_IOC_NR(VIDIOC_G_MPEGCOMP)] = "VIDIOC_G_MPEGCOMP",
- [_IOC_NR(VIDIOC_S_MPEGCOMP)] = "VIDIOC_S_MPEGCOMP",
[_IOC_NR(VIDIOC_REQBUFS)] = "VIDIOC_REQBUFS",
[_IOC_NR(VIDIOC_QUERYBUF)] = "VIDIOC_QUERYBUF",
[_IOC_NR(VIDIOC_G_FBUF)] = "VIDIOC_G_FBUF",
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 5599a36490f..89a44f16f0b 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -967,6 +967,7 @@ int videobuf_cgmbuf(struct videobuf_queue *q,
return 0;
}
+EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
#endif
/* --------------------------------------------------------------------- */
@@ -985,7 +986,6 @@ EXPORT_SYMBOL_GPL(videobuf_reqbufs);
EXPORT_SYMBOL_GPL(videobuf_querybuf);
EXPORT_SYMBOL_GPL(videobuf_qbuf);
EXPORT_SYMBOL_GPL(videobuf_dqbuf);
-EXPORT_SYMBOL_GPL(videobuf_cgmbuf);
EXPORT_SYMBOL_GPL(videobuf_streamon);
EXPORT_SYMBOL_GPL(videobuf_streamoff);
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 3eb6123227b..0a18286279d 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -60,12 +60,13 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
+ sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
if (NULL == pg)
goto err;
BUG_ON(PageHighMem(pg));
- sglist[i].page = pg;
+ sg_set_page(&sglist[i], pg);
sglist[i].length = PAGE_SIZE;
}
return sglist;
@@ -86,13 +87,14 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
sglist = kcalloc(nr_pages, sizeof(*sglist), GFP_KERNEL);
if (NULL == sglist)
return NULL;
+ sg_init_table(sglist, nr_pages);
if (NULL == pages[0])
goto nopage;
if (PageHighMem(pages[0]))
/* DMA to highmem pages might not work */
goto highmem;
- sglist[0].page = pages[0];
+ sg_set_page(&sglist[0], pages[0]);
sglist[0].offset = offset;
sglist[0].length = PAGE_SIZE - offset;
for (i = 1; i < nr_pages; i++) {
@@ -100,7 +102,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
goto nopage;
if (PageHighMem(pages[i]))
goto highmem;
- sglist[i].page = pages[i];
+ sg_set_page(&sglist[i], pages[i]);
sglist[i].length = PAGE_SIZE;
}
return sglist;
diff --git a/drivers/media/video/videocodec.c b/drivers/media/video/videocodec.c
index f2bbd7a4d56..87951ec8254 100644
--- a/drivers/media/video/videocodec.c
+++ b/drivers/media/video/videocodec.c
@@ -86,8 +86,8 @@ videocodec_attach (struct videocodec_master *master)
}
dprintk(2,
- "videocodec_attach: '%s', type: %x, flags %lx, magic %lx\n",
- master->name, master->type, master->flags, master->magic);
+ "videocodec_attach: '%s', flags %lx, magic %lx\n",
+ master->name, master->flags, master->magic);
if (!h) {
dprintk(1,
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 8d8e517b344..9611c399028 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -1313,48 +1313,6 @@ static int __video_do_ioctl(struct inode *inode, struct file *file,
ret=vfd->vidioc_cropcap(file, fh, p);
break;
}
- case VIDIOC_G_MPEGCOMP:
- {
- struct v4l2_mpeg_compression *p=arg;
-
- /*FIXME: Several fields not shown */
- if (!vfd->vidioc_g_mpegcomp)
- break;
- ret=vfd->vidioc_g_mpegcomp(file, fh, p);
- if (!ret)
- dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d,"
- " ts_pid_video=%d, ts_pid_pcr=%d, "
- "ps_size=%d, au_sample_rate=%d, "
- "au_pesid=%c, vi_frame_rate=%d, "
- "vi_frames_per_gop=%d, "
- "vi_bframes_count=%d, vi_pesid=%c\n",
- p->ts_pid_pmt,p->ts_pid_audio,
- p->ts_pid_video,p->ts_pid_pcr,
- p->ps_size, p->au_sample_rate,
- p->au_pesid, p->vi_frame_rate,
- p->vi_frames_per_gop,
- p->vi_bframes_count, p->vi_pesid);
- break;
- }
- case VIDIOC_S_MPEGCOMP:
- {
- struct v4l2_mpeg_compression *p=arg;
- /*FIXME: Several fields not shown */
- if (!vfd->vidioc_s_mpegcomp)
- break;
- dbgarg (cmd, "ts_pid_pmt=%d, ts_pid_audio=%d, "
- "ts_pid_video=%d, ts_pid_pcr=%d, ps_size=%d, "
- "au_sample_rate=%d, au_pesid=%c, "
- "vi_frame_rate=%d, vi_frames_per_gop=%d, "
- "vi_bframes_count=%d, vi_pesid=%c\n",
- p->ts_pid_pmt,p->ts_pid_audio, p->ts_pid_video,
- p->ts_pid_pcr, p->ps_size, p->au_sample_rate,
- p->au_pesid, p->vi_frame_rate,
- p->vi_frames_per_gop, p->vi_bframes_count,
- p->vi_pesid);
- ret=vfd->vidioc_s_mpegcomp(file, fh, p);
- break;
- }
case VIDIOC_G_JPEGCOMP:
{
struct v4l2_jpegcompression *p=arg;
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index b532aa280a1..ee73dc75131 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -1119,7 +1119,6 @@ static const struct file_operations vivi_fops = {
static struct video_device vivi = {
.name = "vivi",
.type = VID_TYPE_CAPTURE,
- .hardware = 0,
.fops = &vivi_fops,
.minor = -1,
// .release = video_device_release,
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 47366408637..08aaae07c7e 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -196,7 +196,6 @@ static struct video_device w9966_template = {
.owner = THIS_MODULE,
.name = W9966_DRIVERNAME,
.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
- .hardware = VID_HARDWARE_W9966,
.fops = &w9966_fops,
};
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 9e7f3e685d7..2ae1430f5f7 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -3549,7 +3549,6 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
cam->v4ldev->owner = THIS_MODULE;
cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
- cam->v4ldev->hardware = VID_HARDWARE_W9968CF;
cam->v4ldev->fops = &w9968cf_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 08a93c31c0a..2c5665c8244 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -1985,7 +1985,6 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
cam->v4ldev->owner = THIS_MODULE;
cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
- cam->v4ldev->hardware = 0;
cam->v4ldev->fops = &zc0301_fops;
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
diff --git a/drivers/media/video/zoran_card.c b/drivers/media/video/zoran_card.c
index 48da36a15fc..6e0ac4c5c37 100644
--- a/drivers/media/video/zoran_card.c
+++ b/drivers/media/video/zoran_card.c
@@ -1235,8 +1235,14 @@ zoran_setup_videocodec (struct zoran *zr,
return m;
}
- m->magic = 0L; /* magic not used */
- m->type = VID_HARDWARE_ZR36067;
+ /* magic and type are unused for master struct. Makes sense only at
+ codec structs.
+ In the past, .type were initialized to the old V4L1 .hardware
+ value, as VID_HARDWARE_ZR36067
+ */
+ m->magic = 0L;
+ m->type = 0;
+
m->flags = CODEC_FLAG_ENCODER | CODEC_FLAG_DECODER;
strncpy(m->name, ZR_DEVNAME(zr), sizeof(m->name));
m->data = zr;
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 1c14fa2bd41..dd3d7d2c8b0 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -60,7 +60,6 @@
#include <linux/spinlock.h>
#define MAP_NR(x) virt_to_page(x)
-#define ZORAN_HARDWARE VID_HARDWARE_ZR36067
#define ZORAN_VID_TYPE ( \
VID_TYPE_CAPTURE | \
VID_TYPE_OVERLAY | \
@@ -1285,7 +1284,7 @@ zoran_open (struct inode *inode,
}
dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
@@ -1358,7 +1357,7 @@ zoran_close (struct inode *inode,
struct zoran *zr = fh->zr;
dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), current->comm, current->pid, zr->user);
+ ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
@@ -4659,7 +4658,6 @@ struct video_device zoran_template __devinitdata = {
#ifdef CONFIG_VIDEO_V4L2
.type2 = ZORAN_V4L2_VID_FLAGS,
#endif
- .hardware = ZORAN_HARDWARE,
.fops = &zoran_fops,
.release = &zoran_vdev_release,
.minor = -1
diff --git a/drivers/message/i2o/README b/drivers/message/i2o/README
index a81f851f7b5..911fc3021e3 100644
--- a/drivers/message/i2o/README
+++ b/drivers/message/i2o/README
@@ -30,13 +30,13 @@ Juha Sievanen, University of Helsinki Finland
Bug fixes
Core code extensions
-Auvo Hkkinen, University of Helsinki Finland
+Auvo Häkkinen, University of Helsinki Finland
LAN OSM code
/Proc interface to LAN class
Bug fixes
Core code extensions
-Taneli Vhkangas, University of Helsinki Finland
+Taneli Vähäkangas, University of Helsinki Finland
Fixes to i2o_config
CREDITS
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index ce8f1a34ed2..6cbcc21de51 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -15,8 +15,8 @@
*
* Fixes/additions:
* Philipp Rumpf
- * Juha Sievnen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Hkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
* Deepak Saxena <deepak@plexity.net>
* Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
* Alan Cox <alan@redhat.com>:
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 84e046e94f5..c0fb77dc19b 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -10,12 +10,12 @@
* Added basic ioctl() support
* Deepak Saxena (06/07/1999):
* Added software download ioctl (still testing)
- * Auvo Hkkinen (09/10/1999):
+ * Auvo Häkkinen (09/10/1999):
* Changes to i2o_cfg_reply(), ioctl_parms()
* Added ioct_validate()
- * Taneli Vhkangas (09/30/1999):
+ * Taneli Vähäkangas (09/30/1999):
* Fixed ioctl_swdl()
- * Taneli Vhkangas (10/04/1999):
+ * Taneli Vähäkangas (10/04/1999):
* Changed ioctl_swdl(), implemented ioctl_swul() and ioctl_swdel()
* Deepak Saxena (11/18/1999):
* Added event managmenet support
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 06892ac2286..6fdd072201f 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -19,8 +19,8 @@
*
*
* Fixes/additions:
- * Juha Sievnen (Juha.Sievanen@cs.Helsinki.FI),
- * Auvo Hkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
+ * Juha Sievänen (Juha.Sievanen@cs.Helsinki.FI),
+ * Auvo Häkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
* University of Helsinki, Department of Computer Science
* LAN entries
* Markus Lidel <Markus.Lidel@shadowconnect.com>
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index a1ec16a075c..7814a06ae97 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -15,8 +15,8 @@
*
* Fixes/additions:
* Philipp Rumpf
- * Juha Sievnen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Hkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
* Deepak Saxena <deepak@plexity.net>
* Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
* Alan Cox <alan@redhat.com>:
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 3661e6e065d..685a89547a5 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -15,8 +15,8 @@
*
* Fixes/additions:
* Philipp Rumpf
- * Juha Sievnen <Juha.Sievanen@cs.Helsinki.FI>
- * Auvo Hkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
+ * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
+ * Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
* Deepak Saxena <deepak@plexity.net>
* Boji T Kannanthanam <boji.t.kannanthanam@intel.com>
* Alan Cox <alan@redhat.com>:
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a20a51efe11..25716193a53 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -10,8 +10,8 @@ config MFD_SM501
---help---
This is the core driver for the Silicon Motion SM501 multimedia
companion chip. This device is a multifunction device which may
- provide numerous interfaces including USB host controller USB gadget,
- Asyncronous Serial ports, Audio functions and a dual display video
+ provide numerous interfaces including USB host controller, USB gadget,
+ asynchronous serial ports, audio functions, and a dual display video
interface. The device may be connected by PCI or local bus with
varying functions enabled.
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 346c44eff95..b5e67c0ff43 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -111,6 +111,21 @@ config ASUS_LAPTOP
If you have an ACPI-compatible ASUS laptop, say Y or M here.
+config FUJITSU_LAPTOP
+ tristate "Fujitsu Laptop Extras"
+ depends on X86
+ depends on ACPI
+ depends on BACKLIGHT_CLASS_DEVICE
+ ---help---
+ This is a driver for laptops built by Fujitsu:
+
+ * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks
+ * Possibly other Fujitsu laptop models
+
+ It adds support for LCD brightness control.
+
+ If you have a Fujitsu laptop, say Y or M here.
+
config MSI_LAPTOP
tristate "MSI Laptop Extras"
depends on X86
@@ -134,6 +149,7 @@ config SONY_LAPTOP
tristate "Sony Laptop Extras"
depends on X86 && ACPI
select BACKLIGHT_CLASS_DEVICE
+ depends on INPUT
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
@@ -156,6 +172,7 @@ config THINKPAD_ACPI
select BACKLIGHT_CLASS_DEVICE
select HWMON
select NVRAM
+ depends on INPUT
---help---
This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
support for Fn-Fx key combinations, Bluetooth control, video
@@ -163,7 +180,7 @@ config THINKPAD_ACPI
For more information about this driver see
<file:Documentation/thinkpad-acpi.txt> and <http://ibm-acpi.sf.net/> .
- This driver was formely known as ibm-acpi.
+ This driver was formerly known as ibm-acpi.
If you have an IBM or Lenovo ThinkPad laptop, say Y or M here.
@@ -197,7 +214,7 @@ config THINKPAD_ACPI_BAY
default y
---help---
Allows the thinkpad_acpi driver to handle removable bays. It will
- eletrically disable the device in the bay, and also generate
+ electrically disable the device in the bay, and also generate
notifications when the bay lever is ejected or inserted.
If you are not sure, say Y here.
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a24c61475c2..87f2685d728 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -15,4 +15,5 @@ obj-$(CONFIG_PHANTOM) += phantom.o
obj-$(CONFIG_SGI_IOC4) += ioc4.o
obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
+obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c
new file mode 100644
index 00000000000..d366a6cc1fd
--- /dev/null
+++ b/drivers/misc/fujitsu-laptop.c
@@ -0,0 +1,358 @@
+/*-*-linux-c-*-*/
+
+/*
+ Copyright (C) 2007 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
+ Based on earlier work:
+ Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
+ Adrian Yee <brewt-fujitsu@brewt.org>
+
+ Templated from msi-laptop.c which is copyright by its respective authors.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+ */
+
+/*
+ * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional
+ * features made available on a range of Fujitsu laptops including the
+ * P2xxx/P5xxx/S6xxx/S7xxx series.
+ *
+ * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/;
+ * others may be added at a later date.
+ *
+ * lcd_level - Screen brightness: contains a single integer in the
+ * range 0..7. (rw)
+ *
+ * In addition to these platform device attributes the driver
+ * registers itself in the Linux backlight control subsystem and is
+ * available to userspace under /sys/class/backlight/fujitsu-laptop/.
+ *
+ * This driver has been tested on a Fujitsu Lifebook S7020. It should
+ * work on most P-series and S-series Lifebooks, but YMMV.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/autoconf.h>
+
+#define FUJITSU_DRIVER_VERSION "0.3"
+
+#define FUJITSU_LCD_N_LEVELS 8
+
+#define ACPI_FUJITSU_CLASS "fujitsu"
+#define ACPI_FUJITSU_HID "FUJ02B1"
+#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI extras driver"
+#define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1"
+
+struct fujitsu_t {
+ acpi_handle acpi_handle;
+ struct backlight_device *bl_device;
+ struct platform_device *pf_device;
+
+ unsigned long fuj02b1_state;
+ unsigned int brightness_changed;
+ unsigned int brightness_level;
+};
+
+static struct fujitsu_t *fujitsu;
+
+/* Hardware access */
+
+static int set_lcd_level(int level)
+{
+ acpi_status status = AE_OK;
+ union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+ struct acpi_object_list arg_list = { 1, &arg0 };
+ acpi_handle handle = NULL;
+
+ if (level < 0 || level >= FUJITSU_LCD_N_LEVELS)
+ return -EINVAL;
+
+ if (!fujitsu)
+ return -EINVAL;
+
+ status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle);
+ if (ACPI_FAILURE(status)) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n"));
+ return -ENODEV;
+ }
+
+ arg0.integer.value = level;
+
+ status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int get_lcd_level(void)
+{
+ unsigned long state = 0;
+ acpi_status status = AE_OK;
+
+ // Get the Brightness
+ status =
+ acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state);
+ if (status < 0)
+ return status;
+
+ fujitsu->fuj02b1_state = state;
+ fujitsu->brightness_level = state & 0x0fffffff;
+
+ if (state & 0x80000000)
+ fujitsu->brightness_changed = 1;
+ else
+ fujitsu->brightness_changed = 0;
+
+ if (status < 0)
+ return status;
+
+ return fujitsu->brightness_level;
+}
+
+/* Backlight device stuff */
+
+static int bl_get_brightness(struct backlight_device *b)
+{
+ return get_lcd_level();
+}
+
+static int bl_update_status(struct backlight_device *b)
+{
+ return set_lcd_level(b->props.brightness);
+}
+
+static struct backlight_ops fujitsubl_ops = {
+ .get_brightness = bl_get_brightness,
+ .update_status = bl_update_status,
+};
+
+/* Platform device */
+
+static ssize_t show_lcd_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ int ret;
+
+ ret = get_lcd_level();
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buf, "%i\n", ret);
+}
+
+static ssize_t store_lcd_level(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+
+ int level, ret;
+
+ if (sscanf(buf, "%i", &level) != 1
+ || (level < 0 || level >= FUJITSU_LCD_N_LEVELS))
+ return -EINVAL;
+
+ ret = set_lcd_level(level);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level);
+
+static struct attribute *fujitsupf_attributes[] = {
+ &dev_attr_lcd_level.attr,
+ NULL
+};
+
+static struct attribute_group fujitsupf_attribute_group = {
+ .attrs = fujitsupf_attributes
+};
+
+static struct platform_driver fujitsupf_driver = {
+ .driver = {
+ .name = "fujitsu-laptop",
+ .owner = THIS_MODULE,
+ }
+};
+
+/* ACPI device */
+
+int acpi_fujitsu_add(struct acpi_device *device)
+{
+ int result = 0;
+ int state = 0;
+
+ ACPI_FUNCTION_TRACE("acpi_fujitsu_add");
+
+ if (!device)
+ return -EINVAL;
+
+ fujitsu->acpi_handle = device->handle;
+ sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME);
+ sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS);
+ acpi_driver_data(device) = fujitsu;
+
+ result = acpi_bus_get_power(fujitsu->acpi_handle, &state);
+ if (result) {
+ ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
+ "Error reading power state\n"));
+ goto end;
+ }
+
+ printk(KERN_INFO PREFIX "%s [%s] (%s)\n",
+ acpi_device_name(device), acpi_device_bid(device),
+ !device->power.state ? "on" : "off");
+
+ end:
+
+ return result;
+}
+
+int acpi_fujitsu_remove(struct acpi_device *device, int type)
+{
+ ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ fujitsu->acpi_handle = 0;
+
+ return 0;
+}
+
+static const struct acpi_device_id fujitsu_device_ids[] = {
+ {ACPI_FUJITSU_HID, 0},
+ {"", 0},
+};
+
+static struct acpi_driver acpi_fujitsu_driver = {
+ .name = ACPI_FUJITSU_DRIVER_NAME,
+ .class = ACPI_FUJITSU_CLASS,
+ .ids = fujitsu_device_ids,
+ .ops = {
+ .add = acpi_fujitsu_add,
+ .remove = acpi_fujitsu_remove,
+ },
+};
+
+/* Initialization */
+
+static int __init fujitsu_init(void)
+{
+ int ret, result;
+
+ if (acpi_disabled)
+ return -ENODEV;
+
+ fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL);
+ if (!fujitsu)
+ return -ENOMEM;
+ memset(fujitsu, 0, sizeof(struct fujitsu_t));
+
+ result = acpi_bus_register_driver(&acpi_fujitsu_driver);
+ if (result < 0) {
+ ret = -ENODEV;
+ goto fail_acpi;
+ }
+
+ /* Register backlight stuff */
+
+ fujitsu->bl_device =
+ backlight_device_register("fujitsu-laptop", NULL, NULL,
+ &fujitsubl_ops);
+ if (IS_ERR(fujitsu->bl_device))
+ return PTR_ERR(fujitsu->bl_device);
+
+ fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1;
+ ret = platform_driver_register(&fujitsupf_driver);
+ if (ret)
+ goto fail_backlight;
+
+ /* Register platform stuff */
+
+ fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1);
+ if (!fujitsu->pf_device) {
+ ret = -ENOMEM;
+ goto fail_platform_driver;
+ }
+
+ ret = platform_device_add(fujitsu->pf_device);
+ if (ret)
+ goto fail_platform_device1;
+
+ ret =
+ sysfs_create_group(&fujitsu->pf_device->dev.kobj,
+ &fujitsupf_attribute_group);
+ if (ret)
+ goto fail_platform_device2;
+
+ printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
+ " successfully loaded.\n");
+
+ return 0;
+
+ fail_platform_device2:
+
+ platform_device_del(fujitsu->pf_device);
+
+ fail_platform_device1:
+
+ platform_device_put(fujitsu->pf_device);
+
+ fail_platform_driver:
+
+ platform_driver_unregister(&fujitsupf_driver);
+
+ fail_backlight:
+
+ backlight_device_unregister(fujitsu->bl_device);
+
+ fail_acpi:
+
+ kfree(fujitsu);
+
+ return ret;
+}
+
+static void __exit fujitsu_cleanup(void)
+{
+ sysfs_remove_group(&fujitsu->pf_device->dev.kobj,
+ &fujitsupf_attribute_group);
+ platform_device_unregister(fujitsu->pf_device);
+ platform_driver_unregister(&fujitsupf_driver);
+ backlight_device_unregister(fujitsu->bl_device);
+
+ acpi_bus_unregister_driver(&acpi_fujitsu_driver);
+
+ kfree(fujitsu);
+
+ printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
+}
+
+module_init(fujitsu_init);
+module_exit(fujitsu_cleanup);
+
+MODULE_AUTHOR("Jonathan Woithe");
+MODULE_DESCRIPTION("Fujitsu laptop extras support");
+MODULE_VERSION(FUJITSU_DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
index 0550ce075fc..477bb43c899 100644
--- a/drivers/misc/ibmasm/remote.c
+++ b/drivers/misc/ibmasm/remote.c
@@ -17,7 +17,7 @@
*
* Copyright (C) IBM Corporation, 2004
*
- * Authors: Max Asbck <amax@us.ibm.com>
+ * Authors: Max Asböck <amax@us.ibm.com>
* Vernon Mauery <vernux@us.ibm.com>
*
*/
@@ -226,9 +226,9 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp)
mouse_dev->id.product = pdev->device;
mouse_dev->id.version = 1;
mouse_dev->dev.parent = sp->dev;
- mouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) |
- BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+ mouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
set_bit(BTN_TOUCH, mouse_dev->keybit);
mouse_dev->name = "ibmasm RSA I remote mouse";
input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0);
@@ -239,7 +239,7 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp)
keybd_dev->id.product = pdev->device;
keybd_dev->id.version = 2;
keybd_dev->dev.parent = sp->dev;
- keybd_dev->evbit[0] = BIT(EV_KEY);
+ keybd_dev->evbit[0] = BIT_MASK(EV_KEY);
keybd_dev->name = "ibmasm RSA I remote keyboard";
for (i = 0; i < XLATE_SIZE; i++) {
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 5108b7c576d..cd221fd0fb9 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -9,6 +9,7 @@
* You need an userspace library to cooperate with this driver. It (and other
* info) may be obtained here:
* http://www.fi.muni.cz/~xslaby/phantom.html
+ * or alternatively, you might use OpenHaptics provided by Sensable.
*/
#include <linux/kernel.h>
@@ -24,13 +25,14 @@
#include <asm/atomic.h>
#include <asm/io.h>
-#define PHANTOM_VERSION "n0.9.5"
+#define PHANTOM_VERSION "n0.9.7"
#define PHANTOM_MAX_MINORS 8
#define PHN_IRQCTL 0x4c /* irq control in caddr space */
#define PHB_RUNNING 1
+#define PHB_NOT_OH 2
static struct class *phantom_class;
static int phantom_major;
@@ -47,7 +49,11 @@ struct phantom_device {
struct cdev cdev;
struct mutex open_lock;
- spinlock_t ioctl_lock;
+ spinlock_t regs_lock;
+
+ /* used in NOT_OH mode */
+ struct phm_regs oregs;
+ u32 ctl_reg;
};
static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -82,6 +88,7 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
struct phm_regs rs;
struct phm_reg r;
void __user *argp = (void __user *)arg;
+ unsigned long flags;
unsigned int i;
if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
@@ -96,32 +103,45 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
if (r.reg > 7)
return -EINVAL;
- spin_lock(&dev->ioctl_lock);
+ spin_lock_irqsave(&dev->regs_lock, flags);
if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
phantom_status(dev, dev->status | PHB_RUNNING)){
- spin_unlock(&dev->ioctl_lock);
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
return -ENODEV;
}
pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
+
+ /* preserve amp bit (don't allow to change it when in NOT_OH) */
+ if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) {
+ r.value &= ~PHN_CTL_AMP;
+ r.value |= dev->ctl_reg & PHN_CTL_AMP;
+ dev->ctl_reg = r.value;
+ }
+
iowrite32(r.value, dev->iaddr + r.reg);
ioread32(dev->iaddr); /* PCI posting */
if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
phantom_status(dev, dev->status & ~PHB_RUNNING);
- spin_unlock(&dev->ioctl_lock);
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
break;
case PHN_SET_REGS:
if (copy_from_user(&rs, argp, sizeof(rs)))
return -EFAULT;
pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
- spin_lock(&dev->ioctl_lock);
- for (i = 0; i < min(rs.count, 8U); i++)
- if ((1 << i) & rs.mask)
- iowrite32(rs.values[i], dev->oaddr + i);
- ioread32(dev->iaddr); /* PCI posting */
- spin_unlock(&dev->ioctl_lock);
+ spin_lock_irqsave(&dev->regs_lock, flags);
+ if (dev->status & PHB_NOT_OH)
+ memcpy(&dev->oregs, &rs, sizeof(rs));
+ else {
+ u32 m = min(rs.count, 8U);
+ for (i = 0; i < m; i++)
+ if (rs.mask & BIT(i))
+ iowrite32(rs.values[i], dev->oaddr + i);
+ ioread32(dev->iaddr); /* PCI posting */
+ }
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
break;
case PHN_GET_REG:
if (copy_from_user(&r, argp, sizeof(r)))
@@ -135,20 +155,35 @@ static long phantom_ioctl(struct file *file, unsigned int cmd,
if (copy_to_user(argp, &r, sizeof(r)))
return -EFAULT;
break;
- case PHN_GET_REGS:
+ case PHN_GET_REGS: {
+ u32 m;
+
if (copy_from_user(&rs, argp, sizeof(rs)))
return -EFAULT;
+ m = min(rs.count, 8U);
+
pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
- spin_lock(&dev->ioctl_lock);
- for (i = 0; i < min(rs.count, 8U); i++)
- if ((1 << i) & rs.mask)
+ spin_lock_irqsave(&dev->regs_lock, flags);
+ for (i = 0; i < m; i++)
+ if (rs.mask & BIT(i))
rs.values[i] = ioread32(dev->iaddr + i);
- spin_unlock(&dev->ioctl_lock);
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
if (copy_to_user(argp, &rs, sizeof(rs)))
return -EFAULT;
break;
+ } case PHN_NOT_OH:
+ spin_lock_irqsave(&dev->regs_lock, flags);
+ if (dev->status & PHB_RUNNING) {
+ printk(KERN_ERR "phantom: you need to set NOT_OH "
+ "before you start the device!\n");
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
+ return -EINVAL;
+ }
+ dev->status |= PHB_NOT_OH;
+ spin_unlock_irqrestore(&dev->regs_lock, flags);
+ break;
default:
return -ENOTTY;
}
@@ -171,8 +206,11 @@ static int phantom_open(struct inode *inode, struct file *file)
return -EINVAL;
}
+ WARN_ON(dev->status & PHB_NOT_OH);
+
file->private_data = dev;
+ atomic_set(&dev->counter, 0);
dev->opened++;
mutex_unlock(&dev->open_lock);
@@ -187,6 +225,7 @@ static int phantom_release(struct inode *inode, struct file *file)
dev->opened = 0;
phantom_status(dev, dev->status & ~PHB_RUNNING);
+ dev->status &= ~PHB_NOT_OH;
mutex_unlock(&dev->open_lock);
@@ -220,12 +259,32 @@ static struct file_operations phantom_file_ops = {
static irqreturn_t phantom_isr(int irq, void *data)
{
struct phantom_device *dev = data;
+ unsigned int i;
+ u32 ctl;
- if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
+ spin_lock(&dev->regs_lock);
+ ctl = ioread32(dev->iaddr + PHN_CONTROL);
+ if (!(ctl & PHN_CTL_IRQ)) {
+ spin_unlock(&dev->regs_lock);
return IRQ_NONE;
+ }
iowrite32(0, dev->iaddr);
iowrite32(0xc0, dev->iaddr);
+
+ if (dev->status & PHB_NOT_OH) {
+ struct phm_regs *r = &dev->oregs;
+ u32 m = min(r->count, 8U);
+
+ for (i = 0; i < m; i++)
+ if (r->mask & BIT(i))
+ iowrite32(r->values[i], dev->oaddr + i);
+
+ dev->ctl_reg ^= PHN_CTL_AMP;
+ iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL);
+ }
+ spin_unlock(&dev->regs_lock);
+
ioread32(dev->iaddr); /* PCI posting */
atomic_inc(&dev->counter);
@@ -297,7 +356,7 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
}
mutex_init(&pht->open_lock);
- spin_lock_init(&pht->ioctl_lock);
+ spin_lock_init(&pht->regs_lock);
init_waitqueue_head(&pht->wait);
cdev_init(&pht->cdev, &phantom_file_ops);
pht->cdev.owner = THIS_MODULE;
@@ -378,6 +437,8 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
iowrite32(0, dev->caddr + PHN_IRQCTL);
ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */
+ synchronize_irq(pdev->irq);
+
return 0;
}
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index e73a71f04bb..bb13858f60a 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -14,7 +14,7 @@
*
* Copyright (C) 2005 Narayanan R S <nars@kadamba.org>
*
- * Copyright (C) 2001-2002 Alcve <www.alcove.com>
+ * Copyright (C) 2001-2002 Alcôve <www.alcove.com>
*
* Copyright (C) 2001 Michael Ashley <m.ashley@unsw.edu.au>
*
@@ -277,7 +277,7 @@ static void do_sony_laptop_release_key(struct work_struct *work)
static DECLARE_WORK(sony_laptop_release_key_work,
do_sony_laptop_release_key);
-/* forward event to the input subsytem */
+/* forward event to the input subsystem */
static void sony_laptop_report_input_event(u8 event)
{
struct input_dev *jog_dev = sony_laptop_input.jog_dev;
@@ -411,9 +411,9 @@ static int sony_laptop_setup_input(void)
jog_dev->id.bustype = BUS_ISA;
jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
- jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
- jog_dev->relbit[0] = BIT(REL_WHEEL);
+ jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE);
+ jog_dev->relbit[0] = BIT_MASK(REL_WHEEL);
error = input_register_device(jog_dev);
if (error)
@@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE3_OFFSET 0x12
struct sony_pic_ioport {
- struct acpi_resource_io io;
+ struct acpi_resource_io io1;
+ struct acpi_resource_io io2;
struct list_head list;
};
@@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev)
{
u8 v1, v2;
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
ITERATIONS_LONG);
- outb(dev, spic_dev.cur_ioport->io.minimum + 4);
- v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4);
- v2 = inb_p(spic_dev.cur_ioport->io.minimum);
+ outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+ v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4);
+ v2 = inb_p(spic_dev.cur_ioport->io1.minimum);
dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1);
return v2;
}
@@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn)
{
u8 v1;
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
ITERATIONS_LONG);
- outb(dev, spic_dev.cur_ioport->io.minimum + 4);
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2,
+ outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2,
ITERATIONS_LONG);
- outb(fn, spic_dev.cur_ioport->io.minimum);
- v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+ outb(fn, spic_dev.cur_ioport->io1.minimum);
+ v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
dprintk("sony_pic_call2: 0x%.4x\n", v1);
return v1;
}
@@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
{
u8 v1;
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
- outb(dev, spic_dev.cur_ioport->io.minimum + 4);
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
- outb(fn, spic_dev.cur_ioport->io.minimum);
- wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG);
- outb(v, spic_dev.cur_ioport->io.minimum);
- v1 = inb_p(spic_dev.cur_ioport->io.minimum);
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+ outb(dev, spic_dev.cur_ioport->io1.minimum + 4);
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+ outb(fn, spic_dev.cur_ioport->io1.minimum);
+ wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG);
+ outb(v, spic_dev.cur_ioport->io1.minimum);
+ v1 = inb_p(spic_dev.cur_ioport->io1.minimum);
dprintk("sony_pic_call3: 0x%.4x\n", v1);
return v1;
}
@@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
+ {
+ /* start IO enumeration */
+ struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
+ if (!ioport)
+ return AE_ERROR;
+
+ list_add(&ioport->list, &dev->ioports);
+ return AE_OK;
+ }
+
case ACPI_RESOURCE_TYPE_END_DEPENDENT:
+ /* end IO enumeration */
return AE_OK;
case ACPI_RESOURCE_TYPE_IRQ:
@@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
if (!interrupt)
return AE_ERROR;
- list_add_tail(&interrupt->list, &dev->interrupts);
+ list_add(&interrupt->list, &dev->interrupts);
interrupt->irq.triggering = p->triggering;
interrupt->irq.polarity = p->polarity;
interrupt->irq.sharable = p->sharable;
@@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
case ACPI_RESOURCE_TYPE_IO:
{
struct acpi_resource_io *io = &resource->data.io;
- struct sony_pic_ioport *ioport = NULL;
+ struct sony_pic_ioport *ioport =
+ list_first_entry(&dev->ioports, struct sony_pic_ioport, list);
if (!io) {
dprintk("Blank IO resource\n");
return AE_OK;
}
- ioport = kzalloc(sizeof(*ioport), GFP_KERNEL);
- if (!ioport)
+ if (!ioport->io1.minimum) {
+ memcpy(&ioport->io1, io, sizeof(*io));
+ dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum,
+ ioport->io1.address_length);
+ }
+ else if (!ioport->io2.minimum) {
+ memcpy(&ioport->io2, io, sizeof(*io));
+ dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum,
+ ioport->io2.address_length);
+ }
+ else {
+ printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
return AE_ERROR;
-
- list_add_tail(&ioport->list, &dev->ioports);
- memcpy(&ioport->io, io, sizeof(*io));
+ }
return AE_OK;
}
default:
@@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device,
{
acpi_status status;
int result = 0;
+ /* Type 1 resource layout is:
+ * IO
+ * IO
+ * IRQNoFlags
+ * End
+ *
+ * Type 2 and 3 resource layout is:
+ * IO
+ * IRQNoFlags
+ * End
+ */
struct {
- struct acpi_resource io_res;
- struct acpi_resource irq_res;
- struct acpi_resource end;
+ struct acpi_resource res1;
+ struct acpi_resource res2;
+ struct acpi_resource res3;
+ struct acpi_resource res4;
} *resource;
struct acpi_buffer buffer = { 0, NULL };
@@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device,
buffer.length = sizeof(*resource) + 1;
buffer.pointer = resource;
- /* setup io resource */
- resource->io_res.type = ACPI_RESOURCE_TYPE_IO;
- resource->io_res.length = sizeof(struct acpi_resource);
- memcpy(&resource->io_res.data.io, &ioport->io,
- sizeof(struct acpi_resource_io));
+ /* setup Type 1 resources */
+ if (spic_dev.model == SONYPI_DEVICE_TYPE1) {
- /* setup irq resource */
- resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ;
- resource->irq_res.length = sizeof(struct acpi_resource);
- memcpy(&resource->irq_res.data.irq, &irq->irq,
- sizeof(struct acpi_resource_irq));
- /* we requested a shared irq */
- resource->irq_res.data.irq.sharable = ACPI_SHARED;
+ /* setup io resources */
+ resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+ resource->res1.length = sizeof(struct acpi_resource);
+ memcpy(&resource->res1.data.io, &ioport->io1,
+ sizeof(struct acpi_resource_io));
- resource->end.type = ACPI_RESOURCE_TYPE_END_TAG;
+ resource->res2.type = ACPI_RESOURCE_TYPE_IO;
+ resource->res2.length = sizeof(struct acpi_resource);
+ memcpy(&resource->res2.data.io, &ioport->io2,
+ sizeof(struct acpi_resource_io));
+
+ /* setup irq resource */
+ resource->res3.type = ACPI_RESOURCE_TYPE_IRQ;
+ resource->res3.length = sizeof(struct acpi_resource);
+ memcpy(&resource->res3.data.irq, &irq->irq,
+ sizeof(struct acpi_resource_irq));
+ /* we requested a shared irq */
+ resource->res3.data.irq.sharable = ACPI_SHARED;
+
+ resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG;
+
+ }
+ /* setup Type 2/3 resources */
+ else {
+ /* setup io resource */
+ resource->res1.type = ACPI_RESOURCE_TYPE_IO;
+ resource->res1.length = sizeof(struct acpi_resource);
+ memcpy(&resource->res1.data.io, &ioport->io1,
+ sizeof(struct acpi_resource_io));
+
+ /* setup irq resource */
+ resource->res2.type = ACPI_RESOURCE_TYPE_IRQ;
+ resource->res2.length = sizeof(struct acpi_resource);
+ memcpy(&resource->res2.data.irq, &irq->irq,
+ sizeof(struct acpi_resource_irq));
+ /* we requested a shared irq */
+ resource->res2.data.irq.sharable = ACPI_SHARED;
+
+ resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG;
+ }
/* Attempt to set the resource */
dprintk("Evaluating _SRS\n");
@@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device,
/* check for total failure */
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR DRV_PFX "Error evaluating _SRS");
+ printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
result = -ENODEV;
goto end;
}
@@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id;
- ev = inb_p(dev->cur_ioport->io.minimum);
- data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset);
+ ev = inb_p(dev->cur_ioport->io1.minimum);
+ if (dev->cur_ioport->io2.minimum)
+ data_mask = inb_p(dev->cur_ioport->io2.minimum);
+ else
+ data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset);
dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n",
- ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset);
+ ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);
if (ev == 0x00 || ev == 0xff)
return IRQ_HANDLED;
@@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type)
}
free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
- release_region(spic_dev.cur_ioport->io.minimum,
- spic_dev.cur_ioport->io.address_length);
+ release_region(spic_dev.cur_ioport->io1.minimum,
+ spic_dev.cur_ioport->io1.address_length);
+ if (spic_dev.cur_ioport->io2.minimum)
+ release_region(spic_dev.cur_ioport->io2.minimum,
+ spic_dev.cur_ioport->io2.address_length);
sonypi_compat_exit();
@@ -2397,14 +2464,36 @@ static int sony_pic_add(struct acpi_device *device)
goto err_remove_input;
/* request io port */
- list_for_each_entry(io, &spic_dev.ioports, list) {
- if (request_region(io->io.minimum, io->io.address_length,
+ list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
+ if (request_region(io->io1.minimum, io->io1.address_length,
"Sony Programable I/O Device")) {
- dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n",
- io->io.minimum, io->io.maximum,
- io->io.address_length);
- spic_dev.cur_ioport = io;
- break;
+ dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
+ io->io1.minimum, io->io1.maximum,
+ io->io1.address_length);
+ /* Type 1 have 2 ioports */
+ if (io->io2.minimum) {
+ if (request_region(io->io2.minimum,
+ io->io2.address_length,
+ "Sony Programable I/O Device")) {
+ dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
+ io->io2.minimum, io->io2.maximum,
+ io->io2.address_length);
+ spic_dev.cur_ioport = io;
+ break;
+ }
+ else {
+ dprintk("Unable to get I/O port2: "
+ "0x%.4x (0x%.4x) + 0x%.2x\n",
+ io->io2.minimum, io->io2.maximum,
+ io->io2.address_length);
+ release_region(io->io1.minimum,
+ io->io1.address_length);
+ }
+ }
+ else {
+ spic_dev.cur_ioport = io;
+ break;
+ }
}
}
if (!spic_dev.cur_ioport) {
@@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device)
}
/* request IRQ */
- list_for_each_entry(irq, &spic_dev.interrupts, list) {
+ list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) {
if (!request_irq(irq->irq.interrupts[0], sony_pic_irq,
IRQF_SHARED, "sony-laptop", &spic_dev)) {
dprintk("IRQ: %d - triggering: %d - "
@@ -2462,8 +2551,11 @@ err_free_irq:
free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev);
err_release_region:
- release_region(spic_dev.cur_ioport->io.minimum,
- spic_dev.cur_ioport->io.address_length);
+ release_region(spic_dev.cur_ioport->io1.minimum,
+ spic_dev.cur_ioport->io1.address_length);
+ if (spic_dev.cur_ioport->io2.minimum)
+ release_region(spic_dev.cur_ioport->io2.minimum,
+ spic_dev.cur_ioport->io2.address_length);
err_remove_compat:
sonypi_compat_exit();
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index 81e068fa7ac..e953276664a 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -22,7 +22,7 @@
*/
#define IBM_VERSION "0.16"
-#define TPACPI_SYSFS_VERSION 0x010000
+#define TPACPI_SYSFS_VERSION 0x020000
/*
* Changelog:
@@ -117,6 +117,12 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");
#define __unused __attribute__ ((unused))
+static enum {
+ TPACPI_LIFE_INIT = 0,
+ TPACPI_LIFE_RUNNING,
+ TPACPI_LIFE_EXITING,
+} tpacpi_lifecycle;
+
/****************************************************************************
****************************************************************************
*
@@ -342,6 +348,9 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data)
{
struct ibm_struct *ibm = data;
+ if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+ return;
+
if (!ibm || !ibm->acpi || !ibm->acpi->notify)
return;
@@ -517,8 +526,10 @@ static char *next_cmd(char **cmds)
****************************************************************************/
static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
static struct device *tpacpi_hwmon;
static struct input_dev *tpacpi_inputdev;
+static struct mutex tpacpi_inputdev_send_mutex;
static int tpacpi_resume_handler(struct platform_device *pdev)
@@ -543,6 +554,12 @@ static struct platform_driver tpacpi_pdriver = {
.resume = tpacpi_resume_handler,
};
+static struct platform_driver tpacpi_hwmon_pdriver = {
+ .driver = {
+ .name = IBM_HWMON_DRVR_NAME,
+ .owner = THIS_MODULE,
+ },
+};
/*************************************************************************
* thinkpad-acpi driver attributes
@@ -692,6 +709,8 @@ static int parse_strtoul(const char *buf,
{
char *endp;
+ while (*buf && isspace(*buf))
+ buf++;
*value = simple_strtoul(buf, &endp, 0);
while (*endp && isspace(*endp))
endp++;
@@ -989,6 +1008,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
int res, i;
int status;
+ int hkeyv;
vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
@@ -1014,18 +1034,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
return res;
/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p,
- A30, R30, R31, T20-22, X20-21, X22-24 */
- tp_features.hotkey_mask =
- acpi_evalf(hkey_handle, NULL, "DHKN", "qv");
+ A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking
+ for HKEY interface version 0x100 */
+ if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
+ if ((hkeyv >> 8) != 1) {
+ printk(IBM_ERR "unknown version of the "
+ "HKEY interface: 0x%x\n", hkeyv);
+ printk(IBM_ERR "please report this to %s\n",
+ IBM_MAIL);
+ } else {
+ /*
+ * MHKV 0x100 in A31, R40, R40e,
+ * T4x, X31, and later
+ * */
+ tp_features.hotkey_mask = 1;
+ }
+ }
vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
str_supported(tp_features.hotkey_mask));
if (tp_features.hotkey_mask) {
- /* MHKA available in A31, R40, R40e, T4x, X31, and later */
if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
- "MHKA", "qd"))
+ "MHKA", "qd")) {
+ printk(IBM_ERR
+ "missing MHKA handler, "
+ "please report this to %s\n",
+ IBM_MAIL);
hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */
+ }
}
res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask);
@@ -1131,6 +1168,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
unsigned int keycode)
{
if (keycode != KEY_RESERVED) {
+ mutex_lock(&tpacpi_inputdev_send_mutex);
+
input_report_key(tpacpi_inputdev, keycode, 1);
if (keycode == KEY_UNKNOWN)
input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
@@ -1142,6 +1181,8 @@ static void tpacpi_input_send_key(unsigned int scancode,
input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
scancode);
input_sync(tpacpi_inputdev);
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
}
}
@@ -1149,18 +1190,47 @@ static void tpacpi_input_send_radiosw(void)
{
int wlsw;
- if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw))
+ mutex_lock(&tpacpi_inputdev_send_mutex);
+
+ if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
input_report_switch(tpacpi_inputdev,
SW_RADIO, !!wlsw);
+ input_sync(tpacpi_inputdev);
+ }
+
+ mutex_unlock(&tpacpi_inputdev_send_mutex);
}
static void hotkey_notify(struct ibm_struct *ibm, u32 event)
{
u32 hkey;
unsigned int keycode, scancode;
- int send_acpi_ev = 0;
+ int send_acpi_ev;
+ int ignore_acpi_ev;
+
+ if (event != 0x80) {
+ printk(IBM_ERR "unknown HKEY notification event %d\n", event);
+ /* forward it to userspace, maybe it knows how to handle it */
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, 0);
+ return;
+ }
+
+ while (1) {
+ if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
+ printk(IBM_ERR "failed to retrieve HKEY event\n");
+ return;
+ }
+
+ if (hkey == 0) {
+ /* queue empty */
+ return;
+ }
+
+ send_acpi_ev = 0;
+ ignore_acpi_ev = 0;
- if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
switch (hkey >> 12) {
case 1:
/* 0x1000-0x1FFF: key presses */
@@ -1182,9 +1252,11 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
* eat up known LID events */
if (hkey != 0x5001 && hkey != 0x5002) {
printk(IBM_ERR
- "unknown LID-related hotkey event: 0x%04x\n",
- hkey);
+ "unknown LID-related HKEY event: 0x%04x\n",
+ hkey);
send_acpi_ev = 1;
+ } else {
+ ignore_acpi_ev = 1;
}
break;
case 7:
@@ -1202,21 +1274,18 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
send_acpi_ev = 1;
}
- } else {
- printk(IBM_ERR "unknown hotkey notification event %d\n", event);
- hkey = 0;
- send_acpi_ev = 1;
- }
- /* Legacy events */
- if (send_acpi_ev || hotkey_report_mode < 2)
- acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+ /* Legacy events */
+ if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) {
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+ }
- /* netlink events */
- if (send_acpi_ev) {
- acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
- ibm->acpi->device->dev.bus_id,
- event, hkey);
+ /* netlink events */
+ if (!ignore_acpi_ev && send_acpi_ev) {
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, hkey);
+ }
}
}
@@ -2812,7 +2881,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
switch(thermal_read_mode) {
case TPACPI_THERMAL_TPEC_16:
- res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+ res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
&thermal_temp_input16_group);
if (res)
return res;
@@ -2820,7 +2889,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm)
case TPACPI_THERMAL_TPEC_8:
case TPACPI_THERMAL_ACPI_TMP07:
case TPACPI_THERMAL_ACPI_UPDT:
- res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+ res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
&thermal_temp_input8_group);
if (res)
return res;
@@ -2837,13 +2906,13 @@ static void thermal_exit(void)
{
switch(thermal_read_mode) {
case TPACPI_THERMAL_TPEC_16:
- sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+ sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
&thermal_temp_input16_group);
break;
case TPACPI_THERMAL_TPEC_8:
case TPACPI_THERMAL_ACPI_TMP07:
case TPACPI_THERMAL_ACPI_UPDT:
- sysfs_remove_group(&tpacpi_pdev->dev.kobj,
+ sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
&thermal_temp_input16_group);
break;
case TPACPI_THERMAL_NONE:
@@ -3626,7 +3695,7 @@ static struct device_attribute dev_attr_fan_fan1_input =
__ATTR(fan1_input, S_IRUGO,
fan_fan1_input_show, NULL);
-/* sysfs fan fan_watchdog (driver) ------------------------------------- */
+/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */
static ssize_t fan_fan_watchdog_show(struct device_driver *drv,
char *buf)
{
@@ -3768,10 +3837,10 @@ static int __init fan_init(struct ibm_init_struct *iibm)
if (fan_status_access_mode != TPACPI_FAN_NONE ||
fan_control_access_mode != TPACPI_FAN_WR_NONE) {
- rc = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+ rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj,
&fan_attr_group);
if (!(rc < 0))
- rc = driver_create_file(&tpacpi_pdriver.driver,
+ rc = driver_create_file(&tpacpi_hwmon_pdriver.driver,
&driver_attr_fan_watchdog);
if (rc < 0)
return rc;
@@ -3854,8 +3923,8 @@ static void fan_exit(void)
vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n");
/* FIXME: can we really do this unconditionally? */
- sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group);
- driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog);
+ sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group);
+ driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog);
cancel_delayed_work(&fan_watchdog_task);
flush_scheduled_work();
@@ -3888,6 +3957,9 @@ static void fan_watchdog_fire(struct work_struct *ignored)
{
int rc;
+ if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
+ return;
+
printk(IBM_NOTICE "fan watchdog: enabling fan\n");
rc = fan_set_enable();
if (rc < 0) {
@@ -3908,7 +3980,8 @@ static void fan_watchdog_reset(void)
if (fan_watchdog_active)
cancel_delayed_work(&fan_watchdog_task);
- if (fan_watchdog_maxinterval > 0) {
+ if (fan_watchdog_maxinterval > 0 &&
+ tpacpi_lifecycle != TPACPI_LIFE_EXITING) {
fan_watchdog_active = 1;
if (!schedule_delayed_work(&fan_watchdog_task,
msecs_to_jiffies(fan_watchdog_maxinterval
@@ -4302,6 +4375,19 @@ static struct ibm_struct fan_driver_data = {
****************************************************************************
****************************************************************************/
+/* sysfs name ---------------------------------------------------------- */
+static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME);
+}
+
+static struct device_attribute dev_attr_thinkpad_acpi_pdev_name =
+ __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL);
+
+/* --------------------------------------------------------------------- */
+
/* /proc support */
static struct proc_dir_entry *proc_dir;
@@ -4674,6 +4760,8 @@ static int __init thinkpad_acpi_module_init(void)
{
int ret, i;
+ tpacpi_lifecycle = TPACPI_LIFE_INIT;
+
/* Parameter checking */
if (hotkey_report_mode > 2)
return -EINVAL;
@@ -4702,19 +4790,31 @@ static int __init thinkpad_acpi_module_init(void)
ret = platform_driver_register(&tpacpi_pdriver);
if (ret) {
- printk(IBM_ERR "unable to register platform driver\n");
+ printk(IBM_ERR "unable to register main platform driver\n");
thinkpad_acpi_module_exit();
return ret;
}
tp_features.platform_drv_registered = 1;
+ ret = platform_driver_register(&tpacpi_hwmon_pdriver);
+ if (ret) {
+ printk(IBM_ERR "unable to register hwmon platform driver\n");
+ thinkpad_acpi_module_exit();
+ return ret;
+ }
+ tp_features.sensors_pdrv_registered = 1;
+
ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
+ if (!ret) {
+ tp_features.platform_drv_attrs_registered = 1;
+ ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver);
+ }
if (ret) {
printk(IBM_ERR "unable to create sysfs driver attributes\n");
thinkpad_acpi_module_exit();
return ret;
}
- tp_features.platform_drv_attrs_registered = 1;
+ tp_features.sensors_pdrv_attrs_registered = 1;
/* Device initialization */
@@ -4727,7 +4827,26 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit();
return ret;
}
- tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev);
+ tpacpi_sensors_pdev = platform_device_register_simple(
+ IBM_HWMON_DRVR_NAME,
+ -1, NULL, 0);
+ if (IS_ERR(tpacpi_sensors_pdev)) {
+ ret = PTR_ERR(tpacpi_sensors_pdev);
+ tpacpi_sensors_pdev = NULL;
+ printk(IBM_ERR "unable to register hwmon platform device\n");
+ thinkpad_acpi_module_exit();
+ return ret;
+ }
+ ret = device_create_file(&tpacpi_sensors_pdev->dev,
+ &dev_attr_thinkpad_acpi_pdev_name);
+ if (ret) {
+ printk(IBM_ERR
+ "unable to create sysfs hwmon device attributes\n");
+ thinkpad_acpi_module_exit();
+ return ret;
+ }
+ tp_features.sensors_pdev_attrs_registered = 1;
+ tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev);
if (IS_ERR(tpacpi_hwmon)) {
ret = PTR_ERR(tpacpi_hwmon);
tpacpi_hwmon = NULL;
@@ -4735,6 +4854,7 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit();
return ret;
}
+ mutex_init(&tpacpi_inputdev_send_mutex);
tpacpi_inputdev = input_allocate_device();
if (!tpacpi_inputdev) {
printk(IBM_ERR "unable to allocate input device\n");
@@ -4769,6 +4889,7 @@ static int __init thinkpad_acpi_module_init(void)
tp_features.input_device_registered = 1;
}
+ tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
return 0;
}
@@ -4776,6 +4897,8 @@ static void thinkpad_acpi_module_exit(void)
{
struct ibm_struct *ibm, *itmp;
+ tpacpi_lifecycle = TPACPI_LIFE_EXITING;
+
list_for_each_entry_safe_reverse(ibm, itmp,
&tpacpi_all_drivers,
all_drivers) {
@@ -4794,12 +4917,22 @@ static void thinkpad_acpi_module_exit(void)
if (tpacpi_hwmon)
hwmon_device_unregister(tpacpi_hwmon);
+ if (tp_features.sensors_pdev_attrs_registered)
+ device_remove_file(&tpacpi_sensors_pdev->dev,
+ &dev_attr_thinkpad_acpi_pdev_name);
+ if (tpacpi_sensors_pdev)
+ platform_device_unregister(tpacpi_sensors_pdev);
if (tpacpi_pdev)
platform_device_unregister(tpacpi_pdev);
+ if (tp_features.sensors_pdrv_attrs_registered)
+ tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver);
if (tp_features.platform_drv_attrs_registered)
tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
+ if (tp_features.sensors_pdrv_registered)
+ platform_driver_unregister(&tpacpi_hwmon_pdriver);
+
if (tp_features.platform_drv_registered)
platform_driver_unregister(&tpacpi_pdriver);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index acd5835ec88..3abcc812063 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -58,13 +58,14 @@
#define IBM_NAME "thinkpad"
#define IBM_DESC "ThinkPad ACPI Extras"
-#define IBM_FILE "thinkpad_acpi"
+#define IBM_FILE IBM_NAME "_acpi"
#define IBM_URL "http://ibm-acpi.sf.net/"
#define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net"
#define IBM_PROC_DIR "ibm"
#define IBM_ACPI_EVENT_PREFIX "ibm"
#define IBM_DRVR_NAME IBM_FILE
+#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"
#define IBM_LOG IBM_FILE ": "
#define IBM_ERR KERN_ERR IBM_LOG
@@ -171,6 +172,7 @@ static int parse_strtoul(const char *buf, unsigned long max,
/* Device model */
static struct platform_device *tpacpi_pdev;
+static struct platform_device *tpacpi_sensors_pdev;
static struct device *tpacpi_hwmon;
static struct platform_driver tpacpi_pdriver;
static struct input_dev *tpacpi_inputdev;
@@ -233,22 +235,25 @@ struct ibm_init_struct {
static struct {
#ifdef CONFIG_THINKPAD_ACPI_BAY
- u16 bay_status:1;
- u16 bay_eject:1;
- u16 bay_status2:1;
- u16 bay_eject2:1;
+ u32 bay_status:1;
+ u32 bay_eject:1;
+ u32 bay_status2:1;
+ u32 bay_eject2:1;
#endif
- u16 bluetooth:1;
- u16 hotkey:1;
- u16 hotkey_mask:1;
- u16 hotkey_wlsw:1;
- u16 light:1;
- u16 light_status:1;
- u16 wan:1;
- u16 fan_ctrl_status_undef:1;
- u16 input_device_registered:1;
- u16 platform_drv_registered:1;
- u16 platform_drv_attrs_registered:1;
+ u32 bluetooth:1;
+ u32 hotkey:1;
+ u32 hotkey_mask:1;
+ u32 hotkey_wlsw:1;
+ u32 light:1;
+ u32 light_status:1;
+ u32 wan:1;
+ u32 fan_ctrl_status_undef:1;
+ u32 input_device_registered:1;
+ u32 platform_drv_registered:1;
+ u32 platform_drv_attrs_registered:1;
+ u32 sensors_pdrv_registered:1;
+ u32 sensors_pdrv_attrs_registered:1;
+ u32 sensors_pdev_attrs_registered:1;
} tp_features;
struct thinkpad_id_data {
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index a5d0354bbbd..9203a0b221b 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -13,6 +13,7 @@
#include <linux/blkdev.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
+#include <linux/scatterlist.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -153,19 +154,21 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
blk_queue_max_segment_size(mq->queue, bouncesz);
- mq->sg = kzalloc(sizeof(struct scatterlist),
+ mq->sg = kmalloc(sizeof(struct scatterlist),
GFP_KERNEL);
if (!mq->sg) {
ret = -ENOMEM;
goto cleanup_queue;
}
+ sg_init_table(mq->sg, 1);
- mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
+ mq->bounce_sg = kmalloc(sizeof(struct scatterlist) *
bouncesz / 512, GFP_KERNEL);
if (!mq->bounce_sg) {
ret = -ENOMEM;
goto cleanup_queue;
}
+ sg_init_table(mq->bounce_sg, bouncesz / 512);
}
}
#endif
@@ -302,12 +305,12 @@ static void copy_sg(struct scatterlist *dst, unsigned int dst_len,
BUG_ON(dst_len == 0);
if (dst_size == 0) {
- dst_buf = page_address(dst->page) + dst->offset;
+ dst_buf = sg_virt(dst);
dst_size = dst->length;
}
if (src_size == 0) {
- src_buf = page_address(src->page) + src->offset;
+ src_buf = sg_virt(dst);
src_size = src->length;
}
@@ -353,9 +356,7 @@ unsigned int mmc_queue_map_sg(struct mmc_queue *mq)
return 1;
}
- mq->sg[0].page = virt_to_page(mq->bounce_buf);
- mq->sg[0].offset = offset_in_page(mq->bounce_buf);
- mq->sg[0].length = 0;
+ sg_init_one(mq->sg, mq->bounce_buf, 0);
while (sg_len) {
mq->sg[0].length += mq->bounce_sg[sg_len - 1].length;
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 7a452c2ad1f..b1edcefdd4f 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -149,7 +149,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
sg = &data->sg[i];
- sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+ sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
amount = min(size, sg->length);
size -= amount;
@@ -226,7 +226,7 @@ static void at91_mci_pre_dma_read(struct at91mci_host *host)
sg = &data->sg[host->transfer_index++];
pr_debug("sg = %p\n", sg);
- sg->dma_address = dma_map_page(NULL, sg->page, sg->offset, sg->length, DMA_FROM_DEVICE);
+ sg->dma_address = dma_map_page(NULL, sg_page(sg), sg->offset, sg->length, DMA_FROM_DEVICE);
pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
@@ -283,7 +283,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
int index;
/* Swap the contents of the buffer */
- buffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
+ buffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
pr_debug("buffer = %p, length = %d\n", buffer, sg->length);
for (index = 0; index < (sg->length / 4); index++)
@@ -292,7 +292,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
}
- flush_dcache_page(sg->page);
+ flush_dcache_page(sg_page(sg));
}
/* Is there another transfer to trigger? */
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 92c4d0dfee4..bcbb6d247bf 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -340,7 +340,7 @@ static void au1xmmc_send_pio(struct au1xmmc_host *host)
/* This is the pointer to the data buffer */
sg = &data->sg[host->pio.index];
- sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+ sg_ptr = sg_virt(sg) + host->pio.offset;
/* This is the space left inside the buffer */
sg_len = data->sg[host->pio.index].length - host->pio.offset;
@@ -400,7 +400,7 @@ static void au1xmmc_receive_pio(struct au1xmmc_host *host)
if (host->pio.index < host->dma.len) {
sg = &data->sg[host->pio.index];
- sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset;
+ sg_ptr = sg_virt(sg) + host->pio.offset;
/* This is the space left inside the buffer */
sg_len = sg_dma_len(&data->sg[host->pio.index]) - host->pio.offset;
@@ -613,14 +613,11 @@ au1xmmc_prepare_data(struct au1xmmc_host *host, struct mmc_data *data)
if (host->flags & HOST_F_XMIT){
ret = au1xxx_dbdma_put_source_flags(channel,
- (void *) (page_address(sg->page) +
- sg->offset),
- len, flags);
+ (void *) sg_virt(sg), len, flags);
}
else {
ret = au1xxx_dbdma_put_dest_flags(channel,
- (void *) (page_address(sg->page) +
- sg->offset),
+ (void *) sg_virt(sg),
len, flags);
}
diff --git a/drivers/mmc/host/imxmmc.c b/drivers/mmc/host/imxmmc.c
index 6ebc41e7592..fc72e1fadb6 100644
--- a/drivers/mmc/host/imxmmc.c
+++ b/drivers/mmc/host/imxmmc.c
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
}
/* Convert back to virtual address */
- host->data_ptr = (u16*)(page_address(data->sg->page) + data->sg->offset);
+ host->data_ptr = (u16*)sg_virt(sg);
host->data_cnt = 0;
clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 7ae18eaed6c..12c2d807c14 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -813,7 +813,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
&& dir == DMA_FROM_DEVICE)
dir = DMA_BIDIRECTIONAL;
- dma_addr = dma_map_page(dma_dev, sg->page, 0,
+ dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
PAGE_SIZE, dir);
if (direction == DMA_TO_DEVICE)
t->tx_dma = dma_addr + sg->offset;
@@ -822,7 +822,7 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
}
/* allow pio too; we don't allow highmem */
- kmap_addr = kmap(sg->page);
+ kmap_addr = kmap(sg_page(sg));
if (direction == DMA_TO_DEVICE)
t->tx_buf = kmap_addr + sg->offset;
else
@@ -855,8 +855,8 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd,
/* discard mappings */
if (direction == DMA_FROM_DEVICE)
- flush_kernel_dcache_page(sg->page);
- kunmap(sg->page);
+ flush_kernel_dcache_page(sg_page(sg));
+ kunmap(sg_page(sg));
if (dma_dev)
dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 60a67dfcda6..971e18b91f4 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -24,10 +24,10 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/clk.h>
+#include <linux/scatterlist.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/scatterlist.h>
#include <asm/mach-types.h>
#include <asm/arch/board.h>
@@ -383,7 +383,7 @@ mmc_omap_sg_to_buf(struct mmc_omap_host *host)
sg = host->data->sg + host->sg_idx;
host->buffer_bytes_left = sg->length;
- host->buffer = page_address(sg->page) + sg->offset;
+ host->buffer = sg_virt(sg);
if (host->buffer_bytes_left > host->total_bytes_left)
host->buffer_bytes_left = host->total_bytes_left;
}
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index b397121b947..0db837e44b7 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -231,7 +231,7 @@ static void sdhci_deactivate_led(struct sdhci_host *host)
static inline char* sdhci_sg_to_buffer(struct sdhci_host* host)
{
- return page_address(host->cur_sg->page) + host->cur_sg->offset;
+ return sg_virt(host->cur_sg);
}
static inline int sdhci_next_sg(struct sdhci_host* host)
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index 9b904795eb7..c11a3d25605 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -192,7 +192,7 @@ static void tifm_sd_transfer_data(struct tifm_sd *host)
}
off = sg[host->sg_pos].offset + host->block_pos;
- pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+ pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
p_off = offset_in_page(off);
p_cnt = PAGE_SIZE - p_off;
p_cnt = min(p_cnt, cnt);
@@ -241,18 +241,18 @@ static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
}
off = sg[host->sg_pos].offset + host->block_pos;
- pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
+ pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
p_off = offset_in_page(off);
p_cnt = PAGE_SIZE - p_off;
p_cnt = min(p_cnt, cnt);
p_cnt = min(p_cnt, t_size);
if (r_data->flags & MMC_DATA_WRITE)
- tifm_sd_copy_page(host->bounce_buf.page,
+ tifm_sd_copy_page(sg_page(&host->bounce_buf),
r_data->blksz - t_size,
pg, p_off, p_cnt);
else if (r_data->flags & MMC_DATA_READ)
- tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
+ tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
r_data->blksz - t_size, p_cnt);
t_size -= p_cnt;
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c
index 80db11c05f2..fa4c8c53cc7 100644
--- a/drivers/mmc/host/wbsd.c
+++ b/drivers/mmc/host/wbsd.c
@@ -269,7 +269,7 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
{
- return page_address(host->cur_sg->page) + host->cur_sg->offset;
+ return sg_virt(host->cur_sg);
}
static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -283,7 +283,7 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
len = data->sg_len;
for (i = 0; i < len; i++) {
- sgbuf = page_address(sg[i].page) + sg[i].offset;
+ sgbuf = sg_virt(&sg[i]);
memcpy(dmabuf, sgbuf, sg[i].length);
dmabuf += sg[i].length;
}
@@ -300,7 +300,7 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
len = data->sg_len;
for (i = 0; i < len; i++) {
- sgbuf = page_address(sg[i].page) + sg[i].offset;
+ sgbuf = sg_virt(&sg[i]);
memcpy(sgbuf, dmabuf, sg[i].length);
dmabuf += sg[i].length;
}
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 2a2a125b0c7..a592fc04cf7 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -54,7 +54,7 @@ config MTD_PHYSMAP_BANKWIDTH
help
This is the total width of the data bus of the flash devices
in octets. For example, if you have a data bus width of 32
- bits, you would set the bus width octect value to 4. This is
+ bits, you would set the bus width octet value to 4. This is
used internally by the CFI drivers.
Ignore this option if you use run-time physmap configuration
(i.e., run-time calling physmap_configure()).
@@ -73,12 +73,12 @@ config MTD_PMC_MSP_EVM
depends on PMC_MSP && MTD_CFI
select MTD_PARTITIONS
help
- This provides a 'mapping' driver which support the way
- in which user-programmable flash chips are connected on the
- PMC-Sierra MSP eval/demo boards
+ This provides a 'mapping' driver which supports the way
+ in which user-programmable flash chips are connected on the
+ PMC-Sierra MSP eval/demo boards.
choice
- prompt "Maximum mappable memory avialable for flash IO"
+ prompt "Maximum mappable memory available for flash IO"
depends on MTD_PMC_MSP_EVM
default MSP_FLASH_MAP_LIMIT_32M
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
index a4f1bf33164..6330c8cc72b 100644
--- a/drivers/mtd/ubi/wl.c
+++ b/drivers/mtd/ubi/wl.c
@@ -1309,7 +1309,7 @@ static int ubi_thread(void *u)
struct ubi_device *ubi = u;
ubi_msg("background thread \"%s\" started, PID %d",
- ubi->bgt_name, current->pid);
+ ubi->bgt_name, task_pid_nr(current));
set_freezable();
for (;;) {
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 973b684c11e..eef6fecfff2 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -73,7 +73,7 @@
Jean-Jacques Michel - bug fix
- Tobias Ringstrm - Rx interrupt status checking suggestion
+ Tobias Ringström - Rx interrupt status checking suggestion
Andrew Morton - Clear blocked signals, avoid
buffer overrun setting current->comm.
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 83d52c8acab..ce34b539bf3 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -855,7 +855,7 @@ config BFIN_MAC_USE_L1
depends on BFIN_MAC && BF537
default y
help
- To get maximum network performace, you should use L1 memory as rx/tx buffers.
+ To get maximum network performance, you should use L1 memory as rx/tx buffers.
Say N here if you want to reserve L1 memory for other uses.
config BFIN_TX_DESC_NUM
@@ -1293,9 +1293,6 @@ config PCNET32_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config AMD8111_ETH
@@ -1313,7 +1310,7 @@ config AMD8111_ETH
will be called amd8111e.
config AMD8111E_NAPI
- bool "Enable NAPI support"
+ bool "Use RX polling (NAPI)"
depends on AMD8111_ETH
help
NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1324,9 +1321,6 @@ config AMD8111E_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config ADAPTEC_STARFIRE
@@ -1355,9 +1349,6 @@ config ADAPTEC_STARFIRE_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config AC3200
@@ -1431,7 +1422,7 @@ config FORCEDETH
called forcedeth.
config FORCEDETH_NAPI
- bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+ bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
depends on FORCEDETH && EXPERIMENTAL
help
NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -1442,9 +1433,6 @@ config FORCEDETH_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config CS89x0
@@ -1756,9 +1744,6 @@ config VIA_RHINE_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
config LAN_SAA9730
bool "Philips SAA9730 Ethernet support"
depends on NET_PCI && PCI && MIPS_ATLAS
@@ -2003,9 +1988,6 @@ config E1000_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config E1000_DISABLE_PACKET_SPLIT
@@ -2099,7 +2081,7 @@ config R8169
will be called r8169. This is recommended.
config R8169_NAPI
- bool "Use Rx and Tx Polling (NAPI) (EXPERIMENTAL)"
+ bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
depends on R8169 && EXPERIMENTAL
help
NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -2110,9 +2092,6 @@ config R8169_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config R8169_VLAN
@@ -2364,7 +2343,7 @@ config GIANFAR
and MPC86xx family of chips, and the FEC on the 8540.
config GFAR_NAPI
- bool "NAPI Support"
+ bool "Use Rx Polling (NAPI)"
depends on GIANFAR
config UCC_GETH
@@ -2376,7 +2355,7 @@ config UCC_GETH
which is available on some Freescale SOCs.
config UGETH_NAPI
- bool "NAPI Support"
+ bool "Use Rx Polling (NAPI)"
depends on UCC_GETH
config UGETH_MAGIC_PACKET
@@ -2494,7 +2473,7 @@ config CHELSIO_T3
config EHEA
tristate "eHEA Ethernet support"
- depends on IBMEBUS
+ depends on IBMEBUS && INET
select INET_LRO
---help---
This driver supports the IBM pSeries eHEA ethernet adapter.
@@ -2559,9 +2538,6 @@ config IXGB_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config S2IO
@@ -2584,14 +2560,11 @@ config S2IO_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config MYRI10GE
tristate "Myricom Myri-10G Ethernet support"
- depends on PCI
+ depends on PCI && INET
select FW_LOADER
select CRC32
select INET_LRO
diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c
index 1cc74ec88a5..eebf5bb2b03 100644
--- a/drivers/net/amd8111e.c
+++ b/drivers/net/amd8111e.c
@@ -1111,7 +1111,7 @@ static struct net_device_stats *amd8111e_get_stats(struct net_device * dev)
return new_stats;
}
-/* This function recalculate the interupt coalescing mode on every interrupt
+/* This function recalculate the interrupt coalescing mode on every interrupt
according to the datarate and the packet rate.
*/
static int amd8111e_calc_coalesce(struct net_device *dev)
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 3fa3bccd1ad..10f3a196be3 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -1,7 +1,7 @@
/*
* Amiga Linux/m68k Ariadne Ethernet Driver
*
- * Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
+ * © Copyright 1995-2003 by Geert Uytterhoeven (geert@linux-m68k.org)
* Peter De Schrijver (p2@mind.be)
*
* ---------------------------------------------------------------------------
diff --git a/drivers/net/ariadne.h b/drivers/net/ariadne.h
index f7913d5a39f..bb613f292e0 100644
--- a/drivers/net/ariadne.h
+++ b/drivers/net/ariadne.h
@@ -1,7 +1,7 @@
/*
* Amiga Linux/m68k Ariadne Ethernet Driver
*
- * Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
+ * © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
* Peter De Schrijver
* (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
*
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 185f98e3964..504b7ce2747 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -542,7 +542,7 @@ static struct {
static int num_ifs;
/*
- * Setup the base address and interupt of the Au1xxx ethernet macs
+ * Setup the base address and interrupt of the Au1xxx ethernet macs
* based on cpu type and whether the interface is enabled in sys_pinfunc
* register. The last interface is enabled if SYS_PF_NI2 (bit 4) is 0.
*/
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 96cee4badd2..da767d3d5af 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -26,7 +26,7 @@
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/dma-mapping.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <linux/delay.h>
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 7a045a37056..084f0292ea6 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -126,7 +126,7 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator);
// ================= main 802.3ad protocol functions ==================
static int ad_lacpdu_send(struct port *port);
-static int ad_marker_send(struct port *port, struct marker *marker);
+static int ad_marker_send(struct port *port, struct bond_marker *marker);
static void ad_mux_machine(struct port *port);
static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port);
static void ad_tx_machine(struct port *port);
@@ -139,8 +139,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast);
static void ad_initialize_lacpdu(struct lacpdu *Lacpdu);
static void ad_enable_collecting_distributing(struct port *port);
static void ad_disable_collecting_distributing(struct port *port);
-static void ad_marker_info_received(struct marker *marker_info, struct port *port);
-static void ad_marker_response_received(struct marker *marker, struct port *port);
+static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port);
+static void ad_marker_response_received(struct bond_marker *marker, struct port *port);
/////////////////////////////////////////////////////////////////////////////////
@@ -889,12 +889,12 @@ static int ad_lacpdu_send(struct port *port)
* Returns: 0 on success
* < 0 on error
*/
-static int ad_marker_send(struct port *port, struct marker *marker)
+static int ad_marker_send(struct port *port, struct bond_marker *marker)
{
struct slave *slave = port->slave;
struct sk_buff *skb;
- struct marker_header *marker_header;
- int length = sizeof(struct marker_header);
+ struct bond_marker_header *marker_header;
+ int length = sizeof(struct bond_marker_header);
struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR;
skb = dev_alloc_skb(length + 16);
@@ -909,7 +909,7 @@ static int ad_marker_send(struct port *port, struct marker *marker)
skb->network_header = skb->mac_header + ETH_HLEN;
skb->protocol = PKT_TYPE_LACPDU;
- marker_header = (struct marker_header *)skb_put(skb, length);
+ marker_header = (struct bond_marker_header *)skb_put(skb, length);
marker_header->ad_header.destination_address = lacpdu_multicast_address;
/* Note: source addres is set to be the member's PERMANENT address, because we use it
@@ -1709,7 +1709,7 @@ static void ad_disable_collecting_distributing(struct port *port)
*/
static void ad_marker_info_send(struct port *port)
{
- struct marker marker;
+ struct bond_marker marker;
u16 index;
// fill the marker PDU with the appropriate values
@@ -1742,13 +1742,14 @@ static void ad_marker_info_send(struct port *port)
* @port: the port we're looking at
*
*/
-static void ad_marker_info_received(struct marker *marker_info,struct port *port)
+static void ad_marker_info_received(struct bond_marker *marker_info,
+ struct port *port)
{
- struct marker marker;
+ struct bond_marker marker;
// copy the received marker data to the response marker
//marker = *marker_info;
- memcpy(&marker, marker_info, sizeof(struct marker));
+ memcpy(&marker, marker_info, sizeof(struct bond_marker));
// change the marker subtype to marker response
marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE;
// send the marker response
@@ -1767,7 +1768,8 @@ static void ad_marker_info_received(struct marker *marker_info,struct port *port
* response for marker PDU's, in this stage, but only to respond to marker
* information.
*/
-static void ad_marker_response_received(struct marker *marker, struct port *port)
+static void ad_marker_response_received(struct bond_marker *marker,
+ struct port *port)
{
marker=NULL; // just to satisfy the compiler
port=NULL; // just to satisfy the compiler
@@ -2164,15 +2166,15 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u
case AD_TYPE_MARKER:
// No need to convert fields to Little Endian since we don't use the marker's fields.
- switch (((struct marker *)lacpdu)->tlv_type) {
+ switch (((struct bond_marker *)lacpdu)->tlv_type) {
case AD_MARKER_INFORMATION_SUBTYPE:
dprintk("Received Marker Information on port %d\n", port->actor_port_number);
- ad_marker_info_received((struct marker *)lacpdu, port);
+ ad_marker_info_received((struct bond_marker *)lacpdu, port);
break;
case AD_MARKER_RESPONSE_SUBTYPE:
dprintk("Received Marker Response on port %d\n", port->actor_port_number);
- ad_marker_response_received((struct marker *)lacpdu, port);
+ ad_marker_response_received((struct bond_marker *)lacpdu, port);
break;
default:
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index 862952fa6fd..f1655726494 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -92,7 +92,7 @@ typedef enum {
typedef enum {
AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype
AD_MARKER_RESPONSE_SUBTYPE // marker response subtype
-} marker_subtype_t;
+} bond_marker_subtype_t;
// timers types(43.4.9 in the 802.3ad standard)
typedef enum {
@@ -148,7 +148,7 @@ typedef struct lacpdu_header {
} lacpdu_header_t;
// Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard)
-typedef struct marker {
+typedef struct bond_marker {
u8 subtype; // = 0x02 (marker PDU)
u8 version_number; // = 0x01
u8 tlv_type; // = 0x01 (marker information)
@@ -161,12 +161,12 @@ typedef struct marker {
u8 tlv_type_terminator; // = 0x00
u8 terminator_length; // = 0x00
u8 reserved_90[90]; // = 0
-} marker_t;
+} bond_marker_t;
-typedef struct marker_header {
+typedef struct bond_marker_header {
struct ad_header ad_header;
- struct marker marker;
-} marker_header_t;
+ struct bond_marker marker;
+} bond_marker_header_t;
#pragma pack()
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 80c0c8c415e..855dc10ffa1 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -55,7 +55,7 @@ static int expected_refcount = -1;
static struct class *netdev_class;
/*--------------------------- Data Structures -----------------------------*/
-/* Bonding sysfs lock. Why can't we just use the subsytem lock?
+/* Bonding sysfs lock. Why can't we just use the subsystem lock?
* Because kobject_register tries to acquire the subsystem lock. If
* we already hold the lock (which we would if the user was creating
* a new bond through the sysfs interface), we deadlock.
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index ed53aaab4c0..ae419736158 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -471,7 +471,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
len = max(skb->len, ETH_ZLEN);
- queue = skb->queue_mapping;
+ queue = skb_get_queue_mapping(skb);
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(dev, queue);
#else
diff --git a/drivers/net/cris/eth_v10.c b/drivers/net/cris/eth_v10.c
index 314b2f68f78..edd6828f0a7 100644
--- a/drivers/net/cris/eth_v10.c
+++ b/drivers/net/cris/eth_v10.c
@@ -234,6 +234,7 @@
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/bitops.h>
#include <linux/if.h>
#include <linux/mii.h>
@@ -247,7 +248,6 @@
#include <asm/irq.h>
#include <asm/dma.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/ethernet.h>
#include <asm/cache.h>
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 04426170338..2a3df145850 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -41,9 +41,9 @@
#include <linux/timer.h>
#include <linux/cache.h>
#include <linux/mutex.h>
+#include <linux/bitops.h>
#include "t3cdev.h"
#include <asm/semaphore.h>
-#include <asm/bitops.h>
#include <asm/io.h>
typedef irqreturn_t(*intr_handler_t) (int, void *);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 27ac010900a..3286d2a0a87 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -542,7 +542,8 @@ dm9000_probe(struct platform_device *pdev)
if (id_val != DM9000_ID) {
printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
- goto release;
+ ret = -ENODEV;
+ goto out;
}
/* from this point we assume that we have found a DM9000 */
@@ -602,8 +603,7 @@ dm9000_probe(struct platform_device *pdev)
}
return 0;
- release:
- out:
+out:
printk("%s: not found (%d).\n", CARDNAME, ret);
dm9000_release_board(pdev, db);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 64f35e20fd4..3dbaec680b4 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1324,7 +1324,7 @@ static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb,
if (!--counter) break;
}
- /* ack any interupts, something could have been set */
+ /* ack any interrupts, something could have been set */
iowrite8(~0, &nic->csr->scb.stat_ack);
/* if the command failed, or is not OK, notify and return */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 047263830e6..f1ce348470c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3590,7 +3590,7 @@ e1000_update_stats(struct e1000_adapter *adapter)
spin_lock_irqsave(&adapter->stats_lock, flags);
- /* these counters are modified from e1000_adjust_tbi_stats,
+ /* these counters are modified from e1000_tbi_adjust_stats,
* called from the interrupt context, so they must only
* be written while holding adapter->stats_lock
*/
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index 243fc6b354b..e3dd8b13690 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -170,7 +170,6 @@ static char *version =
/* Few macros */
-#define BIT(a) ( (1 << (a)) )
#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index 43f7647ff24..7bb9c728a1d 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -111,7 +111,6 @@ MODULE_AUTHOR("Myson or whoever");
MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
MODULE_LICENSE("GPL");
module_param(max_interrupt_work, int, 0);
-//MODULE_PARM(min_pci_latency, "i");
module_param(debug, int, 0);
module_param(rx_copybreak, int, 0);
module_param(multicast_filter_limit, int, 0);
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index ad9e327c3b0..e0119f6a331 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -3,7 +3,7 @@
* devices like TTY. It interfaces between a raw TTY and the
* kernel's AX.25 protocol layers.
*
- * Authors: Andreas Knsgen <ajk@iehk.rwth-aachen.de>
+ * Authors: Andreas Könsgen <ajk@iehk.rwth-aachen.de>
* Ralf Baechle DL5RB <ralf@linux-mips.org>
*
* Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index 36d2c7d4f4d..62d5d5cfd6a 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -64,7 +64,7 @@ config DMASCC
dmascc. If you don't pass any parameter to the driver, all
possible I/O addresses are probed. This could irritate other devices
that are currently not in use. You may specify the list of addresses
- to be probed by "dmascc=addr1,addr2,..." (when compiled into the
+ to be probed by "dmascc.io=addr1,addr2,..." (when compiled into the
kernel image) or "io=addr1,addr2,..." (when loaded as a module). The
network interfaces will be called dmascc0 and dmascc1 for the board
detected first, dmascc2 and dmascc3 for the second one, and so on.
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index bc02e469480..11b83dae00a 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -21,6 +21,7 @@
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
@@ -35,7 +36,6 @@
#include <linux/sockios.h>
#include <linux/workqueue.h>
#include <asm/atomic.h>
-#include <asm/bitops.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/irq.h>
diff --git a/drivers/net/irda/actisys-sir.c b/drivers/net/irda/actisys-sir.c
index ccf6ec548a6..736d2473b7e 100644
--- a/drivers/net/irda/actisys-sir.c
+++ b/drivers/net/irda/actisys-sir.c
@@ -21,7 +21,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/actisys.c b/drivers/net/irda/actisys.c
index b2e31f4a384..ae0b80a5680 100644
--- a/drivers/net/irda/actisys.c
+++ b/drivers/net/irda/actisys.c
@@ -19,7 +19,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index a82d8f98383..1257e1a7e81 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -595,7 +595,7 @@ toshoboe_startchip (struct toshoboe_cb *self)
OUTB ((physaddr >> 18) & 0xff, OBOE_RING_BASE1);
OUTB ((physaddr >> 26) & 0x3f, OBOE_RING_BASE2);
- /*Enable DMA controler in byte mode and RX */
+ /*Enable DMA controller in byte mode and RX */
OUTB (CONFIG0H_DMA_ON, OBOE_CONFIG0H);
/* Start up the clocks */
diff --git a/drivers/net/irda/girbil-sir.c b/drivers/net/irda/girbil-sir.c
index 0d2fe87fb9b..738531b16bd 100644
--- a/drivers/net/irda/girbil-sir.c
+++ b/drivers/net/irda/girbil-sir.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/girbil.c b/drivers/net/irda/girbil.c
index 248aeb0c726..1f57391a618 100644
--- a/drivers/net/irda/girbil.c
+++ b/drivers/net/irda/girbil.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/irport.h b/drivers/net/irda/irport.h
index 3f46b84c6c8..66fc2433e97 100644
--- a/drivers/net/irda/irport.h
+++ b/drivers/net/irda/irport.h
@@ -17,7 +17,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
index 6f5f697ec9f..2c6f7be36e8 100644
--- a/drivers/net/irda/irtty-sir.c
+++ b/drivers/net/irda/irtty-sir.c
@@ -20,7 +20,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c
index 12b9378c587..a873d2b315c 100644
--- a/drivers/net/irda/nsc-ircc.c
+++ b/drivers/net/irda/nsc-ircc.c
@@ -20,7 +20,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/nsc-ircc.h b/drivers/net/irda/nsc-ircc.h
index dacf671abcd..bbdc97ff83c 100644
--- a/drivers/net/irda/nsc-ircc.h
+++ b/drivers/net/irda/nsc-ircc.h
@@ -19,7 +19,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/tekram-sir.c b/drivers/net/irda/tekram-sir.c
index 0dd6bc7af3f..d1ce5ae6a17 100644
--- a/drivers/net/irda/tekram-sir.c
+++ b/drivers/net/irda/tekram-sir.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/tekram.c b/drivers/net/irda/tekram.c
index 8f6258221cb..9bfd2441adb 100644
--- a/drivers/net/irda/tekram.c
+++ b/drivers/net/irda/tekram.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/irda/w83977af_ir.h b/drivers/net/irda/w83977af_ir.h
index 0b7661deafe..87c3975baf6 100644
--- a/drivers/net/irda/w83977af_ir.h
+++ b/drivers/net/irda/w83977af_ir.h
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/drivers/net/mac89x0.c b/drivers/net/mac89x0.c
index 30854f09496..a19b5958cee 100644
--- a/drivers/net/mac89x0.c
+++ b/drivers/net/mac89x0.c
@@ -99,9 +99,9 @@ static char *version =
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
+#include <linux/bitops.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/hwtest.h>
#include <asm/macints.h>
diff --git a/drivers/net/meth.h b/drivers/net/meth.h
index ea3b8fc86d1..a78dc1ca8c2 100644
--- a/drivers/net/meth.h
+++ b/drivers/net/meth.h
@@ -28,9 +28,6 @@
#define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */
#define RX_BUCKET_SIZE 256
-#undef BIT
-#define BIT(x) (1UL << (x))
-
/* For more detailed explanations of what each field menas,
see Nick's great comments to #defines below (or docs, if
you are lucky enough toget hold of them :)*/
diff --git a/drivers/net/mlx4/icm.c b/drivers/net/mlx4/icm.c
index 4b3c109d5ea..887633b207d 100644
--- a/drivers/net/mlx4/icm.c
+++ b/drivers/net/mlx4/icm.c
@@ -60,7 +60,7 @@ static void mlx4_free_icm_pages(struct mlx4_dev *dev, struct mlx4_icm_chunk *chu
PCI_DMA_BIDIRECTIONAL);
for (i = 0; i < chunk->npages; ++i)
- __free_pages(chunk->mem[i].page,
+ __free_pages(sg_page(&chunk->mem[i]),
get_order(chunk->mem[i].length));
}
@@ -70,7 +70,7 @@ static void mlx4_free_icm_coherent(struct mlx4_dev *dev, struct mlx4_icm_chunk *
for (i = 0; i < chunk->npages; ++i)
dma_free_coherent(&dev->pdev->dev, chunk->mem[i].length,
- lowmem_page_address(chunk->mem[i].page),
+ lowmem_page_address(sg_page(&chunk->mem[i])),
sg_dma_address(&chunk->mem[i]));
}
@@ -95,10 +95,13 @@ void mlx4_free_icm(struct mlx4_dev *dev, struct mlx4_icm *icm, int coherent)
static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_mask)
{
- mem->page = alloc_pages(gfp_mask, order);
- if (!mem->page)
+ struct page *page;
+
+ page = alloc_pages(gfp_mask, order);
+ if (!page)
return -ENOMEM;
+ sg_set_page(mem, page);
mem->length = PAGE_SIZE << order;
mem->offset = 0;
return 0;
@@ -145,6 +148,7 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages,
if (!chunk)
goto fail;
+ sg_init_table(chunk->mem, MLX4_ICM_CHUNK_LEN);
chunk->npages = 0;
chunk->nsg = 0;
list_add_tail(&chunk->list, &icm->chunk_list);
@@ -334,7 +338,7 @@ void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_han
* been assigned to.
*/
if (chunk->mem[i].length > offset) {
- page = chunk->mem[i].page;
+ page = sg_page(&chunk->mem[i]);
goto out;
}
offset -= chunk->mem[i].length;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 50e1ec67ef9..953117152bb 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -996,7 +996,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
made udelay() unreliable.
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
- depricated.
+ deprecated.
*/
#define eeprom_delay(ee_addr) readl(ee_addr)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index ed1f9bbb2a3..112ab079ce7 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -3103,31 +3103,12 @@ static int niu_alloc_tx_ring_info(struct niu *np,
static void niu_size_rbr(struct niu *np, struct rx_ring_info *rp)
{
- u16 bs;
+ u16 bss;
- switch (PAGE_SIZE) {
- case 4 * 1024:
- case 8 * 1024:
- case 16 * 1024:
- case 32 * 1024:
- rp->rbr_block_size = PAGE_SIZE;
- rp->rbr_blocks_per_page = 1;
- break;
+ bss = min(PAGE_SHIFT, 15);
- default:
- if (PAGE_SIZE % (32 * 1024) == 0)
- bs = 32 * 1024;
- else if (PAGE_SIZE % (16 * 1024) == 0)
- bs = 16 * 1024;
- else if (PAGE_SIZE % (8 * 1024) == 0)
- bs = 8 * 1024;
- else if (PAGE_SIZE % (4 * 1024) == 0)
- bs = 4 * 1024;
- else
- BUG();
- rp->rbr_block_size = bs;
- rp->rbr_blocks_per_page = PAGE_SIZE / bs;
- }
+ rp->rbr_block_size = 1 << bss;
+ rp->rbr_blocks_per_page = 1 << (PAGE_SHIFT-bss);
rp->rbr_sizes[0] = 256;
rp->rbr_sizes[1] = 1024;
@@ -7902,12 +7883,7 @@ static int __init niu_init(void)
{
int err = 0;
- BUILD_BUG_ON((PAGE_SIZE < 4 * 1024) ||
- ((PAGE_SIZE > 32 * 1024) &&
- ((PAGE_SIZE % (32 * 1024)) != 0 &&
- (PAGE_SIZE % (16 * 1024)) != 0 &&
- (PAGE_SIZE % (8 * 1024)) != 0 &&
- (PAGE_SIZE % (4 * 1024)) != 0)));
+ BUILD_BUG_ON(PAGE_SIZE < 4 * 1024);
niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
index 8cd243d92af..2747b1f89ff 100644
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -185,3 +185,5 @@ void free_mdio_bitbang(struct mii_bus *bus)
module_put(ctrl->ops->owner);
kfree(bus);
}
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index c0b6d19d145..bcb0885011c 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -55,7 +55,7 @@
#include <linux/mm.h>
#include <linux/ppp_defs.h>
#include <linux/ppp-comp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
#include "ppp_mppe.h"
@@ -68,9 +68,7 @@ MODULE_VERSION("1.0.2");
static unsigned int
setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
{
- sg[0].page = virt_to_page(address);
- sg[0].offset = offset_in_page(address);
- sg[0].length = length;
+ sg_init_one(sg, address, length);
return length;
}
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index aef66e2d98d..01f08d726ac 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -20,17 +20,17 @@ struct XENA_dev_config {
/* General Control-Status Registers */
u64 general_int_status;
-#define GEN_INTR_TXPIC BIT(0)
-#define GEN_INTR_TXDMA BIT(1)
-#define GEN_INTR_TXMAC BIT(2)
-#define GEN_INTR_TXXGXS BIT(3)
-#define GEN_INTR_TXTRAFFIC BIT(8)
-#define GEN_INTR_RXPIC BIT(32)
-#define GEN_INTR_RXDMA BIT(33)
-#define GEN_INTR_RXMAC BIT(34)
-#define GEN_INTR_MC BIT(35)
-#define GEN_INTR_RXXGXS BIT(36)
-#define GEN_INTR_RXTRAFFIC BIT(40)
+#define GEN_INTR_TXPIC s2BIT(0)
+#define GEN_INTR_TXDMA s2BIT(1)
+#define GEN_INTR_TXMAC s2BIT(2)
+#define GEN_INTR_TXXGXS s2BIT(3)
+#define GEN_INTR_TXTRAFFIC s2BIT(8)
+#define GEN_INTR_RXPIC s2BIT(32)
+#define GEN_INTR_RXDMA s2BIT(33)
+#define GEN_INTR_RXMAC s2BIT(34)
+#define GEN_INTR_MC s2BIT(35)
+#define GEN_INTR_RXXGXS s2BIT(36)
+#define GEN_INTR_RXTRAFFIC s2BIT(40)
#define GEN_ERROR_INTR GEN_INTR_TXPIC | GEN_INTR_RXPIC | \
GEN_INTR_TXDMA | GEN_INTR_RXDMA | \
GEN_INTR_TXMAC | GEN_INTR_RXMAC | \
@@ -54,36 +54,36 @@ struct XENA_dev_config {
u64 adapter_status;
-#define ADAPTER_STATUS_TDMA_READY BIT(0)
-#define ADAPTER_STATUS_RDMA_READY BIT(1)
-#define ADAPTER_STATUS_PFC_READY BIT(2)
-#define ADAPTER_STATUS_TMAC_BUF_EMPTY BIT(3)
-#define ADAPTER_STATUS_PIC_QUIESCENT BIT(5)
-#define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6)
-#define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7)
+#define ADAPTER_STATUS_TDMA_READY s2BIT(0)
+#define ADAPTER_STATUS_RDMA_READY s2BIT(1)
+#define ADAPTER_STATUS_PFC_READY s2BIT(2)
+#define ADAPTER_STATUS_TMAC_BUF_EMPTY s2BIT(3)
+#define ADAPTER_STATUS_PIC_QUIESCENT s2BIT(5)
+#define ADAPTER_STATUS_RMAC_REMOTE_FAULT s2BIT(6)
+#define ADAPTER_STATUS_RMAC_LOCAL_FAULT s2BIT(7)
#define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8)
#define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE vBIT(0x0F,8,8)
#define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8)
-#define ADAPTER_STATUS_MC_DRAM_READY BIT(24)
-#define ADAPTER_STATUS_MC_QUEUES_READY BIT(25)
-#define ADAPTER_STATUS_M_PLL_LOCK BIT(30)
-#define ADAPTER_STATUS_P_PLL_LOCK BIT(31)
+#define ADAPTER_STATUS_MC_DRAM_READY s2BIT(24)
+#define ADAPTER_STATUS_MC_QUEUES_READY s2BIT(25)
+#define ADAPTER_STATUS_M_PLL_LOCK s2BIT(30)
+#define ADAPTER_STATUS_P_PLL_LOCK s2BIT(31)
u64 adapter_control;
-#define ADAPTER_CNTL_EN BIT(7)
-#define ADAPTER_EOI_TX_ON BIT(15)
-#define ADAPTER_LED_ON BIT(23)
+#define ADAPTER_CNTL_EN s2BIT(7)
+#define ADAPTER_EOI_TX_ON s2BIT(15)
+#define ADAPTER_LED_ON s2BIT(23)
#define ADAPTER_UDPI(val) vBIT(val,36,4)
-#define ADAPTER_WAIT_INT BIT(48)
-#define ADAPTER_ECC_EN BIT(55)
+#define ADAPTER_WAIT_INT s2BIT(48)
+#define ADAPTER_ECC_EN s2BIT(55)
u64 serr_source;
-#define SERR_SOURCE_PIC BIT(0)
-#define SERR_SOURCE_TXDMA BIT(1)
-#define SERR_SOURCE_RXDMA BIT(2)
-#define SERR_SOURCE_MAC BIT(3)
-#define SERR_SOURCE_MC BIT(4)
-#define SERR_SOURCE_XGXS BIT(5)
+#define SERR_SOURCE_PIC s2BIT(0)
+#define SERR_SOURCE_TXDMA s2BIT(1)
+#define SERR_SOURCE_RXDMA s2BIT(2)
+#define SERR_SOURCE_MAC s2BIT(3)
+#define SERR_SOURCE_MC s2BIT(4)
+#define SERR_SOURCE_XGXS s2BIT(5)
#define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \
SERR_SOURCE_TXDMA | \
SERR_SOURCE_RXDMA | \
@@ -101,41 +101,41 @@ struct XENA_dev_config {
#define PCI_MODE_PCIX_M2_66 0x5
#define PCI_MODE_PCIX_M2_100 0x6
#define PCI_MODE_PCIX_M2_133 0x7
-#define PCI_MODE_UNSUPPORTED BIT(0)
-#define PCI_MODE_32_BITS BIT(8)
-#define PCI_MODE_UNKNOWN_MODE BIT(9)
+#define PCI_MODE_UNSUPPORTED s2BIT(0)
+#define PCI_MODE_32_BITS s2BIT(8)
+#define PCI_MODE_UNKNOWN_MODE s2BIT(9)
u8 unused_0[0x800 - 0x128];
/* PCI-X Controller registers */
u64 pic_int_status;
u64 pic_int_mask;
-#define PIC_INT_TX BIT(0)
-#define PIC_INT_FLSH BIT(1)
-#define PIC_INT_MDIO BIT(2)
-#define PIC_INT_IIC BIT(3)
-#define PIC_INT_GPIO BIT(4)
-#define PIC_INT_RX BIT(32)
+#define PIC_INT_TX s2BIT(0)
+#define PIC_INT_FLSH s2BIT(1)
+#define PIC_INT_MDIO s2BIT(2)
+#define PIC_INT_IIC s2BIT(3)
+#define PIC_INT_GPIO s2BIT(4)
+#define PIC_INT_RX s2BIT(32)
u64 txpic_int_reg;
u64 txpic_int_mask;
-#define PCIX_INT_REG_ECC_SG_ERR BIT(0)
-#define PCIX_INT_REG_ECC_DB_ERR BIT(1)
-#define PCIX_INT_REG_FLASHR_R_FSM_ERR BIT(8)
-#define PCIX_INT_REG_FLASHR_W_FSM_ERR BIT(9)
-#define PCIX_INT_REG_INI_TX_FSM_SERR BIT(10)
-#define PCIX_INT_REG_INI_TXO_FSM_ERR BIT(11)
-#define PCIX_INT_REG_TRT_FSM_SERR BIT(13)
-#define PCIX_INT_REG_SRT_FSM_SERR BIT(14)
-#define PCIX_INT_REG_PIFR_FSM_SERR BIT(15)
-#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR BIT(21)
-#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR BIT(23)
-#define PCIX_INT_REG_INI_RX_FSM_SERR BIT(48)
-#define PCIX_INT_REG_RA_RX_FSM_SERR BIT(50)
+#define PCIX_INT_REG_ECC_SG_ERR s2BIT(0)
+#define PCIX_INT_REG_ECC_DB_ERR s2BIT(1)
+#define PCIX_INT_REG_FLASHR_R_FSM_ERR s2BIT(8)
+#define PCIX_INT_REG_FLASHR_W_FSM_ERR s2BIT(9)
+#define PCIX_INT_REG_INI_TX_FSM_SERR s2BIT(10)
+#define PCIX_INT_REG_INI_TXO_FSM_ERR s2BIT(11)
+#define PCIX_INT_REG_TRT_FSM_SERR s2BIT(13)
+#define PCIX_INT_REG_SRT_FSM_SERR s2BIT(14)
+#define PCIX_INT_REG_PIFR_FSM_SERR s2BIT(15)
+#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR s2BIT(21)
+#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR s2BIT(23)
+#define PCIX_INT_REG_INI_RX_FSM_SERR s2BIT(48)
+#define PCIX_INT_REG_RA_RX_FSM_SERR s2BIT(50)
/*
-#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR BIT(52)
-#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR BIT(54)
-#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR BIT(58)
+#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR s2BIT(52)
+#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR s2BIT(54)
+#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR s2BIT(58)
*/
u64 txpic_alarms;
u64 rxpic_int_reg;
@@ -144,92 +144,92 @@ struct XENA_dev_config {
u64 flsh_int_reg;
u64 flsh_int_mask;
-#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR BIT(63)
-#define PIC_FLSH_INT_REG_ERR BIT(62)
+#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR s2BIT(63)
+#define PIC_FLSH_INT_REG_ERR s2BIT(62)
u64 flash_alarms;
u64 mdio_int_reg;
u64 mdio_int_mask;
-#define MDIO_INT_REG_MDIO_BUS_ERR BIT(0)
-#define MDIO_INT_REG_DTX_BUS_ERR BIT(8)
-#define MDIO_INT_REG_LASI BIT(39)
+#define MDIO_INT_REG_MDIO_BUS_ERR s2BIT(0)
+#define MDIO_INT_REG_DTX_BUS_ERR s2BIT(8)
+#define MDIO_INT_REG_LASI s2BIT(39)
u64 mdio_alarms;
u64 iic_int_reg;
u64 iic_int_mask;
-#define IIC_INT_REG_BUS_FSM_ERR BIT(4)
-#define IIC_INT_REG_BIT_FSM_ERR BIT(5)
-#define IIC_INT_REG_CYCLE_FSM_ERR BIT(6)
-#define IIC_INT_REG_REQ_FSM_ERR BIT(7)
-#define IIC_INT_REG_ACK_ERR BIT(8)
+#define IIC_INT_REG_BUS_FSM_ERR s2BIT(4)
+#define IIC_INT_REG_BIT_FSM_ERR s2BIT(5)
+#define IIC_INT_REG_CYCLE_FSM_ERR s2BIT(6)
+#define IIC_INT_REG_REQ_FSM_ERR s2BIT(7)
+#define IIC_INT_REG_ACK_ERR s2BIT(8)
u64 iic_alarms;
u8 unused4[0x08];
u64 gpio_int_reg;
-#define GPIO_INT_REG_DP_ERR_INT BIT(0)
-#define GPIO_INT_REG_LINK_DOWN BIT(1)
-#define GPIO_INT_REG_LINK_UP BIT(2)
+#define GPIO_INT_REG_DP_ERR_INT s2BIT(0)
+#define GPIO_INT_REG_LINK_DOWN s2BIT(1)
+#define GPIO_INT_REG_LINK_UP s2BIT(2)
u64 gpio_int_mask;
-#define GPIO_INT_MASK_LINK_DOWN BIT(1)
-#define GPIO_INT_MASK_LINK_UP BIT(2)
+#define GPIO_INT_MASK_LINK_DOWN s2BIT(1)
+#define GPIO_INT_MASK_LINK_UP s2BIT(2)
u64 gpio_alarms;
u8 unused5[0x38];
u64 tx_traffic_int;
-#define TX_TRAFFIC_INT_n(n) BIT(n)
+#define TX_TRAFFIC_INT_n(n) s2BIT(n)
u64 tx_traffic_mask;
u64 rx_traffic_int;
-#define RX_TRAFFIC_INT_n(n) BIT(n)
+#define RX_TRAFFIC_INT_n(n) s2BIT(n)
u64 rx_traffic_mask;
/* PIC Control registers */
u64 pic_control;
-#define PIC_CNTL_RX_ALARM_MAP_1 BIT(0)
+#define PIC_CNTL_RX_ALARM_MAP_1 s2BIT(0)
#define PIC_CNTL_SHARED_SPLITS(n) vBIT(n,11,5)
u64 swapper_ctrl;
-#define SWAPPER_CTRL_PIF_R_FE BIT(0)
-#define SWAPPER_CTRL_PIF_R_SE BIT(1)
-#define SWAPPER_CTRL_PIF_W_FE BIT(8)
-#define SWAPPER_CTRL_PIF_W_SE BIT(9)
-#define SWAPPER_CTRL_TXP_FE BIT(16)
-#define SWAPPER_CTRL_TXP_SE BIT(17)
-#define SWAPPER_CTRL_TXD_R_FE BIT(18)
-#define SWAPPER_CTRL_TXD_R_SE BIT(19)
-#define SWAPPER_CTRL_TXD_W_FE BIT(20)
-#define SWAPPER_CTRL_TXD_W_SE BIT(21)
-#define SWAPPER_CTRL_TXF_R_FE BIT(22)
-#define SWAPPER_CTRL_TXF_R_SE BIT(23)
-#define SWAPPER_CTRL_RXD_R_FE BIT(32)
-#define SWAPPER_CTRL_RXD_R_SE BIT(33)
-#define SWAPPER_CTRL_RXD_W_FE BIT(34)
-#define SWAPPER_CTRL_RXD_W_SE BIT(35)
-#define SWAPPER_CTRL_RXF_W_FE BIT(36)
-#define SWAPPER_CTRL_RXF_W_SE BIT(37)
-#define SWAPPER_CTRL_XMSI_FE BIT(40)
-#define SWAPPER_CTRL_XMSI_SE BIT(41)
-#define SWAPPER_CTRL_STATS_FE BIT(48)
-#define SWAPPER_CTRL_STATS_SE BIT(49)
+#define SWAPPER_CTRL_PIF_R_FE s2BIT(0)
+#define SWAPPER_CTRL_PIF_R_SE s2BIT(1)
+#define SWAPPER_CTRL_PIF_W_FE s2BIT(8)
+#define SWAPPER_CTRL_PIF_W_SE s2BIT(9)
+#define SWAPPER_CTRL_TXP_FE s2BIT(16)
+#define SWAPPER_CTRL_TXP_SE s2BIT(17)
+#define SWAPPER_CTRL_TXD_R_FE s2BIT(18)
+#define SWAPPER_CTRL_TXD_R_SE s2BIT(19)
+#define SWAPPER_CTRL_TXD_W_FE s2BIT(20)
+#define SWAPPER_CTRL_TXD_W_SE s2BIT(21)
+#define SWAPPER_CTRL_TXF_R_FE s2BIT(22)
+#define SWAPPER_CTRL_TXF_R_SE s2BIT(23)
+#define SWAPPER_CTRL_RXD_R_FE s2BIT(32)
+#define SWAPPER_CTRL_RXD_R_SE s2BIT(33)
+#define SWAPPER_CTRL_RXD_W_FE s2BIT(34)
+#define SWAPPER_CTRL_RXD_W_SE s2BIT(35)
+#define SWAPPER_CTRL_RXF_W_FE s2BIT(36)
+#define SWAPPER_CTRL_RXF_W_SE s2BIT(37)
+#define SWAPPER_CTRL_XMSI_FE s2BIT(40)
+#define SWAPPER_CTRL_XMSI_SE s2BIT(41)
+#define SWAPPER_CTRL_STATS_FE s2BIT(48)
+#define SWAPPER_CTRL_STATS_SE s2BIT(49)
u64 pif_rd_swapper_fb;
#define IF_RD_SWAPPER_FB 0x0123456789ABCDEF
u64 scheduled_int_ctrl;
-#define SCHED_INT_CTRL_TIMER_EN BIT(0)
-#define SCHED_INT_CTRL_ONE_SHOT BIT(1)
+#define SCHED_INT_CTRL_TIMER_EN s2BIT(0)
+#define SCHED_INT_CTRL_ONE_SHOT s2BIT(1)
#define SCHED_INT_CTRL_INT2MSI(val) vBIT(val,10,6)
#define SCHED_INT_PERIOD TBD
u64 txreqtimeout;
#define TXREQTO_VAL(val) vBIT(val,0,32)
-#define TXREQTO_EN BIT(63)
+#define TXREQTO_EN s2BIT(63)
u64 statsreqtimeout;
#define STATREQTO_VAL(n) TBD
-#define STATREQTO_EN BIT(63)
+#define STATREQTO_EN s2BIT(63)
u64 read_retry_delay;
u64 read_retry_acceleration;
@@ -255,10 +255,10 @@ struct XENA_dev_config {
/* Automated statistics collection */
u64 stat_cfg;
-#define STAT_CFG_STAT_EN BIT(0)
-#define STAT_CFG_ONE_SHOT_EN BIT(1)
-#define STAT_CFG_STAT_NS_EN BIT(8)
-#define STAT_CFG_STAT_RO BIT(9)
+#define STAT_CFG_STAT_EN s2BIT(0)
+#define STAT_CFG_ONE_SHOT_EN s2BIT(1)
+#define STAT_CFG_STAT_NS_EN s2BIT(8)
+#define STAT_CFG_STAT_RO s2BIT(9)
#define STAT_TRSF_PER(n) TBD
#define PER_SEC 0x208d5
#define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32)
@@ -290,18 +290,18 @@ struct XENA_dev_config {
#define I2C_CONTROL_DEV_ID(id) vBIT(id,1,3)
#define I2C_CONTROL_ADDR(addr) vBIT(addr,5,11)
#define I2C_CONTROL_BYTE_CNT(cnt) vBIT(cnt,22,2)
-#define I2C_CONTROL_READ BIT(24)
-#define I2C_CONTROL_NACK BIT(25)
+#define I2C_CONTROL_READ s2BIT(24)
+#define I2C_CONTROL_NACK s2BIT(25)
#define I2C_CONTROL_CNTL_START vBIT(0xE,28,4)
#define I2C_CONTROL_CNTL_END(val) (val & vBIT(0x1,28,4))
#define I2C_CONTROL_GET_DATA(val) (u32)(val & 0xFFFFFFFF)
#define I2C_CONTROL_SET_DATA(val) vBIT(val,32,32)
u64 gpio_control;
-#define GPIO_CTRL_GPIO_0 BIT(8)
+#define GPIO_CTRL_GPIO_0 s2BIT(8)
u64 misc_control;
-#define FAULT_BEHAVIOUR BIT(0)
-#define EXT_REQ_EN BIT(1)
+#define FAULT_BEHAVIOUR s2BIT(0)
+#define EXT_REQ_EN s2BIT(1)
#define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3)
u8 unused7_1[0x230 - 0x208];
@@ -317,29 +317,29 @@ struct XENA_dev_config {
/* TxDMA registers */
u64 txdma_int_status;
u64 txdma_int_mask;
-#define TXDMA_PFC_INT BIT(0)
-#define TXDMA_TDA_INT BIT(1)
-#define TXDMA_PCC_INT BIT(2)
-#define TXDMA_TTI_INT BIT(3)
-#define TXDMA_LSO_INT BIT(4)
-#define TXDMA_TPA_INT BIT(5)
-#define TXDMA_SM_INT BIT(6)
+#define TXDMA_PFC_INT s2BIT(0)
+#define TXDMA_TDA_INT s2BIT(1)
+#define TXDMA_PCC_INT s2BIT(2)
+#define TXDMA_TTI_INT s2BIT(3)
+#define TXDMA_LSO_INT s2BIT(4)
+#define TXDMA_TPA_INT s2BIT(5)
+#define TXDMA_SM_INT s2BIT(6)
u64 pfc_err_reg;
-#define PFC_ECC_SG_ERR BIT(7)
-#define PFC_ECC_DB_ERR BIT(15)
-#define PFC_SM_ERR_ALARM BIT(23)
-#define PFC_MISC_0_ERR BIT(31)
-#define PFC_MISC_1_ERR BIT(32)
-#define PFC_PCIX_ERR BIT(39)
+#define PFC_ECC_SG_ERR s2BIT(7)
+#define PFC_ECC_DB_ERR s2BIT(15)
+#define PFC_SM_ERR_ALARM s2BIT(23)
+#define PFC_MISC_0_ERR s2BIT(31)
+#define PFC_MISC_1_ERR s2BIT(32)
+#define PFC_PCIX_ERR s2BIT(39)
u64 pfc_err_mask;
u64 pfc_err_alarm;
u64 tda_err_reg;
#define TDA_Fn_ECC_SG_ERR vBIT(0xff,0,8)
#define TDA_Fn_ECC_DB_ERR vBIT(0xff,8,8)
-#define TDA_SM0_ERR_ALARM BIT(22)
-#define TDA_SM1_ERR_ALARM BIT(23)
-#define TDA_PCIX_ERR BIT(39)
+#define TDA_SM0_ERR_ALARM s2BIT(22)
+#define TDA_SM1_ERR_ALARM s2BIT(23)
+#define TDA_PCIX_ERR s2BIT(39)
u64 tda_err_mask;
u64 tda_err_alarm;
@@ -351,40 +351,40 @@ struct XENA_dev_config {
#define PCC_SM_ERR_ALARM vBIT(0xff,32,8)
#define PCC_WR_ERR_ALARM vBIT(0xff,40,8)
#define PCC_N_SERR vBIT(0xff,48,8)
-#define PCC_6_COF_OV_ERR BIT(56)
-#define PCC_7_COF_OV_ERR BIT(57)
-#define PCC_6_LSO_OV_ERR BIT(58)
-#define PCC_7_LSO_OV_ERR BIT(59)
+#define PCC_6_COF_OV_ERR s2BIT(56)
+#define PCC_7_COF_OV_ERR s2BIT(57)
+#define PCC_6_LSO_OV_ERR s2BIT(58)
+#define PCC_7_LSO_OV_ERR s2BIT(59)
#define PCC_ENABLE_FOUR vBIT(0x0F,0,8)
u64 pcc_err_mask;
u64 pcc_err_alarm;
u64 tti_err_reg;
-#define TTI_ECC_SG_ERR BIT(7)
-#define TTI_ECC_DB_ERR BIT(15)
-#define TTI_SM_ERR_ALARM BIT(23)
+#define TTI_ECC_SG_ERR s2BIT(7)
+#define TTI_ECC_DB_ERR s2BIT(15)
+#define TTI_SM_ERR_ALARM s2BIT(23)
u64 tti_err_mask;
u64 tti_err_alarm;
u64 lso_err_reg;
-#define LSO6_SEND_OFLOW BIT(12)
-#define LSO7_SEND_OFLOW BIT(13)
-#define LSO6_ABORT BIT(14)
-#define LSO7_ABORT BIT(15)
-#define LSO6_SM_ERR_ALARM BIT(22)
-#define LSO7_SM_ERR_ALARM BIT(23)
+#define LSO6_SEND_OFLOW s2BIT(12)
+#define LSO7_SEND_OFLOW s2BIT(13)
+#define LSO6_ABORT s2BIT(14)
+#define LSO7_ABORT s2BIT(15)
+#define LSO6_SM_ERR_ALARM s2BIT(22)
+#define LSO7_SM_ERR_ALARM s2BIT(23)
u64 lso_err_mask;
u64 lso_err_alarm;
u64 tpa_err_reg;
-#define TPA_TX_FRM_DROP BIT(7)
-#define TPA_SM_ERR_ALARM BIT(23)
+#define TPA_TX_FRM_DROP s2BIT(7)
+#define TPA_SM_ERR_ALARM s2BIT(23)
u64 tpa_err_mask;
u64 tpa_err_alarm;
u64 sm_err_reg;
-#define SM_SM_ERR_ALARM BIT(15)
+#define SM_SM_ERR_ALARM s2BIT(15)
u64 sm_err_mask;
u64 sm_err_alarm;
@@ -397,7 +397,7 @@ struct XENA_dev_config {
#define X_MAX_FIFOS 8
#define X_FIFO_MAX_LEN 0x1FFF /*8191 */
u64 tx_fifo_partition_0;
-#define TX_FIFO_PARTITION_EN BIT(0)
+#define TX_FIFO_PARTITION_EN s2BIT(0)
#define TX_FIFO_PARTITION_0_PRI(val) vBIT(val,5,3)
#define TX_FIFO_PARTITION_0_LEN(val) vBIT(val,19,13)
#define TX_FIFO_PARTITION_1_PRI(val) vBIT(val,37,3)
@@ -437,16 +437,16 @@ struct XENA_dev_config {
u64 tx_w_round_robin_4;
u64 tti_command_mem;
-#define TTI_CMD_MEM_WE BIT(7)
-#define TTI_CMD_MEM_STROBE_NEW_CMD BIT(15)
-#define TTI_CMD_MEM_STROBE_BEING_EXECUTED BIT(15)
+#define TTI_CMD_MEM_WE s2BIT(7)
+#define TTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
+#define TTI_CMD_MEM_STROBE_BEING_EXECUTED s2BIT(15)
#define TTI_CMD_MEM_OFFSET(n) vBIT(n,26,6)
u64 tti_data1_mem;
#define TTI_DATA1_MEM_TX_TIMER_VAL(n) vBIT(n,6,26)
#define TTI_DATA1_MEM_TX_TIMER_AC_CI(n) vBIT(n,38,2)
-#define TTI_DATA1_MEM_TX_TIMER_AC_EN BIT(38)
-#define TTI_DATA1_MEM_TX_TIMER_CI_EN BIT(39)
+#define TTI_DATA1_MEM_TX_TIMER_AC_EN s2BIT(38)
+#define TTI_DATA1_MEM_TX_TIMER_CI_EN s2BIT(39)
#define TTI_DATA1_MEM_TX_URNG_A(n) vBIT(n,41,7)
#define TTI_DATA1_MEM_TX_URNG_B(n) vBIT(n,49,7)
#define TTI_DATA1_MEM_TX_URNG_C(n) vBIT(n,57,7)
@@ -459,11 +459,11 @@ struct XENA_dev_config {
/* Tx Protocol assist */
u64 tx_pa_cfg;
-#define TX_PA_CFG_IGNORE_FRM_ERR BIT(1)
-#define TX_PA_CFG_IGNORE_SNAP_OUI BIT(2)
-#define TX_PA_CFG_IGNORE_LLC_CTRL BIT(3)
-#define TX_PA_CFG_IGNORE_L2_ERR BIT(6)
-#define RX_PA_CFG_STRIP_VLAN_TAG BIT(15)
+#define TX_PA_CFG_IGNORE_FRM_ERR s2BIT(1)
+#define TX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2)
+#define TX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3)
+#define TX_PA_CFG_IGNORE_L2_ERR s2BIT(6)
+#define RX_PA_CFG_STRIP_VLAN_TAG s2BIT(15)
/* Recent add, used only debug purposes. */
u64 pcc_enable;
@@ -477,31 +477,31 @@ struct XENA_dev_config {
/* RxDMA Registers */
u64 rxdma_int_status;
u64 rxdma_int_mask;
-#define RXDMA_INT_RC_INT_M BIT(0)
-#define RXDMA_INT_RPA_INT_M BIT(1)
-#define RXDMA_INT_RDA_INT_M BIT(2)
-#define RXDMA_INT_RTI_INT_M BIT(3)
+#define RXDMA_INT_RC_INT_M s2BIT(0)
+#define RXDMA_INT_RPA_INT_M s2BIT(1)
+#define RXDMA_INT_RDA_INT_M s2BIT(2)
+#define RXDMA_INT_RTI_INT_M s2BIT(3)
u64 rda_err_reg;
#define RDA_RXDn_ECC_SG_ERR vBIT(0xFF,0,8)
#define RDA_RXDn_ECC_DB_ERR vBIT(0xFF,8,8)
-#define RDA_FRM_ECC_SG_ERR BIT(23)
-#define RDA_FRM_ECC_DB_N_AERR BIT(31)
-#define RDA_SM1_ERR_ALARM BIT(38)
-#define RDA_SM0_ERR_ALARM BIT(39)
-#define RDA_MISC_ERR BIT(47)
-#define RDA_PCIX_ERR BIT(55)
-#define RDA_RXD_ECC_DB_SERR BIT(63)
+#define RDA_FRM_ECC_SG_ERR s2BIT(23)
+#define RDA_FRM_ECC_DB_N_AERR s2BIT(31)
+#define RDA_SM1_ERR_ALARM s2BIT(38)
+#define RDA_SM0_ERR_ALARM s2BIT(39)
+#define RDA_MISC_ERR s2BIT(47)
+#define RDA_PCIX_ERR s2BIT(55)
+#define RDA_RXD_ECC_DB_SERR s2BIT(63)
u64 rda_err_mask;
u64 rda_err_alarm;
u64 rc_err_reg;
#define RC_PRCn_ECC_SG_ERR vBIT(0xFF,0,8)
#define RC_PRCn_ECC_DB_ERR vBIT(0xFF,8,8)
-#define RC_FTC_ECC_SG_ERR BIT(23)
-#define RC_FTC_ECC_DB_ERR BIT(31)
+#define RC_FTC_ECC_SG_ERR s2BIT(23)
+#define RC_FTC_ECC_DB_ERR s2BIT(31)
#define RC_PRCn_SM_ERR_ALARM vBIT(0xFF,32,8)
-#define RC_FTC_SM_ERR_ALARM BIT(47)
+#define RC_FTC_SM_ERR_ALARM s2BIT(47)
#define RC_RDA_FAIL_WR_Rn vBIT(0xFF,48,8)
u64 rc_err_mask;
u64 rc_err_alarm;
@@ -517,18 +517,18 @@ struct XENA_dev_config {
u64 prc_pcix_err_alarm;
u64 rpa_err_reg;
-#define RPA_ECC_SG_ERR BIT(7)
-#define RPA_ECC_DB_ERR BIT(15)
-#define RPA_FLUSH_REQUEST BIT(22)
-#define RPA_SM_ERR_ALARM BIT(23)
-#define RPA_CREDIT_ERR BIT(31)
+#define RPA_ECC_SG_ERR s2BIT(7)
+#define RPA_ECC_DB_ERR s2BIT(15)
+#define RPA_FLUSH_REQUEST s2BIT(22)
+#define RPA_SM_ERR_ALARM s2BIT(23)
+#define RPA_CREDIT_ERR s2BIT(31)
u64 rpa_err_mask;
u64 rpa_err_alarm;
u64 rti_err_reg;
-#define RTI_ECC_SG_ERR BIT(7)
-#define RTI_ECC_DB_ERR BIT(15)
-#define RTI_SM_ERR_ALARM BIT(23)
+#define RTI_ECC_SG_ERR s2BIT(7)
+#define RTI_ECC_DB_ERR s2BIT(15)
+#define RTI_SM_ERR_ALARM s2BIT(23)
u64 rti_err_mask;
u64 rti_err_alarm;
@@ -568,49 +568,49 @@ struct XENA_dev_config {
#endif
u64 prc_rxd0_n[RX_MAX_RINGS];
u64 prc_ctrl_n[RX_MAX_RINGS];
-#define PRC_CTRL_RC_ENABLED BIT(7)
-#define PRC_CTRL_RING_MODE (BIT(14)|BIT(15))
+#define PRC_CTRL_RC_ENABLED s2BIT(7)
+#define PRC_CTRL_RING_MODE (s2BIT(14)|s2BIT(15))
#define PRC_CTRL_RING_MODE_1 vBIT(0,14,2)
#define PRC_CTRL_RING_MODE_3 vBIT(1,14,2)
#define PRC_CTRL_RING_MODE_5 vBIT(2,14,2)
#define PRC_CTRL_RING_MODE_x vBIT(3,14,2)
-#define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23))
-#define PRC_CTRL_NO_SNOOP_DESC BIT(22)
-#define PRC_CTRL_NO_SNOOP_BUFF BIT(23)
-#define PRC_CTRL_BIMODAL_INTERRUPT BIT(37)
-#define PRC_CTRL_GROUP_READS BIT(38)
+#define PRC_CTRL_NO_SNOOP (s2BIT(22)|s2BIT(23))
+#define PRC_CTRL_NO_SNOOP_DESC s2BIT(22)
+#define PRC_CTRL_NO_SNOOP_BUFF s2BIT(23)
+#define PRC_CTRL_BIMODAL_INTERRUPT s2BIT(37)
+#define PRC_CTRL_GROUP_READS s2BIT(38)
#define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24)
u64 prc_alarm_action;
-#define PRC_ALARM_ACTION_RR_R0_STOP BIT(3)
-#define PRC_ALARM_ACTION_RW_R0_STOP BIT(7)
-#define PRC_ALARM_ACTION_RR_R1_STOP BIT(11)
-#define PRC_ALARM_ACTION_RW_R1_STOP BIT(15)
-#define PRC_ALARM_ACTION_RR_R2_STOP BIT(19)
-#define PRC_ALARM_ACTION_RW_R2_STOP BIT(23)
-#define PRC_ALARM_ACTION_RR_R3_STOP BIT(27)
-#define PRC_ALARM_ACTION_RW_R3_STOP BIT(31)
-#define PRC_ALARM_ACTION_RR_R4_STOP BIT(35)
-#define PRC_ALARM_ACTION_RW_R4_STOP BIT(39)
-#define PRC_ALARM_ACTION_RR_R5_STOP BIT(43)
-#define PRC_ALARM_ACTION_RW_R5_STOP BIT(47)
-#define PRC_ALARM_ACTION_RR_R6_STOP BIT(51)
-#define PRC_ALARM_ACTION_RW_R6_STOP BIT(55)
-#define PRC_ALARM_ACTION_RR_R7_STOP BIT(59)
-#define PRC_ALARM_ACTION_RW_R7_STOP BIT(63)
+#define PRC_ALARM_ACTION_RR_R0_STOP s2BIT(3)
+#define PRC_ALARM_ACTION_RW_R0_STOP s2BIT(7)
+#define PRC_ALARM_ACTION_RR_R1_STOP s2BIT(11)
+#define PRC_ALARM_ACTION_RW_R1_STOP s2BIT(15)
+#define PRC_ALARM_ACTION_RR_R2_STOP s2BIT(19)
+#define PRC_ALARM_ACTION_RW_R2_STOP s2BIT(23)
+#define PRC_ALARM_ACTION_RR_R3_STOP s2BIT(27)
+#define PRC_ALARM_ACTION_RW_R3_STOP s2BIT(31)
+#define PRC_ALARM_ACTION_RR_R4_STOP s2BIT(35)
+#define PRC_ALARM_ACTION_RW_R4_STOP s2BIT(39)
+#define PRC_ALARM_ACTION_RR_R5_STOP s2BIT(43)
+#define PRC_ALARM_ACTION_RW_R5_STOP s2BIT(47)
+#define PRC_ALARM_ACTION_RR_R6_STOP s2BIT(51)
+#define PRC_ALARM_ACTION_RW_R6_STOP s2BIT(55)
+#define PRC_ALARM_ACTION_RR_R7_STOP s2BIT(59)
+#define PRC_ALARM_ACTION_RW_R7_STOP s2BIT(63)
/* Receive traffic interrupts */
u64 rti_command_mem;
-#define RTI_CMD_MEM_WE BIT(7)
-#define RTI_CMD_MEM_STROBE BIT(15)
-#define RTI_CMD_MEM_STROBE_NEW_CMD BIT(15)
-#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED BIT(15)
+#define RTI_CMD_MEM_WE s2BIT(7)
+#define RTI_CMD_MEM_STROBE s2BIT(15)
+#define RTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
+#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED s2BIT(15)
#define RTI_CMD_MEM_OFFSET(n) vBIT(n,29,3)
u64 rti_data1_mem;
#define RTI_DATA1_MEM_RX_TIMER_VAL(n) vBIT(n,3,29)
-#define RTI_DATA1_MEM_RX_TIMER_AC_EN BIT(38)
-#define RTI_DATA1_MEM_RX_TIMER_CI_EN BIT(39)
+#define RTI_DATA1_MEM_RX_TIMER_AC_EN s2BIT(38)
+#define RTI_DATA1_MEM_RX_TIMER_CI_EN s2BIT(39)
#define RTI_DATA1_MEM_RX_URNG_A(n) vBIT(n,41,7)
#define RTI_DATA1_MEM_RX_URNG_B(n) vBIT(n,49,7)
#define RTI_DATA1_MEM_RX_URNG_C(n) vBIT(n,57,7)
@@ -622,10 +622,10 @@ struct XENA_dev_config {
#define RTI_DATA2_MEM_RX_UFC_D(n) vBIT(n,48,16)
u64 rx_pa_cfg;
-#define RX_PA_CFG_IGNORE_FRM_ERR BIT(1)
-#define RX_PA_CFG_IGNORE_SNAP_OUI BIT(2)
-#define RX_PA_CFG_IGNORE_LLC_CTRL BIT(3)
-#define RX_PA_CFG_IGNORE_L2_ERR BIT(6)
+#define RX_PA_CFG_IGNORE_FRM_ERR s2BIT(1)
+#define RX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2)
+#define RX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3)
+#define RX_PA_CFG_IGNORE_L2_ERR s2BIT(6)
u64 unused_11_1;
@@ -641,64 +641,64 @@ struct XENA_dev_config {
/* Media Access Controller Register */
u64 mac_int_status;
u64 mac_int_mask;
-#define MAC_INT_STATUS_TMAC_INT BIT(0)
-#define MAC_INT_STATUS_RMAC_INT BIT(1)
+#define MAC_INT_STATUS_TMAC_INT s2BIT(0)
+#define MAC_INT_STATUS_RMAC_INT s2BIT(1)
u64 mac_tmac_err_reg;
-#define TMAC_ECC_SG_ERR BIT(7)
-#define TMAC_ECC_DB_ERR BIT(15)
-#define TMAC_TX_BUF_OVRN BIT(23)
-#define TMAC_TX_CRI_ERR BIT(31)
-#define TMAC_TX_SM_ERR BIT(39)
-#define TMAC_DESC_ECC_SG_ERR BIT(47)
-#define TMAC_DESC_ECC_DB_ERR BIT(55)
+#define TMAC_ECC_SG_ERR s2BIT(7)
+#define TMAC_ECC_DB_ERR s2BIT(15)
+#define TMAC_TX_BUF_OVRN s2BIT(23)
+#define TMAC_TX_CRI_ERR s2BIT(31)
+#define TMAC_TX_SM_ERR s2BIT(39)
+#define TMAC_DESC_ECC_SG_ERR s2BIT(47)
+#define TMAC_DESC_ECC_DB_ERR s2BIT(55)
u64 mac_tmac_err_mask;
u64 mac_tmac_err_alarm;
u64 mac_rmac_err_reg;
-#define RMAC_RX_BUFF_OVRN BIT(0)
-#define RMAC_FRM_RCVD_INT BIT(1)
-#define RMAC_UNUSED_INT BIT(2)
-#define RMAC_RTS_PNUM_ECC_SG_ERR BIT(5)
-#define RMAC_RTS_DS_ECC_SG_ERR BIT(6)
-#define RMAC_RD_BUF_ECC_SG_ERR BIT(7)
-#define RMAC_RTH_MAP_ECC_SG_ERR BIT(8)
-#define RMAC_RTH_SPDM_ECC_SG_ERR BIT(9)
-#define RMAC_RTS_VID_ECC_SG_ERR BIT(10)
-#define RMAC_DA_SHADOW_ECC_SG_ERR BIT(11)
-#define RMAC_RTS_PNUM_ECC_DB_ERR BIT(13)
-#define RMAC_RTS_DS_ECC_DB_ERR BIT(14)
-#define RMAC_RD_BUF_ECC_DB_ERR BIT(15)
-#define RMAC_RTH_MAP_ECC_DB_ERR BIT(16)
-#define RMAC_RTH_SPDM_ECC_DB_ERR BIT(17)
-#define RMAC_RTS_VID_ECC_DB_ERR BIT(18)
-#define RMAC_DA_SHADOW_ECC_DB_ERR BIT(19)
-#define RMAC_LINK_STATE_CHANGE_INT BIT(31)
-#define RMAC_RX_SM_ERR BIT(39)
-#define RMAC_SINGLE_ECC_ERR (BIT(5) | BIT(6) | BIT(7) |\
- BIT(8) | BIT(9) | BIT(10)|\
- BIT(11))
-#define RMAC_DOUBLE_ECC_ERR (BIT(13) | BIT(14) | BIT(15) |\
- BIT(16) | BIT(17) | BIT(18)|\
- BIT(19))
+#define RMAC_RX_BUFF_OVRN s2BIT(0)
+#define RMAC_FRM_RCVD_INT s2BIT(1)
+#define RMAC_UNUSED_INT s2BIT(2)
+#define RMAC_RTS_PNUM_ECC_SG_ERR s2BIT(5)
+#define RMAC_RTS_DS_ECC_SG_ERR s2BIT(6)
+#define RMAC_RD_BUF_ECC_SG_ERR s2BIT(7)
+#define RMAC_RTH_MAP_ECC_SG_ERR s2BIT(8)
+#define RMAC_RTH_SPDM_ECC_SG_ERR s2BIT(9)
+#define RMAC_RTS_VID_ECC_SG_ERR s2BIT(10)
+#define RMAC_DA_SHADOW_ECC_SG_ERR s2BIT(11)
+#define RMAC_RTS_PNUM_ECC_DB_ERR s2BIT(13)
+#define RMAC_RTS_DS_ECC_DB_ERR s2BIT(14)
+#define RMAC_RD_BUF_ECC_DB_ERR s2BIT(15)
+#define RMAC_RTH_MAP_ECC_DB_ERR s2BIT(16)
+#define RMAC_RTH_SPDM_ECC_DB_ERR s2BIT(17)
+#define RMAC_RTS_VID_ECC_DB_ERR s2BIT(18)
+#define RMAC_DA_SHADOW_ECC_DB_ERR s2BIT(19)
+#define RMAC_LINK_STATE_CHANGE_INT s2BIT(31)
+#define RMAC_RX_SM_ERR s2BIT(39)
+#define RMAC_SINGLE_ECC_ERR (s2BIT(5) | s2BIT(6) | s2BIT(7) |\
+ s2BIT(8) | s2BIT(9) | s2BIT(10)|\
+ s2BIT(11))
+#define RMAC_DOUBLE_ECC_ERR (s2BIT(13) | s2BIT(14) | s2BIT(15) |\
+ s2BIT(16) | s2BIT(17) | s2BIT(18)|\
+ s2BIT(19))
u64 mac_rmac_err_mask;
u64 mac_rmac_err_alarm;
u8 unused14[0x100 - 0x40];
u64 mac_cfg;
-#define MAC_CFG_TMAC_ENABLE BIT(0)
-#define MAC_CFG_RMAC_ENABLE BIT(1)
-#define MAC_CFG_LAN_NOT_WAN BIT(2)
-#define MAC_CFG_TMAC_LOOPBACK BIT(3)
-#define MAC_CFG_TMAC_APPEND_PAD BIT(4)
-#define MAC_CFG_RMAC_STRIP_FCS BIT(5)
-#define MAC_CFG_RMAC_STRIP_PAD BIT(6)
-#define MAC_CFG_RMAC_PROM_ENABLE BIT(7)
-#define MAC_RMAC_DISCARD_PFRM BIT(8)
-#define MAC_RMAC_BCAST_ENABLE BIT(9)
-#define MAC_RMAC_ALL_ADDR_ENABLE BIT(10)
+#define MAC_CFG_TMAC_ENABLE s2BIT(0)
+#define MAC_CFG_RMAC_ENABLE s2BIT(1)
+#define MAC_CFG_LAN_NOT_WAN s2BIT(2)
+#define MAC_CFG_TMAC_LOOPBACK s2BIT(3)
+#define MAC_CFG_TMAC_APPEND_PAD s2BIT(4)
+#define MAC_CFG_RMAC_STRIP_FCS s2BIT(5)
+#define MAC_CFG_RMAC_STRIP_PAD s2BIT(6)
+#define MAC_CFG_RMAC_PROM_ENABLE s2BIT(7)
+#define MAC_RMAC_DISCARD_PFRM s2BIT(8)
+#define MAC_RMAC_BCAST_ENABLE s2BIT(9)
+#define MAC_RMAC_ALL_ADDR_ENABLE s2BIT(10)
#define MAC_RMAC_INVLD_IPG_THR(val) vBIT(val,16,8)
u64 tmac_avg_ipg;
@@ -710,14 +710,14 @@ struct XENA_dev_config {
#define RMAC_MAX_PYLD_LEN_JUMBO_DEF vBIT(9600,2,14)
u64 rmac_err_cfg;
-#define RMAC_ERR_FCS BIT(0)
-#define RMAC_ERR_FCS_ACCEPT BIT(1)
-#define RMAC_ERR_TOO_LONG BIT(1)
-#define RMAC_ERR_TOO_LONG_ACCEPT BIT(1)
-#define RMAC_ERR_RUNT BIT(2)
-#define RMAC_ERR_RUNT_ACCEPT BIT(2)
-#define RMAC_ERR_LEN_MISMATCH BIT(3)
-#define RMAC_ERR_LEN_MISMATCH_ACCEPT BIT(3)
+#define RMAC_ERR_FCS s2BIT(0)
+#define RMAC_ERR_FCS_ACCEPT s2BIT(1)
+#define RMAC_ERR_TOO_LONG s2BIT(1)
+#define RMAC_ERR_TOO_LONG_ACCEPT s2BIT(1)
+#define RMAC_ERR_RUNT s2BIT(2)
+#define RMAC_ERR_RUNT_ACCEPT s2BIT(2)
+#define RMAC_ERR_LEN_MISMATCH s2BIT(3)
+#define RMAC_ERR_LEN_MISMATCH_ACCEPT s2BIT(3)
u64 rmac_cfg_key;
#define RMAC_CFG_KEY(val) vBIT(val,0,16)
@@ -728,15 +728,15 @@ struct XENA_dev_config {
#define MAC_MC_ADDR_START_OFFSET 16
#define MAC_MC_ALL_MC_ADDR_OFFSET 63 /* enables all multicast pkts */
u64 rmac_addr_cmd_mem;
-#define RMAC_ADDR_CMD_MEM_WE BIT(7)
+#define RMAC_ADDR_CMD_MEM_WE s2BIT(7)
#define RMAC_ADDR_CMD_MEM_RD 0
-#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD BIT(15)
-#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD s2BIT(15)
+#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING s2BIT(15)
#define RMAC_ADDR_CMD_MEM_OFFSET(n) vBIT(n,26,6)
u64 rmac_addr_data0_mem;
#define RMAC_ADDR_DATA0_MEM_ADDR(n) vBIT(n,0,48)
-#define RMAC_ADDR_DATA0_MEM_USER BIT(48)
+#define RMAC_ADDR_DATA0_MEM_USER s2BIT(48)
u64 rmac_addr_data1_mem;
#define RMAC_ADDR_DATA1_MEM_MASK(n) vBIT(n,0,48)
@@ -753,10 +753,10 @@ struct XENA_dev_config {
u64 tmac_ipg_cfg;
u64 rmac_pause_cfg;
-#define RMAC_PAUSE_GEN BIT(0)
-#define RMAC_PAUSE_GEN_ENABLE BIT(0)
-#define RMAC_PAUSE_RX BIT(1)
-#define RMAC_PAUSE_RX_ENABLE BIT(1)
+#define RMAC_PAUSE_GEN s2BIT(0)
+#define RMAC_PAUSE_GEN_ENABLE s2BIT(0)
+#define RMAC_PAUSE_RX s2BIT(1)
+#define RMAC_PAUSE_RX_ENABLE s2BIT(1)
#define RMAC_PAUSE_HG_PTIME_DEF vBIT(0xFFFF,16,16)
#define RMAC_PAUSE_HG_PTIME(val) vBIT(val,16,16)
@@ -787,29 +787,29 @@ struct XENA_dev_config {
#define MAX_DIX_MAP 4
u64 rts_dix_map_n[MAX_DIX_MAP];
#define RTS_DIX_MAP_ETYPE(val) vBIT(val,0,16)
-#define RTS_DIX_MAP_SCW(val) BIT(val,21)
+#define RTS_DIX_MAP_SCW(val) s2BIT(val,21)
u64 rts_q_alternates;
u64 rts_default_q;
u64 rts_ctrl;
-#define RTS_CTRL_IGNORE_SNAP_OUI BIT(2)
-#define RTS_CTRL_IGNORE_LLC_CTRL BIT(3)
+#define RTS_CTRL_IGNORE_SNAP_OUI s2BIT(2)
+#define RTS_CTRL_IGNORE_LLC_CTRL s2BIT(3)
u64 rts_pn_cam_ctrl;
-#define RTS_PN_CAM_CTRL_WE BIT(7)
-#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD BIT(15)
-#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED BIT(15)
+#define RTS_PN_CAM_CTRL_WE s2BIT(7)
+#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD s2BIT(15)
+#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED s2BIT(15)
#define RTS_PN_CAM_CTRL_OFFSET(n) vBIT(n,24,8)
u64 rts_pn_cam_data;
-#define RTS_PN_CAM_DATA_TCP_SELECT BIT(7)
+#define RTS_PN_CAM_DATA_TCP_SELECT s2BIT(7)
#define RTS_PN_CAM_DATA_PORT(val) vBIT(val,8,16)
#define RTS_PN_CAM_DATA_SCW(val) vBIT(val,24,8)
u64 rts_ds_mem_ctrl;
-#define RTS_DS_MEM_CTRL_WE BIT(7)
-#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD BIT(15)
-#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED BIT(15)
+#define RTS_DS_MEM_CTRL_WE s2BIT(7)
+#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD s2BIT(15)
+#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED s2BIT(15)
#define RTS_DS_MEM_CTRL_OFFSET(n) vBIT(n,26,6)
u64 rts_ds_mem_data;
#define RTS_DS_MEM_DATA(n) vBIT(n,0,8)
@@ -823,23 +823,23 @@ struct XENA_dev_config {
/* memory controller registers */
u64 mc_int_status;
-#define MC_INT_STATUS_MC_INT BIT(0)
+#define MC_INT_STATUS_MC_INT s2BIT(0)
u64 mc_int_mask;
-#define MC_INT_MASK_MC_INT BIT(0)
+#define MC_INT_MASK_MC_INT s2BIT(0)
u64 mc_err_reg;
-#define MC_ERR_REG_ECC_DB_ERR_L BIT(14)
-#define MC_ERR_REG_ECC_DB_ERR_U BIT(15)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_0 BIT(18)
-#define MC_ERR_REG_MIRI_ECC_DB_ERR_1 BIT(20)
-#define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22)
-#define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23)
-#define MC_ERR_REG_SM_ERR BIT(31)
-#define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\
- BIT(17) | BIT(19))
-#define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\
- BIT(13) | BIT(18) | BIT(20))
-#define PLL_LOCK_N BIT(39)
+#define MC_ERR_REG_ECC_DB_ERR_L s2BIT(14)
+#define MC_ERR_REG_ECC_DB_ERR_U s2BIT(15)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_0 s2BIT(18)
+#define MC_ERR_REG_MIRI_ECC_DB_ERR_1 s2BIT(20)
+#define MC_ERR_REG_MIRI_CRI_ERR_0 s2BIT(22)
+#define MC_ERR_REG_MIRI_CRI_ERR_1 s2BIT(23)
+#define MC_ERR_REG_SM_ERR s2BIT(31)
+#define MC_ERR_REG_ECC_ALL_SNG (s2BIT(2) | s2BIT(3) | s2BIT(4) | s2BIT(5) |\
+ s2BIT(17) | s2BIT(19))
+#define MC_ERR_REG_ECC_ALL_DBL (s2BIT(10) | s2BIT(11) | s2BIT(12) |\
+ s2BIT(13) | s2BIT(18) | s2BIT(20))
+#define PLL_LOCK_N s2BIT(39)
u64 mc_err_mask;
u64 mc_err_alarm;
@@ -857,8 +857,8 @@ struct XENA_dev_config {
#define RX_QUEUE_CFG_Q7_SZ(n) vBIT(n,56,8)
u64 mc_rldram_mrs;
-#define MC_RLDRAM_QUEUE_SIZE_ENABLE BIT(39)
-#define MC_RLDRAM_MRS_ENABLE BIT(47)
+#define MC_RLDRAM_QUEUE_SIZE_ENABLE s2BIT(39)
+#define MC_RLDRAM_MRS_ENABLE s2BIT(47)
u64 mc_rldram_interleave;
@@ -871,11 +871,11 @@ struct XENA_dev_config {
u64 mc_rldram_ref_per;
u8 unused20[0x220 - 0x208];
u64 mc_rldram_test_ctrl;
-#define MC_RLDRAM_TEST_MODE BIT(47)
-#define MC_RLDRAM_TEST_WRITE BIT(7)
-#define MC_RLDRAM_TEST_GO BIT(15)
-#define MC_RLDRAM_TEST_DONE BIT(23)
-#define MC_RLDRAM_TEST_PASS BIT(31)
+#define MC_RLDRAM_TEST_MODE s2BIT(47)
+#define MC_RLDRAM_TEST_WRITE s2BIT(7)
+#define MC_RLDRAM_TEST_GO s2BIT(15)
+#define MC_RLDRAM_TEST_DONE s2BIT(23)
+#define MC_RLDRAM_TEST_PASS s2BIT(31)
u8 unused21[0x240 - 0x228];
u64 mc_rldram_test_add;
@@ -888,7 +888,7 @@ struct XENA_dev_config {
u8 unused24_1[0x360 - 0x308];
u64 mc_rldram_ctrl;
-#define MC_RLDRAM_ENABLE_ODT BIT(7)
+#define MC_RLDRAM_ENABLE_ODT s2BIT(7)
u8 unused24_2[0x640 - 0x368];
u64 mc_rldram_ref_per_herc;
@@ -906,24 +906,24 @@ struct XENA_dev_config {
/* XGXS control registers */
u64 xgxs_int_status;
-#define XGXS_INT_STATUS_TXGXS BIT(0)
-#define XGXS_INT_STATUS_RXGXS BIT(1)
+#define XGXS_INT_STATUS_TXGXS s2BIT(0)
+#define XGXS_INT_STATUS_RXGXS s2BIT(1)
u64 xgxs_int_mask;
-#define XGXS_INT_MASK_TXGXS BIT(0)
-#define XGXS_INT_MASK_RXGXS BIT(1)
+#define XGXS_INT_MASK_TXGXS s2BIT(0)
+#define XGXS_INT_MASK_RXGXS s2BIT(1)
u64 xgxs_txgxs_err_reg;
-#define TXGXS_ECC_SG_ERR BIT(7)
-#define TXGXS_ECC_DB_ERR BIT(15)
-#define TXGXS_ESTORE_UFLOW BIT(31)
-#define TXGXS_TX_SM_ERR BIT(39)
+#define TXGXS_ECC_SG_ERR s2BIT(7)
+#define TXGXS_ECC_DB_ERR s2BIT(15)
+#define TXGXS_ESTORE_UFLOW s2BIT(31)
+#define TXGXS_TX_SM_ERR s2BIT(39)
u64 xgxs_txgxs_err_mask;
u64 xgxs_txgxs_err_alarm;
u64 xgxs_rxgxs_err_reg;
-#define RXGXS_ESTORE_OFLOW BIT(7)
-#define RXGXS_RX_SM_ERR BIT(39)
+#define RXGXS_ESTORE_OFLOW s2BIT(7)
+#define RXGXS_RX_SM_ERR s2BIT(39)
u64 xgxs_rxgxs_err_mask;
u64 xgxs_rxgxs_err_alarm;
@@ -942,10 +942,10 @@ struct XENA_dev_config {
#define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3)
#define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8)
#define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24)
-#define SPI_CONTROL_SEL1 BIT(4)
-#define SPI_CONTROL_REQ BIT(7)
-#define SPI_CONTROL_NACK BIT(5)
-#define SPI_CONTROL_DONE BIT(6)
+#define SPI_CONTROL_SEL1 s2BIT(4)
+#define SPI_CONTROL_REQ s2BIT(7)
+#define SPI_CONTROL_NACK s2BIT(5)
+#define SPI_CONTROL_DONE s2BIT(6)
u64 spi_data;
#define SPI_DATA_WRITE(data,len) vBIT(data,0,len)
};
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 22e4054d4fc..b8c0e7b4ca1 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1716,7 +1716,7 @@ static int init_nic(struct s2io_nic *nic)
MISC_LINK_STABILITY_PRD(3);
writeq(val64, &bar0->misc_control);
val64 = readq(&bar0->pic_control2);
- val64 &= ~(BIT(13)|BIT(14)|BIT(15));
+ val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
writeq(val64, &bar0->pic_control2);
}
if (strstr(nic->product_name, "CX4")) {
@@ -2427,7 +2427,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
}
if ((rxdp->Control_1 & RXD_OWN_XENA) &&
((nic->rxd_mode == RXD_MODE_3B) &&
- (rxdp->Control_2 & BIT(0)))) {
+ (rxdp->Control_2 & s2BIT(0)))) {
mac_control->rings[ring_no].rx_curr_put_info.
offset = off;
goto end;
@@ -2540,7 +2540,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
(dev->mtu + 4);
}
- rxdp->Control_2 |= BIT(0);
+ rxdp->Control_2 |= s2BIT(0);
}
rxdp->Host_Control = (unsigned long) (skb);
if (alloc_tab & ((1 << rxsync_frequency) - 1))
@@ -3377,7 +3377,7 @@ static void s2io_reset(struct s2io_nic * sp)
pci_write_config_dword(sp->pdev, 0x68, 0x7C);
/* Clearing PCI_STATUS error reflected here */
- writeq(BIT(62), &bar0->txpic_int_reg);
+ writeq(s2BIT(62), &bar0->txpic_int_reg);
}
/* Reset device statistics maintained by OS */
@@ -3575,7 +3575,7 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i)
do {
val64 = readq(&bar0->xmsi_access);
- if (!(val64 & BIT(15)))
+ if (!(val64 & s2BIT(15)))
break;
mdelay(1);
cnt++;
@@ -3597,7 +3597,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
writeq(nic->msix_info[i].data, &bar0->xmsi_data);
- val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+ val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, i)) {
DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -3614,7 +3614,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
/* Store and display */
for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
- val64 = (BIT(15) | vBIT(i, 26, 6));
+ val64 = (s2BIT(15) | vBIT(i, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, i)) {
DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
@@ -4634,7 +4634,7 @@ static void s2io_updt_stats(struct s2io_nic *sp)
do {
udelay(100);
val64 = readq(&bar0->stat_cfg);
- if (!(val64 & BIT(0)))
+ if (!(val64 & s2BIT(0)))
break;
cnt++;
if (cnt == 5)
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index f6b45565304..cc1797a071a 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -14,7 +14,7 @@
#define _S2IO_H
#define TBD 0
-#define BIT(loc) (0x8000000000000000ULL >> (loc))
+#define s2BIT(loc) (0x8000000000000000ULL >> (loc))
#define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz))
#define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
@@ -473,42 +473,42 @@ struct TxFIFO_element {
u64 List_Control;
#define TX_FIFO_LAST_TXD_NUM( val) vBIT(val,0,8)
-#define TX_FIFO_FIRST_LIST BIT(14)
-#define TX_FIFO_LAST_LIST BIT(15)
+#define TX_FIFO_FIRST_LIST s2BIT(14)
+#define TX_FIFO_LAST_LIST s2BIT(15)
#define TX_FIFO_FIRSTNLAST_LIST vBIT(3,14,2)
-#define TX_FIFO_SPECIAL_FUNC BIT(23)
-#define TX_FIFO_DS_NO_SNOOP BIT(31)
-#define TX_FIFO_BUFF_NO_SNOOP BIT(30)
+#define TX_FIFO_SPECIAL_FUNC s2BIT(23)
+#define TX_FIFO_DS_NO_SNOOP s2BIT(31)
+#define TX_FIFO_BUFF_NO_SNOOP s2BIT(30)
};
/* Tx descriptor structure */
struct TxD {
u64 Control_1;
/* bit mask */
-#define TXD_LIST_OWN_XENA BIT(7)
-#define TXD_T_CODE (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define TXD_LIST_OWN_XENA s2BIT(7)
+#define TXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
#define TXD_T_CODE_OK(val) (|(val & TXD_T_CODE))
#define GET_TXD_T_CODE(val) ((val & TXD_T_CODE)<<12)
-#define TXD_GATHER_CODE (BIT(22) | BIT(23))
-#define TXD_GATHER_CODE_FIRST BIT(22)
-#define TXD_GATHER_CODE_LAST BIT(23)
-#define TXD_TCP_LSO_EN BIT(30)
-#define TXD_UDP_COF_EN BIT(31)
-#define TXD_UFO_EN BIT(31) | BIT(30)
+#define TXD_GATHER_CODE (s2BIT(22) | s2BIT(23))
+#define TXD_GATHER_CODE_FIRST s2BIT(22)
+#define TXD_GATHER_CODE_LAST s2BIT(23)
+#define TXD_TCP_LSO_EN s2BIT(30)
+#define TXD_UDP_COF_EN s2BIT(31)
+#define TXD_UFO_EN s2BIT(31) | s2BIT(30)
#define TXD_TCP_LSO_MSS(val) vBIT(val,34,14)
#define TXD_UFO_MSS(val) vBIT(val,34,14)
#define TXD_BUFFER0_SIZE(val) vBIT(val,48,16)
u64 Control_2;
-#define TXD_TX_CKO_CONTROL (BIT(5)|BIT(6)|BIT(7))
-#define TXD_TX_CKO_IPV4_EN BIT(5)
-#define TXD_TX_CKO_TCP_EN BIT(6)
-#define TXD_TX_CKO_UDP_EN BIT(7)
-#define TXD_VLAN_ENABLE BIT(15)
+#define TXD_TX_CKO_CONTROL (s2BIT(5)|s2BIT(6)|s2BIT(7))
+#define TXD_TX_CKO_IPV4_EN s2BIT(5)
+#define TXD_TX_CKO_TCP_EN s2BIT(6)
+#define TXD_TX_CKO_UDP_EN s2BIT(7)
+#define TXD_VLAN_ENABLE s2BIT(15)
#define TXD_VLAN_TAG(val) vBIT(val,16,16)
#define TXD_INT_NUMBER(val) vBIT(val,34,6)
-#define TXD_INT_TYPE_PER_LIST BIT(47)
-#define TXD_INT_TYPE_UTILZ BIT(46)
+#define TXD_INT_TYPE_PER_LIST s2BIT(47)
+#define TXD_INT_TYPE_UTILZ s2BIT(46)
#define TXD_SET_MARKER vBIT(0x6,0,4)
u64 Buffer_Pointer;
@@ -525,14 +525,14 @@ struct list_info_hold {
struct RxD_t {
u64 Host_Control; /* reserved for host */
u64 Control_1;
-#define RXD_OWN_XENA BIT(7)
-#define RXD_T_CODE (BIT(12)|BIT(13)|BIT(14)|BIT(15))
+#define RXD_OWN_XENA s2BIT(7)
+#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15))
#define RXD_FRAME_PROTO vBIT(0xFFFF,24,8)
-#define RXD_FRAME_PROTO_IPV4 BIT(27)
-#define RXD_FRAME_PROTO_IPV6 BIT(28)
-#define RXD_FRAME_IP_FRAG BIT(29)
-#define RXD_FRAME_PROTO_TCP BIT(30)
-#define RXD_FRAME_PROTO_UDP BIT(31)
+#define RXD_FRAME_PROTO_IPV4 s2BIT(27)
+#define RXD_FRAME_PROTO_IPV6 s2BIT(28)
+#define RXD_FRAME_IP_FRAG s2BIT(29)
+#define RXD_FRAME_PROTO_TCP s2BIT(30)
+#define RXD_FRAME_PROTO_UDP s2BIT(31)
#define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP)
#define RXD_GET_L3_CKSUM(val) ((u16)(val>> 16) & 0xFFFF)
#define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF)
@@ -998,26 +998,26 @@ static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
/* Interrupt masks for the general interrupt mask register */
#define DISABLE_ALL_INTRS 0xFFFFFFFFFFFFFFFFULL
-#define TXPIC_INT_M BIT(0)
-#define TXDMA_INT_M BIT(1)
-#define TXMAC_INT_M BIT(2)
-#define TXXGXS_INT_M BIT(3)
-#define TXTRAFFIC_INT_M BIT(8)
-#define PIC_RX_INT_M BIT(32)
-#define RXDMA_INT_M BIT(33)
-#define RXMAC_INT_M BIT(34)
-#define MC_INT_M BIT(35)
-#define RXXGXS_INT_M BIT(36)
-#define RXTRAFFIC_INT_M BIT(40)
+#define TXPIC_INT_M s2BIT(0)
+#define TXDMA_INT_M s2BIT(1)
+#define TXMAC_INT_M s2BIT(2)
+#define TXXGXS_INT_M s2BIT(3)
+#define TXTRAFFIC_INT_M s2BIT(8)
+#define PIC_RX_INT_M s2BIT(32)
+#define RXDMA_INT_M s2BIT(33)
+#define RXMAC_INT_M s2BIT(34)
+#define MC_INT_M s2BIT(35)
+#define RXXGXS_INT_M s2BIT(36)
+#define RXTRAFFIC_INT_M s2BIT(40)
/* PIC level Interrupts TODO*/
/* DMA level Inressupts */
-#define TXDMA_PFC_INT_M BIT(0)
-#define TXDMA_PCC_INT_M BIT(2)
+#define TXDMA_PFC_INT_M s2BIT(0)
+#define TXDMA_PCC_INT_M s2BIT(2)
/* PFC block interrupts */
-#define PFC_MISC_ERR_1 BIT(0) /* Interrupt to indicate FIFO full */
+#define PFC_MISC_ERR_1 s2BIT(0) /* Interrupt to indicate FIFO full */
/* PCC block interrupts. */
#define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 7c60df46fc6..dd18af0ce67 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -1223,7 +1223,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
}
#endif
- /* Handle PHY interupt condition */
+ /* Handle PHY interrupt condition */
if (status & INT_STS_PHY_INT_) {
DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name);
smc911x_phy_interrupt(dev);
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index fab055ffcc9..bccae7e5c6a 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -46,7 +46,7 @@
#include <linux/vmalloc.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/pci-bridge.h>
#include <net/checksum.h>
@@ -1639,7 +1639,7 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
/**
* spider_net_interrupt - interrupt handler for spider_net
- * @irq: interupt number
+ * @irq: interrupt number
* @ptr: pointer to net_device
* @regs: PU registers
*
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 8038f2882c9..d887c05588d 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1654,7 +1654,7 @@ tc35815_rx(struct net_device *dev)
panic_queues(dev);
}
#endif
- /* pass BD to controler */
+ /* pass BD to controller */
#ifndef TC35815_USE_PACKEDBUFFER
if (!lp->rx_skbs[curid].skb) {
lp->rx_skbs[curid].skb =
@@ -1694,7 +1694,7 @@ tc35815_rx(struct net_device *dev)
}
#endif
for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
- /* pass FD to controler */
+ /* pass FD to controller */
#ifdef DEBUG
lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);
#else
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 014dc2cfe4d..09440d783e6 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -64,8 +64,8 @@
#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.84"
-#define DRV_MODULE_RELDATE "October 12, 2007"
+#define DRV_MODULE_VERSION "3.85"
+#define DRV_MODULE_RELDATE "October 18, 2007"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
@@ -200,6 +200,7 @@ static struct pci_device_id tg3_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5906M)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5784)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5764)},
+ {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
{PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
@@ -5028,10 +5029,7 @@ static int tg3_poll_fw(struct tg3 *tp)
/* Save PCI command register before chip reset */
static void tg3_save_pci_state(struct tg3 *tp)
{
- u32 val;
-
- pci_read_config_dword(tp->pdev, TG3PCI_COMMAND, &val);
- tp->pci_cmd = val;
+ pci_read_config_word(tp->pdev, PCI_COMMAND, &tp->pci_cmd);
}
/* Restore PCI state after chip reset */
@@ -5054,7 +5052,7 @@ static void tg3_restore_pci_state(struct tg3 *tp)
PCISTATE_ALLOW_APE_SHMEM_WR;
pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
- pci_write_config_dword(tp->pdev, TG3PCI_COMMAND, tp->pci_cmd);
+ pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
@@ -10820,9 +10818,24 @@ out_not_found:
strcpy(tp->board_part_number, "none");
}
+static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset)
+{
+ u32 val;
+
+ if (tg3_nvram_read_swab(tp, offset, &val) ||
+ (val & 0xfc000000) != 0x0c000000 ||
+ tg3_nvram_read_swab(tp, offset + 4, &val) ||
+ val != 0)
+ return 0;
+
+ return 1;
+}
+
static void __devinit tg3_read_fw_ver(struct tg3 *tp)
{
u32 val, offset, start;
+ u32 ver_offset;
+ int i, bcnt;
if (tg3_nvram_read_swab(tp, 0, &val))
return;
@@ -10835,29 +10848,71 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
return;
offset = tg3_nvram_logical_addr(tp, offset);
- if (tg3_nvram_read_swab(tp, offset, &val))
+
+ if (!tg3_fw_img_is_valid(tp, offset) ||
+ tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
return;
- if ((val & 0xfc000000) == 0x0c000000) {
- u32 ver_offset, addr;
- int i;
+ offset = offset + ver_offset - start;
+ for (i = 0; i < 16; i += 4) {
+ if (tg3_nvram_read(tp, offset + i, &val))
+ return;
- if (tg3_nvram_read_swab(tp, offset + 4, &val) ||
- tg3_nvram_read_swab(tp, offset + 8, &ver_offset))
+ val = le32_to_cpu(val);
+ memcpy(tp->fw_ver + i, &val, 4);
+ }
+
+ if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
+ (tp->tg3_flags & TG3_FLG3_ENABLE_APE))
+ return;
+
+ for (offset = TG3_NVM_DIR_START;
+ offset < TG3_NVM_DIR_END;
+ offset += TG3_NVM_DIRENT_SIZE) {
+ if (tg3_nvram_read_swab(tp, offset, &val))
return;
- if (val != 0)
+ if ((val >> TG3_NVM_DIRTYPE_SHIFT) == TG3_NVM_DIRTYPE_ASFINI)
+ break;
+ }
+
+ if (offset == TG3_NVM_DIR_END)
+ return;
+
+ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+ start = 0x08000000;
+ else if (tg3_nvram_read_swab(tp, offset - 4, &start))
+ return;
+
+ if (tg3_nvram_read_swab(tp, offset + 4, &offset) ||
+ !tg3_fw_img_is_valid(tp, offset) ||
+ tg3_nvram_read_swab(tp, offset + 8, &val))
+ return;
+
+ offset += val - start;
+
+ bcnt = strlen(tp->fw_ver);
+
+ tp->fw_ver[bcnt++] = ',';
+ tp->fw_ver[bcnt++] = ' ';
+
+ for (i = 0; i < 4; i++) {
+ if (tg3_nvram_read(tp, offset, &val))
return;
- addr = offset + ver_offset - start;
- for (i = 0; i < 16; i += 4) {
- if (tg3_nvram_read(tp, addr + i, &val))
- return;
+ val = le32_to_cpu(val);
+ offset += sizeof(val);
- val = cpu_to_le32(val);
- memcpy(tp->fw_ver + i, &val, 4);
+ if (bcnt > TG3_VER_SIZE - sizeof(val)) {
+ memcpy(&tp->fw_ver[bcnt], &val, TG3_VER_SIZE - bcnt);
+ break;
}
+
+ memcpy(&tp->fw_ver[bcnt], &val, sizeof(val));
+ bcnt += sizeof(val);
}
+
+ tp->fw_ver[TG3_VER_SIZE - 1] = 0;
}
static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 6dbdad2b8f8..1d5b2a3dd29 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1540,6 +1540,12 @@
#define TG3_EEPROM_MAGIC_HW 0xabcd
#define TG3_EEPROM_MAGIC_HW_MSK 0xffff
+#define TG3_NVM_DIR_START 0x18
+#define TG3_NVM_DIR_END 0x78
+#define TG3_NVM_DIRENT_SIZE 0xc
+#define TG3_NVM_DIRTYPE_SHIFT 24
+#define TG3_NVM_DIRTYPE_ASFINI 1
+
/* 32K Window into NIC internal memory */
#define NIC_SRAM_WIN_BASE 0x00008000
@@ -2415,10 +2421,11 @@ struct tg3 {
#define PHY_REV_BCM5411_X0 0x1 /* Found on Netgear GA302T */
u32 led_ctrl;
- u32 pci_cmd;
+ u16 pci_cmd;
char board_part_number[24];
- char fw_ver[16];
+#define TG3_VER_SIZE 32
+ char fw_ver[TG3_VER_SIZE];
u32 nic_sram_data_cfg;
u32 pci_clock_ctrl;
struct pci_dev *pdev_peer;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index df10af7df7b..35d15e85007 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -1629,7 +1629,7 @@ tsi108_init_one(struct platform_device *pdev)
goto register_fail;
}
- printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n"
+ printk(KERN_INFO "%s: Tsi108 Gigabit Ethernet, MAC: %s\n",
dev->name, print_mac(mac, dev->dev_addr));
#ifdef DEBUG
data->msg_enable = DEBUG;
diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig
index 1c537d5a306..49d7a290dbb 100644
--- a/drivers/net/tulip/Kconfig
+++ b/drivers/net/tulip/Kconfig
@@ -67,7 +67,7 @@ config TULIP_MMIO
If in doubt, say N.
config TULIP_NAPI
- bool "Use NAPI RX polling "
+ bool "Use RX polling (NAPI)"
depends on TULIP
help
NAPI is a new driver API designed to reduce CPU and interrupt load
@@ -78,18 +78,16 @@ config TULIP_NAPI
deployed on potentially unfriendly networks (e.g. in a firewall),
then say Y here.
- See <file:Documentation/networking/NAPI_HOWTO.txt> for more
- information.
-
If in doubt, say N.
config TULIP_NAPI_HW_MITIGATION
- bool "Use Interrupt Mitigation "
+ bool "Use Interrupt Mitigation"
depends on TULIP_NAPI
---help---
- Use HW to reduce RX interrupts. Not strict necessary since NAPI reduces
- RX interrupts but itself. Although this reduces RX interrupts even at
- low levels traffic at the cost of a small latency.
+ Use HW to reduce RX interrupts. Not strictly necessary since NAPI
+ reduces RX interrupts by itself. Interrupt mitigation reduces RX
+ interrupts even at low levels of traffic at the cost of a small
+ latency.
If in doubt, say Y.
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 76e55612430..a7afeea156b 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -34,9 +34,9 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
+#include <linux/bitops.h>
#include <asm/processor.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 3c8e3b63be0..35d0cfcf8c4 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -483,7 +483,7 @@ err_out_netdev:
a delay. Note that pre-2.0.34 kernels had a cache-alignment bug that
made udelay() unreliable.
The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
- depricated.
+ deprecated.
*/
#define eeprom_delay(ee_addr) ioread32(ee_addr)
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 8dc09a3790c..5a96d74e4ce 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -71,7 +71,7 @@ config USB_PEGASUS
select MII
---help---
Say Y here if you know you have Pegasus or Pegasus-II based adapter.
- If in doubt then look at <file:drivers/usb/net/pegasus.h> for the
+ If in doubt then look at <file:drivers/net/usb/pegasus.h> for the
complete list of supported devices.
If your particular adapter is not in the list and you are _sure_ it
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 4ae05799ac4..5c4a92de9a0 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1648,7 +1648,7 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
*
* Scan the queues looking for transmitted packets that
* we can complete and clean up. Update any statistics as
- * neccessary/
+ * necessary/
*/
static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index c141a264ac4..9d9ff76a9bc 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -49,7 +49,6 @@
#include "pio.h"
#include "sysfs.h"
#include "xmit.h"
-#include "sysfs.h"
#include "lo.h"
#include "pcmcia.h"
@@ -3495,7 +3494,7 @@ static int b43_start(struct ieee80211_hw *hw)
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
int did_init = 0;
- int err;
+ int err = 0;
mutex_lock(&wl->mutex);
@@ -3521,7 +3520,7 @@ static int b43_start(struct ieee80211_hw *hw)
return err;
}
-void b43_stop(struct ieee80211_hw *hw)
+static void b43_stop(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index f0749510bcd..d09479e816c 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3306,7 +3306,7 @@ static int b43legacy_start(struct ieee80211_hw *hw)
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev;
int did_init = 0;
- int err;
+ int err = 0;
mutex_lock(&wl->mutex);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
index 8f198befba3..cb51dc51cce 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c
@@ -29,7 +29,7 @@
#include "bcm43xx_radio.h"
#include "bcm43xx.h"
-#include <asm/bitops.h>
+#include <linux/bitops.h>
static void bcm43xx_led_changestate(struct bcm43xx_led *led)
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
index 9ecf2bf0d25..47c135a7f4d 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -87,7 +87,7 @@ void bcm43xx_generate_txhdr(struct bcm43xx_private *bcm,
/* RX header as received from the hardware. */
struct bcm43xx_rxhdr {
- /* Frame Length. Must be generated explicitely in PIO mode. */
+ /* Frame Length. Must be generated explicitly in PIO mode. */
__le16 frame_length;
PAD_BYTES(2);
/* Flags field 1 */
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index ceb7f1e5e9e..517f8984514 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -4,9 +4,6 @@
#include <linux/types.h>
#include <linux/if_ether.h>
-#define BIT(x) (1 << (x))
-
-
/* IEEE 802.11 defines */
/* Information Element IDs */
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 40f516d42c5..d8f5efcfcab 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -2920,7 +2920,7 @@ static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i)
printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor "
"- update software to use iwconfig mode monitor\n",
- dev->name, current->pid, current->comm);
+ dev->name, task_pid_nr(current), current->comm);
/* Backward compatibility code - this can be removed at some point */
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2d46a16c094..a6c7904de28 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1858,14 +1858,6 @@ static void ipw2100_down(struct ipw2100_priv *priv)
modify_acceptable_latency("ipw2100", INFINITE_LATENCY);
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
- if (priv->config & CFG_C3_DISABLED) {
- IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
- acpi_set_cstate_limit(priv->cstate_limit);
- priv->config &= ~CFG_C3_DISABLED;
- }
-#endif
-
/* We have to signal any supplicant if we are disassociating */
if (associated)
wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
@@ -2091,26 +2083,52 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
/* RF_KILL is now enabled (else we wouldn't be here) */
priv->status |= STATUS_RF_KILL_HW;
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
- if (priv->config & CFG_C3_DISABLED) {
- IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
- acpi_set_cstate_limit(priv->cstate_limit);
- priv->config &= ~CFG_C3_DISABLED;
- }
-#endif
-
/* Make sure the RF Kill check timer is running */
priv->stop_rf_kill = 0;
cancel_delayed_work(&priv->rf_kill);
queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
}
+static void send_scan_event(void *data)
+{
+ struct ipw2100_priv *priv = data;
+ union iwreq_data wrqu;
+
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);
+}
+
+static void ipw2100_scan_event_later(struct work_struct *work)
+{
+ send_scan_event(container_of(work, struct ipw2100_priv,
+ scan_event_later.work));
+}
+
+static void ipw2100_scan_event_now(struct work_struct *work)
+{
+ send_scan_event(container_of(work, struct ipw2100_priv,
+ scan_event_now));
+}
+
static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
{
IPW_DEBUG_SCAN("scan complete\n");
/* Age the scan results... */
priv->ieee->scans++;
priv->status &= ~STATUS_SCANNING;
+
+ /* Only userspace-requested scan completion events go out immediately */
+ if (!priv->user_requested_scan) {
+ if (!delayed_work_pending(&priv->scan_event_later))
+ queue_delayed_work(priv->workqueue,
+ &priv->scan_event_later,
+ round_jiffies(msecs_to_jiffies(4000)));
+ } else {
+ priv->user_requested_scan = 0;
+ cancel_delayed_work(&priv->scan_event_later);
+ queue_work(priv->workqueue, &priv->scan_event_now);
+ }
}
#ifdef CONFIG_IPW2100_DEBUG
@@ -2329,23 +2347,10 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
u32 match, reg;
int j;
#endif
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
- int limit;
-#endif
IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
i * sizeof(struct ipw2100_status));
-#ifdef ACPI_CSTATE_LIMIT_DEFINED
- IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
- limit = acpi_get_cstate_limit();
- if (limit > 2) {
- priv->cstate_limit = limit;
- acpi_set_cstate_limit(2);
- priv->config |= CFG_C3_DISABLED;
- }
-#endif
-
#ifdef IPW2100_DEBUG_C3
/* Halt the fimrware so we can get a good image */
write_register(priv->net_dev, IPW_REG_RESET_REG,
@@ -4378,6 +4383,7 @@ static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
cancel_delayed_work(&priv->wx_event_work);
cancel_delayed_work(&priv->hang_check);
cancel_delayed_work(&priv->rf_kill);
+ cancel_delayed_work(&priv->scan_event_later);
destroy_workqueue(priv->workqueue);
priv->workqueue = NULL;
}
@@ -6041,7 +6047,7 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
* ends up causing problems. So, we just handle
* the WX extensions through the ipw2100_ioctl interface */
- /* memset() puts everything to 0, so we only have explicitely set
+ /* memset() puts everything to 0, so we only have explicitly set
* those values that need to be something else */
/* If power management is turned on, default to AUTO mode */
@@ -6121,6 +6127,8 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
INIT_DELAYED_WORK(&priv->wx_event_work, ipw2100_wx_event_work);
INIT_DELAYED_WORK(&priv->hang_check, ipw2100_hang_check);
INIT_DELAYED_WORK(&priv->rf_kill, ipw2100_rf_kill);
+ INIT_WORK(&priv->scan_event_now, ipw2100_scan_event_now);
+ INIT_DELAYED_WORK(&priv->scan_event_later, ipw2100_scan_event_later);
tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
ipw2100_irq_tasklet, (unsigned long)priv);
@@ -7425,6 +7433,8 @@ static int ipw2100_wx_set_scan(struct net_device *dev,
}
IPW_DEBUG_WX("Initiating scan...\n");
+
+ priv->user_requested_scan = 1;
if (ipw2100_set_scan_options(priv) || ipw2100_start_scan(priv)) {
IPW_DEBUG_WX("Start scan failed.\n");
@@ -7499,7 +7509,7 @@ static int ipw2100_wx_set_power(struct net_device *dev,
switch (wrqu->power.flags & IW_POWER_MODE) {
case IW_POWER_ON: /* If not specified */
case IW_POWER_MODE: /* If set all mask */
- case IW_POWER_ALL_R: /* If explicitely state all */
+ case IW_POWER_ALL_R: /* If explicitly state all */
break;
default: /* Otherwise we don't support it */
IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index de7d384d38a..bbf1ddcafba 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -479,7 +479,6 @@ enum {
#define CFG_ASSOCIATE (1<<6)
#define CFG_FIXED_RATE (1<<7)
#define CFG_ADHOC_CREATE (1<<8)
-#define CFG_C3_DISABLED (1<<9)
#define CFG_PASSIVE_SCAN (1<<10)
#ifdef CONFIG_IPW2100_MONITOR
#define CFG_CRC_CHECK (1<<11)
@@ -508,7 +507,6 @@ struct ipw2100_priv {
u8 bssid[ETH_ALEN];
u8 channel;
int last_mode;
- int cstate_limit;
unsigned long connect_start;
unsigned long last_reset;
@@ -588,6 +586,10 @@ struct ipw2100_priv {
struct delayed_work wx_event_work;
struct delayed_work hang_check;
struct delayed_work rf_kill;
+ struct work_struct scan_event_now;
+ struct delayed_work scan_event_later;
+
+ int user_requested_scan;
u32 interrupts;
int tx_interrupts;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index feb8fcbab2d..e3c828401b9 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -9603,7 +9603,7 @@ static int ipw_wx_set_power(struct net_device *dev,
switch (wrqu->power.flags & IW_POWER_MODE) {
case IW_POWER_ON: /* If not specified */
case IW_POWER_MODE: /* If set all mask */
- case IW_POWER_ALL_R: /* If explicitely state all */
+ case IW_POWER_ALL_R: /* If explicitly state all */
break;
default: /* Otherwise we don't support it */
IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index f4aabcf480e..262ab0b5582 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -37,9 +37,6 @@
#include <linux/workqueue.h>
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
#define IWL 3945
#include "../net/mac80211/ieee80211_rate.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index acb38750535..19bcb01e278 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -38,7 +38,6 @@
#include <net/mac80211.h>
#include <linux/etherdevice.h>
-#include <linux/delay.h>
#define IWL 3945
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 287c75705c4..8dc78c0bf1f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -36,9 +36,6 @@
#include <linux/workqueue.h>
-#include <net/mac80211.h>
-#include <linux/wireless.h>
-
#define IWL 4965
#include "../net/mac80211/ieee80211_rate.h"
@@ -2024,12 +2021,18 @@ static int open_file_generic(struct inode *inode, struct file *file)
static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
struct iwl_rate *mcs, int index)
{
- const u32 cck_rate = 0x820A;
+ u32 base_rate;
+
+ if (rs_priv->phymode == (u8) MODE_IEEE80211A)
+ base_rate = 0x800D;
+ else
+ base_rate = 0x820A;
+
if (rs_priv->dbg_fixed.rate_n_flags) {
if (index < 12)
mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
else
- mcs->rate_n_flags = cck_rate;
+ mcs->rate_n_flags = base_rate;
IWL_DEBUG_RATE("Fixed rate ON\n");
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b50d20267c8..557deebca1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -35,9 +35,7 @@
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <net/mac80211.h>
-#include <linux/netdevice.h>
#include <linux/etherdevice.h>
-#include <linux/delay.h>
#define IWL 4965
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 75e3b5c3f15..83019d1d7cc 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -48,8 +48,6 @@
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
@@ -1749,21 +1747,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv)
* return : set the bit for each supported rate insert in ie
*/
static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int max_count)
+ u16 basic_rate, int *left)
{
u16 ret_rates = 0, bit;
int i;
- u8 *rates;
-
- rates = &(ie[1]);
+ u8 *cnt = ie;
+ u8 *rates = ie + 1;
for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
if (bit & supported_rate) {
ret_rates |= bit;
- rates[*ie] = iwl_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- *ie = *ie + 1;
- if (*ie >= max_count)
+ rates[*cnt] = iwl_rates[i].ieee |
+ ((bit & basic_rate) ? 0x80 : 0x00);
+ (*cnt)++;
+ (*left)--;
+ if ((*left <= 0) ||
+ (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
break;
}
}
@@ -1780,7 +1779,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
{
int len = 0;
u8 *pos = NULL;
- u16 ret_rates;
+ u16 active_rates, ret_rates, cck_rates;
/* Make sure there is enough space for the probe request,
* two mandatory IEs and the data */
@@ -1825,19 +1824,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
left -= 2;
if (left < 0)
return 0;
+
/* ... fill it in... */
*pos++ = WLAN_EID_SUPP_RATES;
*pos = 0;
- ret_rates = priv->active_rate = priv->rates_mask;
+
+ priv->active_rate = priv->rates_mask;
+ active_rates = priv->active_rate;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
- iwl_supported_rate_to_ie(pos, priv->active_rate,
- priv->active_rate_basic, left);
+ cck_rates = IWL_CCK_RATES_MASK & active_rates;
+ ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+ priv->active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+ priv->active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
len += 2 + *pos;
pos += (*pos) + 1;
- ret_rates = ~ret_rates & priv->active_rate;
-
- if (ret_rates == 0)
+ if (active_rates == 0)
goto fill_end;
/* fill in supported extended rate */
@@ -1848,7 +1855,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
/* ... fill it in... */
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos = 0;
- iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+ iwl_supported_rate_to_ie(pos, active_rates,
+ priv->active_rate_basic, &left);
if (*pos > 0)
len += 2 + *pos;
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index b1a6e39f782..5e1279263b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -48,8 +48,6 @@
#include <linux/netdevice.h>
#include <linux/wireless.h>
#include <linux/firmware.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
@@ -1802,21 +1800,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv)
* return : set the bit for each supported rate insert in ie
*/
static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int max_count)
+ u16 basic_rate, int *left)
{
u16 ret_rates = 0, bit;
int i;
- u8 *rates;
-
- rates = &(ie[1]);
+ u8 *cnt = ie;
+ u8 *rates = ie + 1;
for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
if (bit & supported_rate) {
ret_rates |= bit;
- rates[*ie] = iwl_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- *ie = *ie + 1;
- if (*ie >= max_count)
+ rates[*cnt] = iwl_rates[i].ieee |
+ ((bit & basic_rate) ? 0x80 : 0x00);
+ (*cnt)++;
+ (*left)--;
+ if ((*left <= 0) ||
+ (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
break;
}
}
@@ -1839,7 +1838,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
{
int len = 0;
u8 *pos = NULL;
- u16 ret_rates;
+ u16 active_rates, ret_rates, cck_rates;
/* Make sure there is enough space for the probe request,
* two mandatory IEs and the data */
@@ -1884,19 +1883,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
left -= 2;
if (left < 0)
return 0;
+
/* ... fill it in... */
*pos++ = WLAN_EID_SUPP_RATES;
*pos = 0;
- ret_rates = priv->active_rate = priv->rates_mask;
+
+ priv->active_rate = priv->rates_mask;
+ active_rates = priv->active_rate;
priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
- iwl_supported_rate_to_ie(pos, priv->active_rate,
- priv->active_rate_basic, left);
+ cck_rates = IWL_CCK_RATES_MASK & active_rates;
+ ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
+ priv->active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
+ ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
+ priv->active_rate_basic, &left);
+ active_rates &= ~ret_rates;
+
len += 2 + *pos;
pos += (*pos) + 1;
- ret_rates = ~ret_rates & priv->active_rate;
-
- if (ret_rates == 0)
+ if (active_rates == 0)
goto fill_end;
/* fill in supported extended rate */
@@ -1907,7 +1914,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,
/* ... fill it in... */
*pos++ = WLAN_EID_EXT_SUPP_RATES;
*pos = 0;
- iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left);
+ iwl_supported_rate_to_ie(pos, active_rates,
+ priv->active_rate_basic, &left);
if (*pos > 0)
len += 2 + *pos;
@@ -4494,13 +4502,13 @@ static u8 ratio2dB[100] = {
* Conversion assumes that levels are voltages (20*log), not powers (10*log). */
int iwl_calc_db_from_ratio(int sig_ratio)
{
- /* Anything above 1000:1 just report as 60 dB */
- if (sig_ratio > 1000)
+ /* 1000:1 or higher just report as 60 dB */
+ if (sig_ratio >= 1000)
return 60;
- /* Above 100:1, divide by 10 and use table,
+ /* 100:1 or higher, divide by 10 and use table,
* add 20 dB to make up for divide by 10 */
- if (sig_ratio > 100)
+ if (sig_ratio >= 100)
return (20 + (int)ratio2dB[sig_ratio/10]);
/* We shouldn't see this */
diff --git a/drivers/net/wireless/iwlwifi/iwlwifi.h b/drivers/net/wireless/iwlwifi/iwlwifi.h
index e0b97c34121..432ce887807 100644
--- a/drivers/net/wireless/iwlwifi/iwlwifi.h
+++ b/drivers/net/wireless/iwlwifi/iwlwifi.h
@@ -39,18 +39,13 @@ struct iwl_priv;
/* Hardware specific file defines the PCI IDs table for that hardware module */
extern struct pci_device_id iwl_hw_card_ids[];
+#include "iwl-hw.h"
#if IWL == 3945
-
#define DRV_NAME "iwl3945"
-#include "iwl-hw.h"
#include "iwl-3945-hw.h"
-
#elif IWL == 4965
-
#define DRV_NAME "iwl4965"
-#include "iwl-hw.h"
#include "iwl-4965-hw.h"
-
#endif
#include "iwl-prph.h"
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index c2d71afd57e..2402cb8dd32 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -4,18 +4,18 @@
* Version: 0.4.1
* Description: Netwave AirSurfer Wireless LAN PC Card driver
* Status: Experimental.
- * Authors: John Markus Bjrndalen <johnm@cs.uit.no>
+ * Authors: John Markus Bjørndalen <johnm@cs.uit.no>
* Dag Brattli <dagb@cs.uit.no>
* David Hinds <dahinds@users.sourceforge.net>
* Created at: A long time ago!
* Modified at: Mon Nov 10 11:54:37 1997
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
- * Copyright (c) 1997 University of Troms, Norway
+ * Copyright (c) 1997 University of Tromsø, Norway
*
* Revision History:
*
- * 08-Nov-97 15:14:47 John Markus Bjrndalen <johnm@cs.uit.no>
+ * 08-Nov-97 15:14:47 John Markus Bjørndalen <johnm@cs.uit.no>
* - Fixed some bugs in netwave_rx and cleaned it up a bit.
* (One of the bugs would have destroyed packets when receiving
* multiple packets per interrupt).
@@ -158,7 +158,7 @@ static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version =
-"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjrndalen)\n";
+"netwave_cs.c 0.3.0 Thu Jul 17 14:36:02 1997 (John Markus Bjørndalen)\n";
#else
#define DEBUG(n, args...)
#endif
diff --git a/drivers/net/wireless/p54common.c b/drivers/net/wireless/p54common.c
index 2c63cf0ad2c..1437db0cf4b 100644
--- a/drivers/net/wireless/p54common.c
+++ b/drivers/net/wireless/p54common.c
@@ -577,7 +577,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
struct p54_tx_control_filter *filter;
hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
- priv->tx_hdr_len, GFP_KERNEL);
+ priv->tx_hdr_len, GFP_ATOMIC);
if (!hdr)
return -ENOMEM;
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index bb6f46cfbb9..ff399f8083e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -550,7 +550,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
/*
* Check if we need to set the Length Extension
*/
- if (bitrate == 110 && residual <= 3)
+ if (bitrate == 110 && residual <= 30)
desc.service |= 0x80;
}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 3e42759473c..46c8c0840a6 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2029,6 +2029,7 @@ static struct usb_device_id rt73usb_device_table[] = {
{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
{ USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
+ { USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
/* Billionton */
{ USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
/* Buffalo */
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index 0ef887dd286..de61c8fe649 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -131,7 +131,8 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
struct rtl8187_tx_hdr *hdr;
struct rtl8187_tx_info *info;
struct urb *urb;
- u32 tmp;
+ __le16 rts_dur = 0;
+ u32 flags;
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
@@ -139,24 +140,24 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
return 0;
}
- hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
- tmp = skb->len - sizeof(*hdr);
- tmp |= RTL8187_TX_FLAG_NO_ENCRYPT;
- tmp |= control->rts_cts_rate << 19;
- tmp |= control->tx_rate << 24;
- if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb))
- tmp |= RTL8187_TX_FLAG_MORE_FRAG;
+ flags = skb->len;
+ flags |= RTL8187_TX_FLAG_NO_ENCRYPT;
+ flags |= control->rts_cts_rate << 19;
+ flags |= control->tx_rate << 24;
+ if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data))
+ flags |= RTL8187_TX_FLAG_MORE_FRAG;
if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) {
- tmp |= RTL8187_TX_FLAG_RTS;
- hdr->rts_duration =
- ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
+ flags |= RTL8187_TX_FLAG_RTS;
+ rts_dur = ieee80211_rts_duration(dev, priv->if_id, skb->len, control);
}
if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)
- tmp |= RTL8187_TX_FLAG_CTS;
- hdr->flags = cpu_to_le32(tmp);
+ flags |= RTL8187_TX_FLAG_CTS;
+
+ hdr = (struct rtl8187_tx_hdr *)skb_push(skb, sizeof(*hdr));
+ hdr->flags = cpu_to_le32(flags);
hdr->len = 0;
- tmp = control->retry_limit << 8;
- hdr->retry = cpu_to_le32(tmp);
+ hdr->rts_duration = rts_dur;
+ hdr->retry = cpu_to_le32(control->retry_limit << 8);
info = (struct rtl8187_tx_info *)skb->cb;
info->control = kmemdup(control, sizeof(*control), GFP_ATOMIC);
@@ -587,8 +588,6 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
*total_flags = 0;
- if (changed_flags & FIF_PROMISC_IN_BSS)
- priv->rx_conf ^= RTL818X_RX_CONF_NICMAC;
if (changed_flags & FIF_ALLMULTI)
priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST;
if (changed_flags & FIF_FCSFAIL)
@@ -601,8 +600,6 @@ static void rtl8187_configure_filter(struct ieee80211_hw *dev,
if (mc_count > 0)
priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
- if (priv->rx_conf & RTL818X_RX_CONF_NICMAC)
- *total_flags |= FIF_PROMISC_IN_BSS;
if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
*total_flags |= FIF_ALLMULTI;
if (priv->rx_conf & RTL818X_RX_CONF_FCS)
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index 935b144d9b5..d5c0c66188c 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -327,8 +327,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 6), &data[datalen-8], 6);
memcpy(skb_put(skb, 2), &data[datalen-24], 2);
memcpy(skb_put(skb, len), data, len);
- skb->dev->last_rx = jiffies;
skb->protocol = eth_type_trans(skb, zd->dev);
+ skb->dev->last_rx = jiffies;
zd->stats.rx_packets++;
zd->stats.rx_bytes += skb->len;
netif_rx(skb);
@@ -384,8 +384,8 @@ static void zd1201_usbrx(struct urb *urb)
memcpy(skb_put(skb, 2), &data[6], 2);
memcpy(skb_put(skb, len), data+8, len);
}
- skb->dev->last_rx = jiffies;
skb->protocol = eth_type_trans(skb, zd->dev);
+ skb->dev->last_rx = jiffies;
zd->stats.rx_packets++;
zd->stats.rx_bytes += skb->len;
netif_rx(skb);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index b0684f96576..c755b692381 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -1044,14 +1044,17 @@ error:
static void disconnect(struct usb_interface *intf)
{
struct net_device *netdev = zd_intf_to_netdev(intf);
- struct zd_mac *mac = zd_netdev_mac(netdev);
- struct zd_usb *usb = &mac->chip.usb;
+ struct zd_mac *mac;
+ struct zd_usb *usb;
/* Either something really bad happened, or we're just dealing with
* a DEVICE_INSTALLER. */
if (netdev == NULL)
return;
+ mac = zd_netdev_mac(netdev);
+ usb = &mac->chip.usb;
+
dev_dbg_f(zd_usb_dev(usb), "\n");
zd_netdev_disconnect(netdev);
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 5b86ee5c1ee..5eace9e66e1 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -557,44 +557,6 @@ lba_bios_init(void)
#ifdef CONFIG_64BIT
/*
-** Determine if a device is already configured.
-** If so, reserve it resources.
-**
-** Read PCI cfg command register and see if I/O or MMIO is enabled.
-** PAT has to enable the devices it's using.
-**
-** Note: resources are fixed up before we try to claim them.
-*/
-static void
-lba_claim_dev_resources(struct pci_dev *dev)
-{
- u16 cmd;
- int i, srch_flags;
-
- (void) pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
- srch_flags = (cmd & PCI_COMMAND_IO) ? IORESOURCE_IO : 0;
- if (cmd & PCI_COMMAND_MEMORY)
- srch_flags |= IORESOURCE_MEM;
-
- if (!srch_flags)
- return;
-
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- if (dev->resource[i].flags & srch_flags) {
- pci_claim_resource(dev, i);
- DBG(" claimed %s %d [%lx,%lx]/%lx\n",
- pci_name(dev), i,
- dev->resource[i].start,
- dev->resource[i].end,
- dev->resource[i].flags
- );
- }
- }
-}
-
-
-/*
* truncate_pat_collision: Deal with overlaps or outright collisions
* between PAT PDC reported ranges.
*
@@ -653,7 +615,6 @@ truncate_pat_collision(struct resource *root, struct resource *new)
}
#else
-#define lba_claim_dev_resources(dev) do { } while (0)
#define truncate_pat_collision(r,n) (0)
#endif
@@ -684,8 +645,12 @@ lba_fixup_bus(struct pci_bus *bus)
** pci_alloc_primary_bus() mangles this.
*/
if (bus->self) {
+ int i;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
+ for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+ pci_claim_resource(bus->self, i);
+ }
} else {
/* Host-PCI Bridge */
int err, i;
@@ -803,6 +768,9 @@ lba_fixup_bus(struct pci_bus *bus)
DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
res->flags, res->start, res->end);
}
+ if ((i != PCI_ROM_RESOURCE) ||
+ (res->flags & IORESOURCE_ROM_ENABLE))
+ pci_claim_resource(dev, i);
}
#ifdef FBB_SUPPORT
@@ -814,11 +782,6 @@ lba_fixup_bus(struct pci_bus *bus)
bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK);
#endif
- if (is_pdc_pat()) {
- /* Claim resources for PDC's devices */
- lba_claim_dev_resources(dev);
- }
-
/*
** P2PB's have no IRQs. ignore them.
*/
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c
index fc4bde259dc..ebb09e98d21 100644
--- a/drivers/parisc/pdc_stable.c
+++ b/drivers/parisc/pdc_stable.c
@@ -282,6 +282,7 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
unsigned short i;
char in[count+1], *temp;
struct device *dev;
+ int ret;
if (!entry || !buf || !count)
return -EINVAL;
@@ -333,7 +334,9 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun
/* Update the symlink to the real device */
sysfs_remove_link(&entry->kobj, "device");
- sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ WARN_ON(ret);
+
write_unlock(&entry->rw_lock);
printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
@@ -1003,8 +1006,10 @@ pdcs_register_pathentries(void)
entry->ready = 2;
/* Add a nice symlink to the real device */
- if (entry->dev)
- sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ if (entry->dev) {
+ err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
+ WARN_ON(err);
+ }
write_unlock(&entry->rw_lock);
}
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index d044c48323e..e5c323936ea 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1909,8 +1909,8 @@ sba_driver_callback(struct parisc_device *dev)
global_ioc_cnt *= 2;
}
- printk(KERN_INFO "%s found %s at 0x%lx\n",
- MODULE_NAME, version, dev->hpa.start);
+ printk(KERN_INFO "%s found %s at 0x%llx\n",
+ MODULE_NAME, version, (unsigned long long)dev->hpa.start);
sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL);
if (!sba_dev) {
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 38cdf9fa36a..1e8d2d17f04 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -155,6 +155,7 @@ superio_init(struct pci_dev *pcidev)
struct superio_device *sio = &sio_dev;
struct pci_dev *pdev = sio->lio_pdev;
u16 word;
+ int ret;
if (sio->suckyio_irq_enabled)
return;
@@ -200,7 +201,8 @@ superio_init(struct pci_dev *pcidev)
pci_write_config_word (pdev, PCI_COMMAND, word);
pci_set_master (pdev);
- pci_enable_device(pdev);
+ ret = pci_enable_device(pdev);
+ BUG_ON(ret < 0); /* not too much we can do about this... */
/*
* Next project is programming the onboard interrupt controllers.
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 006054a4099..55505565073 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -20,6 +20,9 @@ obj-$(CONFIG_PCI_MSI) += msi.o
# Build the Hypertransport interrupt support
obj-$(CONFIG_HT_IRQ) += htirq.o
+# Build Intel IOMMU support
+obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
+
#
# Some architectures use the generic PCI setup functions
#
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
new file mode 100644
index 00000000000..5dfdfdac92e
--- /dev/null
+++ b/drivers/pci/dmar.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ * This file implements early detection/parsing of DMA Remapping Devices
+ * reported to OS through BIOS via DMA remapping reporting (DMAR) ACPI
+ * tables.
+ */
+
+#include <linux/pci.h>
+#include <linux/dmar.h>
+
+#undef PREFIX
+#define PREFIX "DMAR:"
+
+/* No locks are needed as DMA remapping hardware unit
+ * list is constructed at boot time and hotplug of
+ * these units are not supported by the architecture.
+ */
+LIST_HEAD(dmar_drhd_units);
+LIST_HEAD(dmar_rmrr_units);
+
+static struct acpi_table_header * __initdata dmar_tbl;
+
+static void __init dmar_register_drhd_unit(struct dmar_drhd_unit *drhd)
+{
+ /*
+ * add INCLUDE_ALL at the tail, so scan the list will find it at
+ * the very end.
+ */
+ if (drhd->include_all)
+ list_add_tail(&drhd->list, &dmar_drhd_units);
+ else
+ list_add(&drhd->list, &dmar_drhd_units);
+}
+
+static void __init dmar_register_rmrr_unit(struct dmar_rmrr_unit *rmrr)
+{
+ list_add(&rmrr->list, &dmar_rmrr_units);
+}
+
+static int __init dmar_parse_one_dev_scope(struct acpi_dmar_device_scope *scope,
+ struct pci_dev **dev, u16 segment)
+{
+ struct pci_bus *bus;
+ struct pci_dev *pdev = NULL;
+ struct acpi_dmar_pci_path *path;
+ int count;
+
+ bus = pci_find_bus(segment, scope->bus);
+ path = (struct acpi_dmar_pci_path *)(scope + 1);
+ count = (scope->length - sizeof(struct acpi_dmar_device_scope))
+ / sizeof(struct acpi_dmar_pci_path);
+
+ while (count) {
+ if (pdev)
+ pci_dev_put(pdev);
+ /*
+ * Some BIOSes list non-exist devices in DMAR table, just
+ * ignore it
+ */
+ if (!bus) {
+ printk(KERN_WARNING
+ PREFIX "Device scope bus [%d] not found\n",
+ scope->bus);
+ break;
+ }
+ pdev = pci_get_slot(bus, PCI_DEVFN(path->dev, path->fn));
+ if (!pdev) {
+ printk(KERN_WARNING PREFIX
+ "Device scope device [%04x:%02x:%02x.%02x] not found\n",
+ segment, bus->number, path->dev, path->fn);
+ break;
+ }
+ path ++;
+ count --;
+ bus = pdev->subordinate;
+ }
+ if (!pdev) {
+ printk(KERN_WARNING PREFIX
+ "Device scope device [%04x:%02x:%02x.%02x] not found\n",
+ segment, scope->bus, path->dev, path->fn);
+ *dev = NULL;
+ return 0;
+ }
+ if ((scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT && \
+ pdev->subordinate) || (scope->entry_type == \
+ ACPI_DMAR_SCOPE_TYPE_BRIDGE && !pdev->subordinate)) {
+ pci_dev_put(pdev);
+ printk(KERN_WARNING PREFIX
+ "Device scope type does not match for %s\n",
+ pci_name(pdev));
+ return -EINVAL;
+ }
+ *dev = pdev;
+ return 0;
+}
+
+static int __init dmar_parse_dev_scope(void *start, void *end, int *cnt,
+ struct pci_dev ***devices, u16 segment)
+{
+ struct acpi_dmar_device_scope *scope;
+ void * tmp = start;
+ int index;
+ int ret;
+
+ *cnt = 0;
+ while (start < end) {
+ scope = start;
+ if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+ scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
+ (*cnt)++;
+ else
+ printk(KERN_WARNING PREFIX
+ "Unsupported device scope\n");
+ start += scope->length;
+ }
+ if (*cnt == 0)
+ return 0;
+
+ *devices = kcalloc(*cnt, sizeof(struct pci_dev *), GFP_KERNEL);
+ if (!*devices)
+ return -ENOMEM;
+
+ start = tmp;
+ index = 0;
+ while (start < end) {
+ scope = start;
+ if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
+ scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) {
+ ret = dmar_parse_one_dev_scope(scope,
+ &(*devices)[index], segment);
+ if (ret) {
+ kfree(*devices);
+ return ret;
+ }
+ index ++;
+ }
+ start += scope->length;
+ }
+
+ return 0;
+}
+
+/**
+ * dmar_parse_one_drhd - parses exactly one DMA remapping hardware definition
+ * structure which uniquely represent one DMA remapping hardware unit
+ * present in the platform
+ */
+static int __init
+dmar_parse_one_drhd(struct acpi_dmar_header *header)
+{
+ struct acpi_dmar_hardware_unit *drhd;
+ struct dmar_drhd_unit *dmaru;
+ int ret = 0;
+ static int include_all;
+
+ dmaru = kzalloc(sizeof(*dmaru), GFP_KERNEL);
+ if (!dmaru)
+ return -ENOMEM;
+
+ drhd = (struct acpi_dmar_hardware_unit *)header;
+ dmaru->reg_base_addr = drhd->address;
+ dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
+
+ if (!dmaru->include_all)
+ ret = dmar_parse_dev_scope((void *)(drhd + 1),
+ ((void *)drhd) + header->length,
+ &dmaru->devices_cnt, &dmaru->devices,
+ drhd->segment);
+ else {
+ /* Only allow one INCLUDE_ALL */
+ if (include_all) {
+ printk(KERN_WARNING PREFIX "Only one INCLUDE_ALL "
+ "device scope is allowed\n");
+ ret = -EINVAL;
+ }
+ include_all = 1;
+ }
+
+ if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all))
+ kfree(dmaru);
+ else
+ dmar_register_drhd_unit(dmaru);
+ return ret;
+}
+
+static int __init
+dmar_parse_one_rmrr(struct acpi_dmar_header *header)
+{
+ struct acpi_dmar_reserved_memory *rmrr;
+ struct dmar_rmrr_unit *rmrru;
+ int ret = 0;
+
+ rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
+ if (!rmrru)
+ return -ENOMEM;
+
+ rmrr = (struct acpi_dmar_reserved_memory *)header;
+ rmrru->base_address = rmrr->base_address;
+ rmrru->end_address = rmrr->end_address;
+ ret = dmar_parse_dev_scope((void *)(rmrr + 1),
+ ((void *)rmrr) + header->length,
+ &rmrru->devices_cnt, &rmrru->devices, rmrr->segment);
+
+ if (ret || (rmrru->devices_cnt == 0))
+ kfree(rmrru);
+ else
+ dmar_register_rmrr_unit(rmrru);
+ return ret;
+}
+
+static void __init
+dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
+{
+ struct acpi_dmar_hardware_unit *drhd;
+ struct acpi_dmar_reserved_memory *rmrr;
+
+ switch (header->type) {
+ case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+ drhd = (struct acpi_dmar_hardware_unit *)header;
+ printk (KERN_INFO PREFIX
+ "DRHD (flags: 0x%08x)base: 0x%016Lx\n",
+ drhd->flags, drhd->address);
+ break;
+ case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+ rmrr = (struct acpi_dmar_reserved_memory *)header;
+
+ printk (KERN_INFO PREFIX
+ "RMRR base: 0x%016Lx end: 0x%016Lx\n",
+ rmrr->base_address, rmrr->end_address);
+ break;
+ }
+}
+
+/**
+ * parse_dmar_table - parses the DMA reporting table
+ */
+static int __init
+parse_dmar_table(void)
+{
+ struct acpi_table_dmar *dmar;
+ struct acpi_dmar_header *entry_header;
+ int ret = 0;
+
+ dmar = (struct acpi_table_dmar *)dmar_tbl;
+ if (!dmar)
+ return -ENODEV;
+
+ if (!dmar->width) {
+ printk (KERN_WARNING PREFIX "Zero: Invalid DMAR haw\n");
+ return -EINVAL;
+ }
+
+ printk (KERN_INFO PREFIX "Host address width %d\n",
+ dmar->width + 1);
+
+ entry_header = (struct acpi_dmar_header *)(dmar + 1);
+ while (((unsigned long)entry_header) <
+ (((unsigned long)dmar) + dmar_tbl->length)) {
+ dmar_table_print_dmar_entry(entry_header);
+
+ switch (entry_header->type) {
+ case ACPI_DMAR_TYPE_HARDWARE_UNIT:
+ ret = dmar_parse_one_drhd(entry_header);
+ break;
+ case ACPI_DMAR_TYPE_RESERVED_MEMORY:
+ ret = dmar_parse_one_rmrr(entry_header);
+ break;
+ default:
+ printk(KERN_WARNING PREFIX
+ "Unknown DMAR structure type\n");
+ ret = 0; /* for forward compatibility */
+ break;
+ }
+ if (ret)
+ break;
+
+ entry_header = ((void *)entry_header + entry_header->length);
+ }
+ return ret;
+}
+
+
+int __init dmar_table_init(void)
+{
+
+ parse_dmar_table();
+ if (list_empty(&dmar_drhd_units)) {
+ printk(KERN_INFO PREFIX "No DMAR devices found\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+/**
+ * early_dmar_detect - checks to see if the platform supports DMAR devices
+ */
+int __init early_dmar_detect(void)
+{
+ acpi_status status = AE_OK;
+
+ /* if we could find DMAR table, then there are DMAR devices */
+ status = acpi_get_table(ACPI_SIG_DMAR, 0,
+ (struct acpi_table_header **)&dmar_tbl);
+
+ if (ACPI_SUCCESS(status) && !dmar_tbl) {
+ printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
+ status = AE_NOT_FOUND;
+ }
+
+ return (ACPI_SUCCESS(status) ? 1 : 0);
+}
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
new file mode 100644
index 00000000000..b3d70310af4
--- /dev/null
+++ b/drivers/pci/intel-iommu.c
@@ -0,0 +1,2271 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+#include <linux/dmar.h>
+#include <linux/dma-mapping.h>
+#include <linux/mempool.h>
+#include "iova.h"
+#include "intel-iommu.h"
+#include <asm/proto.h> /* force_iommu in this header in x86-64*/
+#include <asm/cacheflush.h>
+#include <asm/iommu.h>
+#include "pci.h"
+
+#define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
+#define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+
+#define IOAPIC_RANGE_START (0xfee00000)
+#define IOAPIC_RANGE_END (0xfeefffff)
+#define IOVA_START_ADDR (0x1000)
+
+#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
+
+#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+
+#define DOMAIN_MAX_ADDR(gaw) ((((u64)1) << gaw) - 1)
+
+static void domain_remove_dev_info(struct dmar_domain *domain);
+
+static int dmar_disabled;
+static int __initdata dmar_map_gfx = 1;
+static int dmar_forcedac;
+
+#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
+static DEFINE_SPINLOCK(device_domain_lock);
+static LIST_HEAD(device_domain_list);
+
+static int __init intel_iommu_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+ while (*str) {
+ if (!strncmp(str, "off", 3)) {
+ dmar_disabled = 1;
+ printk(KERN_INFO"Intel-IOMMU: disabled\n");
+ } else if (!strncmp(str, "igfx_off", 8)) {
+ dmar_map_gfx = 0;
+ printk(KERN_INFO
+ "Intel-IOMMU: disable GFX device mapping\n");
+ } else if (!strncmp(str, "forcedac", 8)) {
+ printk (KERN_INFO
+ "Intel-IOMMU: Forcing DAC for PCI devices\n");
+ dmar_forcedac = 1;
+ }
+
+ str += strcspn(str, ",");
+ while (*str == ',')
+ str++;
+ }
+ return 0;
+}
+__setup("intel_iommu=", intel_iommu_setup);
+
+static struct kmem_cache *iommu_domain_cache;
+static struct kmem_cache *iommu_devinfo_cache;
+static struct kmem_cache *iommu_iova_cache;
+
+static inline void *iommu_kmem_cache_alloc(struct kmem_cache *cachep)
+{
+ unsigned int flags;
+ void *vaddr;
+
+ /* trying to avoid low memory issues */
+ flags = current->flags & PF_MEMALLOC;
+ current->flags |= PF_MEMALLOC;
+ vaddr = kmem_cache_alloc(cachep, GFP_ATOMIC);
+ current->flags &= (~PF_MEMALLOC | flags);
+ return vaddr;
+}
+
+
+static inline void *alloc_pgtable_page(void)
+{
+ unsigned int flags;
+ void *vaddr;
+
+ /* trying to avoid low memory issues */
+ flags = current->flags & PF_MEMALLOC;
+ current->flags |= PF_MEMALLOC;
+ vaddr = (void *)get_zeroed_page(GFP_ATOMIC);
+ current->flags &= (~PF_MEMALLOC | flags);
+ return vaddr;
+}
+
+static inline void free_pgtable_page(void *vaddr)
+{
+ free_page((unsigned long)vaddr);
+}
+
+static inline void *alloc_domain_mem(void)
+{
+ return iommu_kmem_cache_alloc(iommu_domain_cache);
+}
+
+static inline void free_domain_mem(void *vaddr)
+{
+ kmem_cache_free(iommu_domain_cache, vaddr);
+}
+
+static inline void * alloc_devinfo_mem(void)
+{
+ return iommu_kmem_cache_alloc(iommu_devinfo_cache);
+}
+
+static inline void free_devinfo_mem(void *vaddr)
+{
+ kmem_cache_free(iommu_devinfo_cache, vaddr);
+}
+
+struct iova *alloc_iova_mem(void)
+{
+ return iommu_kmem_cache_alloc(iommu_iova_cache);
+}
+
+void free_iova_mem(struct iova *iova)
+{
+ kmem_cache_free(iommu_iova_cache, iova);
+}
+
+static inline void __iommu_flush_cache(
+ struct intel_iommu *iommu, void *addr, int size)
+{
+ if (!ecap_coherent(iommu->ecap))
+ clflush_cache_range(addr, size);
+}
+
+/* Gets context entry for a given bus and devfn */
+static struct context_entry * device_to_context_entry(struct intel_iommu *iommu,
+ u8 bus, u8 devfn)
+{
+ struct root_entry *root;
+ struct context_entry *context;
+ unsigned long phy_addr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ root = &iommu->root_entry[bus];
+ context = get_context_addr_from_root(root);
+ if (!context) {
+ context = (struct context_entry *)alloc_pgtable_page();
+ if (!context) {
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return NULL;
+ }
+ __iommu_flush_cache(iommu, (void *)context, PAGE_SIZE_4K);
+ phy_addr = virt_to_phys((void *)context);
+ set_root_value(root, phy_addr);
+ set_root_present(root);
+ __iommu_flush_cache(iommu, root, sizeof(*root));
+ }
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return &context[devfn];
+}
+
+static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+ struct root_entry *root;
+ struct context_entry *context;
+ int ret;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ root = &iommu->root_entry[bus];
+ context = get_context_addr_from_root(root);
+ if (!context) {
+ ret = 0;
+ goto out;
+ }
+ ret = context_present(context[devfn]);
+out:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return ret;
+}
+
+static void clear_context_table(struct intel_iommu *iommu, u8 bus, u8 devfn)
+{
+ struct root_entry *root;
+ struct context_entry *context;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ root = &iommu->root_entry[bus];
+ context = get_context_addr_from_root(root);
+ if (context) {
+ context_clear_entry(context[devfn]);
+ __iommu_flush_cache(iommu, &context[devfn], \
+ sizeof(*context));
+ }
+ spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+static void free_context_table(struct intel_iommu *iommu)
+{
+ struct root_entry *root;
+ int i;
+ unsigned long flags;
+ struct context_entry *context;
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ if (!iommu->root_entry) {
+ goto out;
+ }
+ for (i = 0; i < ROOT_ENTRY_NR; i++) {
+ root = &iommu->root_entry[i];
+ context = get_context_addr_from_root(root);
+ if (context)
+ free_pgtable_page(context);
+ }
+ free_pgtable_page(iommu->root_entry);
+ iommu->root_entry = NULL;
+out:
+ spin_unlock_irqrestore(&iommu->lock, flags);
+}
+
+/* page table handling */
+#define LEVEL_STRIDE (9)
+#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1)
+
+static inline int agaw_to_level(int agaw)
+{
+ return agaw + 2;
+}
+
+static inline int agaw_to_width(int agaw)
+{
+ return 30 + agaw * LEVEL_STRIDE;
+
+}
+
+static inline int width_to_agaw(int width)
+{
+ return (width - 30) / LEVEL_STRIDE;
+}
+
+static inline unsigned int level_to_offset_bits(int level)
+{
+ return (12 + (level - 1) * LEVEL_STRIDE);
+}
+
+static inline int address_level_offset(u64 addr, int level)
+{
+ return ((addr >> level_to_offset_bits(level)) & LEVEL_MASK);
+}
+
+static inline u64 level_mask(int level)
+{
+ return ((u64)-1 << level_to_offset_bits(level));
+}
+
+static inline u64 level_size(int level)
+{
+ return ((u64)1 << level_to_offset_bits(level));
+}
+
+static inline u64 align_to_level(u64 addr, int level)
+{
+ return ((addr + level_size(level) - 1) & level_mask(level));
+}
+
+static struct dma_pte * addr_to_dma_pte(struct dmar_domain *domain, u64 addr)
+{
+ int addr_width = agaw_to_width(domain->agaw);
+ struct dma_pte *parent, *pte = NULL;
+ int level = agaw_to_level(domain->agaw);
+ int offset;
+ unsigned long flags;
+
+ BUG_ON(!domain->pgd);
+
+ addr &= (((u64)1) << addr_width) - 1;
+ parent = domain->pgd;
+
+ spin_lock_irqsave(&domain->mapping_lock, flags);
+ while (level > 0) {
+ void *tmp_page;
+
+ offset = address_level_offset(addr, level);
+ pte = &parent[offset];
+ if (level == 1)
+ break;
+
+ if (!dma_pte_present(*pte)) {
+ tmp_page = alloc_pgtable_page();
+
+ if (!tmp_page) {
+ spin_unlock_irqrestore(&domain->mapping_lock,
+ flags);
+ return NULL;
+ }
+ __iommu_flush_cache(domain->iommu, tmp_page,
+ PAGE_SIZE_4K);
+ dma_set_pte_addr(*pte, virt_to_phys(tmp_page));
+ /*
+ * high level table always sets r/w, last level page
+ * table control read/write
+ */
+ dma_set_pte_readable(*pte);
+ dma_set_pte_writable(*pte);
+ __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+ }
+ parent = phys_to_virt(dma_pte_addr(*pte));
+ level--;
+ }
+
+ spin_unlock_irqrestore(&domain->mapping_lock, flags);
+ return pte;
+}
+
+/* return address's pte at specific level */
+static struct dma_pte *dma_addr_level_pte(struct dmar_domain *domain, u64 addr,
+ int level)
+{
+ struct dma_pte *parent, *pte = NULL;
+ int total = agaw_to_level(domain->agaw);
+ int offset;
+
+ parent = domain->pgd;
+ while (level <= total) {
+ offset = address_level_offset(addr, total);
+ pte = &parent[offset];
+ if (level == total)
+ return pte;
+
+ if (!dma_pte_present(*pte))
+ break;
+ parent = phys_to_virt(dma_pte_addr(*pte));
+ total--;
+ }
+ return NULL;
+}
+
+/* clear one page's page table */
+static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
+{
+ struct dma_pte *pte = NULL;
+
+ /* get last level pte */
+ pte = dma_addr_level_pte(domain, addr, 1);
+
+ if (pte) {
+ dma_clear_pte(*pte);
+ __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+ }
+}
+
+/* clear last level pte, a tlb flush should be followed */
+static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
+{
+ int addr_width = agaw_to_width(domain->agaw);
+
+ start &= (((u64)1) << addr_width) - 1;
+ end &= (((u64)1) << addr_width) - 1;
+ /* in case it's partial page */
+ start = PAGE_ALIGN_4K(start);
+ end &= PAGE_MASK_4K;
+
+ /* we don't need lock here, nobody else touches the iova range */
+ while (start < end) {
+ dma_pte_clear_one(domain, start);
+ start += PAGE_SIZE_4K;
+ }
+}
+
+/* free page table pages. last level pte should already be cleared */
+static void dma_pte_free_pagetable(struct dmar_domain *domain,
+ u64 start, u64 end)
+{
+ int addr_width = agaw_to_width(domain->agaw);
+ struct dma_pte *pte;
+ int total = agaw_to_level(domain->agaw);
+ int level;
+ u64 tmp;
+
+ start &= (((u64)1) << addr_width) - 1;
+ end &= (((u64)1) << addr_width) - 1;
+
+ /* we don't need lock here, nobody else touches the iova range */
+ level = 2;
+ while (level <= total) {
+ tmp = align_to_level(start, level);
+ if (tmp >= end || (tmp + level_size(level) > end))
+ return;
+
+ while (tmp < end) {
+ pte = dma_addr_level_pte(domain, tmp, level);
+ if (pte) {
+ free_pgtable_page(
+ phys_to_virt(dma_pte_addr(*pte)));
+ dma_clear_pte(*pte);
+ __iommu_flush_cache(domain->iommu,
+ pte, sizeof(*pte));
+ }
+ tmp += level_size(level);
+ }
+ level++;
+ }
+ /* free pgd */
+ if (start == 0 && end >= ((((u64)1) << addr_width) - 1)) {
+ free_pgtable_page(domain->pgd);
+ domain->pgd = NULL;
+ }
+}
+
+/* iommu handling */
+static int iommu_alloc_root_entry(struct intel_iommu *iommu)
+{
+ struct root_entry *root;
+ unsigned long flags;
+
+ root = (struct root_entry *)alloc_pgtable_page();
+ if (!root)
+ return -ENOMEM;
+
+ __iommu_flush_cache(iommu, root, PAGE_SIZE_4K);
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ iommu->root_entry = root;
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ return 0;
+}
+
+#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
+{\
+ unsigned long start_time = jiffies;\
+ while (1) {\
+ sts = op (iommu->reg + offset);\
+ if (cond)\
+ break;\
+ if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))\
+ panic("DMAR hardware is malfunctioning\n");\
+ cpu_relax();\
+ }\
+}
+
+static void iommu_set_root_entry(struct intel_iommu *iommu)
+{
+ void *addr;
+ u32 cmd, sts;
+ unsigned long flag;
+
+ addr = iommu->root_entry;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ dmar_writeq(iommu->reg + DMAR_RTADDR_REG, virt_to_phys(addr));
+
+ cmd = iommu->gcmd | DMA_GCMD_SRTP;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (sts & DMA_GSTS_RTPS), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static void iommu_flush_write_buffer(struct intel_iommu *iommu)
+{
+ u32 val;
+ unsigned long flag;
+
+ if (!cap_rwbf(iommu->cap))
+ return;
+ val = iommu->gcmd | DMA_GCMD_WBF;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(val, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (!(val & DMA_GSTS_WBFS)), val);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+/* return value determine if we need a write buffer flush */
+static int __iommu_flush_context(struct intel_iommu *iommu,
+ u16 did, u16 source_id, u8 function_mask, u64 type,
+ int non_present_entry_flush)
+{
+ u64 val = 0;
+ unsigned long flag;
+
+ /*
+ * In the non-present entry flush case, if hardware doesn't cache
+ * non-present entry we do nothing and if hardware cache non-present
+ * entry, we flush entries of domain 0 (the domain id is used to cache
+ * any non-present entries)
+ */
+ if (non_present_entry_flush) {
+ if (!cap_caching_mode(iommu->cap))
+ return 1;
+ else
+ did = 0;
+ }
+
+ switch (type) {
+ case DMA_CCMD_GLOBAL_INVL:
+ val = DMA_CCMD_GLOBAL_INVL;
+ break;
+ case DMA_CCMD_DOMAIN_INVL:
+ val = DMA_CCMD_DOMAIN_INVL|DMA_CCMD_DID(did);
+ break;
+ case DMA_CCMD_DEVICE_INVL:
+ val = DMA_CCMD_DEVICE_INVL|DMA_CCMD_DID(did)
+ | DMA_CCMD_SID(source_id) | DMA_CCMD_FM(function_mask);
+ break;
+ default:
+ BUG();
+ }
+ val |= DMA_CCMD_ICC;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ dmar_writeq(iommu->reg + DMAR_CCMD_REG, val);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_CCMD_REG,
+ dmar_readq, (!(val & DMA_CCMD_ICC)), val);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+ /* flush context entry will implictly flush write buffer */
+ return 0;
+}
+
+static int inline iommu_flush_context_global(struct intel_iommu *iommu,
+ int non_present_entry_flush)
+{
+ return __iommu_flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL,
+ non_present_entry_flush);
+}
+
+static int inline iommu_flush_context_domain(struct intel_iommu *iommu, u16 did,
+ int non_present_entry_flush)
+{
+ return __iommu_flush_context(iommu, did, 0, 0, DMA_CCMD_DOMAIN_INVL,
+ non_present_entry_flush);
+}
+
+static int inline iommu_flush_context_device(struct intel_iommu *iommu,
+ u16 did, u16 source_id, u8 function_mask, int non_present_entry_flush)
+{
+ return __iommu_flush_context(iommu, did, source_id, function_mask,
+ DMA_CCMD_DEVICE_INVL, non_present_entry_flush);
+}
+
+/* return value determine if we need a write buffer flush */
+static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
+ u64 addr, unsigned int size_order, u64 type,
+ int non_present_entry_flush)
+{
+ int tlb_offset = ecap_iotlb_offset(iommu->ecap);
+ u64 val = 0, val_iva = 0;
+ unsigned long flag;
+
+ /*
+ * In the non-present entry flush case, if hardware doesn't cache
+ * non-present entry we do nothing and if hardware cache non-present
+ * entry, we flush entries of domain 0 (the domain id is used to cache
+ * any non-present entries)
+ */
+ if (non_present_entry_flush) {
+ if (!cap_caching_mode(iommu->cap))
+ return 1;
+ else
+ did = 0;
+ }
+
+ switch (type) {
+ case DMA_TLB_GLOBAL_FLUSH:
+ /* global flush doesn't need set IVA_REG */
+ val = DMA_TLB_GLOBAL_FLUSH|DMA_TLB_IVT;
+ break;
+ case DMA_TLB_DSI_FLUSH:
+ val = DMA_TLB_DSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+ break;
+ case DMA_TLB_PSI_FLUSH:
+ val = DMA_TLB_PSI_FLUSH|DMA_TLB_IVT|DMA_TLB_DID(did);
+ /* Note: always flush non-leaf currently */
+ val_iva = size_order | addr;
+ break;
+ default:
+ BUG();
+ }
+ /* Note: set drain read/write */
+#if 0
+ /*
+ * This is probably to be super secure.. Looks like we can
+ * ignore it without any impact.
+ */
+ if (cap_read_drain(iommu->cap))
+ val |= DMA_TLB_READ_DRAIN;
+#endif
+ if (cap_write_drain(iommu->cap))
+ val |= DMA_TLB_WRITE_DRAIN;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ /* Note: Only uses first TLB reg currently */
+ if (val_iva)
+ dmar_writeq(iommu->reg + tlb_offset, val_iva);
+ dmar_writeq(iommu->reg + tlb_offset + 8, val);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, tlb_offset + 8,
+ dmar_readq, (!(val & DMA_TLB_IVT)), val);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+ /* check IOTLB invalidation granularity */
+ if (DMA_TLB_IAIG(val) == 0)
+ printk(KERN_ERR"IOMMU: flush IOTLB failed\n");
+ if (DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type))
+ pr_debug("IOMMU: tlb flush request %Lx, actual %Lx\n",
+ DMA_TLB_IIRG(type), DMA_TLB_IAIG(val));
+ /* flush context entry will implictly flush write buffer */
+ return 0;
+}
+
+static int inline iommu_flush_iotlb_global(struct intel_iommu *iommu,
+ int non_present_entry_flush)
+{
+ return __iommu_flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH,
+ non_present_entry_flush);
+}
+
+static int inline iommu_flush_iotlb_dsi(struct intel_iommu *iommu, u16 did,
+ int non_present_entry_flush)
+{
+ return __iommu_flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH,
+ non_present_entry_flush);
+}
+
+static int iommu_flush_iotlb_psi(struct intel_iommu *iommu, u16 did,
+ u64 addr, unsigned int pages, int non_present_entry_flush)
+{
+ unsigned int mask;
+
+ BUG_ON(addr & (~PAGE_MASK_4K));
+ BUG_ON(pages == 0);
+
+ /* Fallback to domain selective flush if no PSI support */
+ if (!cap_pgsel_inv(iommu->cap))
+ return iommu_flush_iotlb_dsi(iommu, did,
+ non_present_entry_flush);
+
+ /*
+ * PSI requires page size to be 2 ^ x, and the base address is naturally
+ * aligned to the size
+ */
+ mask = ilog2(__roundup_pow_of_two(pages));
+ /* Fallback to domain selective flush if size is too big */
+ if (mask > cap_max_amask_val(iommu->cap))
+ return iommu_flush_iotlb_dsi(iommu, did,
+ non_present_entry_flush);
+
+ return __iommu_flush_iotlb(iommu, did, addr, mask,
+ DMA_TLB_PSI_FLUSH, non_present_entry_flush);
+}
+
+static int iommu_enable_translation(struct intel_iommu *iommu)
+{
+ u32 sts;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+ writel(iommu->gcmd|DMA_GCMD_TE, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (sts & DMA_GSTS_TES), sts);
+
+ iommu->gcmd |= DMA_GCMD_TE;
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+ return 0;
+}
+
+static int iommu_disable_translation(struct intel_iommu *iommu)
+{
+ u32 sts;
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ iommu->gcmd &= ~DMA_GCMD_TE;
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (!(sts & DMA_GSTS_TES)), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ return 0;
+}
+
+/* iommu interrupt handling. Most stuff are MSI-like. */
+
+static char *fault_reason_strings[] =
+{
+ "Software",
+ "Present bit in root entry is clear",
+ "Present bit in context entry is clear",
+ "Invalid context entry",
+ "Access beyond MGAW",
+ "PTE Write access is not set",
+ "PTE Read access is not set",
+ "Next page table ptr is invalid",
+ "Root table address invalid",
+ "Context table ptr is invalid",
+ "non-zero reserved fields in RTP",
+ "non-zero reserved fields in CTP",
+ "non-zero reserved fields in PTE",
+ "Unknown"
+};
+#define MAX_FAULT_REASON_IDX ARRAY_SIZE(fault_reason_strings)
+
+char *dmar_get_fault_reason(u8 fault_reason)
+{
+ if (fault_reason > MAX_FAULT_REASON_IDX)
+ return fault_reason_strings[MAX_FAULT_REASON_IDX];
+ else
+ return fault_reason_strings[fault_reason];
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ /* unmask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(0, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+ unsigned long flag;
+ struct intel_iommu *iommu = get_irq_data(irq);
+
+ /* mask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+ writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+ writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+ msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+ msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
+ u8 fault_reason, u16 source_id, u64 addr)
+{
+ char *reason;
+
+ reason = dmar_get_fault_reason(fault_reason);
+
+ printk(KERN_ERR
+ "DMAR:[%s] Request device [%02x:%02x.%d] "
+ "fault addr %llx \n"
+ "DMAR:[fault reason %02d] %s\n",
+ (type ? "DMA Read" : "DMA Write"),
+ (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+ PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+ return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+static irqreturn_t iommu_page_fault(int irq, void *dev_id)
+{
+ struct intel_iommu *iommu = dev_id;
+ int reg, fault_index;
+ u32 fault_status;
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+
+ /* TBD: ignore advanced fault log currently */
+ if (!(fault_status & DMA_FSTS_PPF))
+ goto clear_overflow;
+
+ fault_index = dma_fsts_fault_record_index(fault_status);
+ reg = cap_fault_reg_offset(iommu->cap);
+ while (1) {
+ u8 fault_reason;
+ u16 source_id;
+ u64 guest_addr;
+ int type;
+ u32 data;
+
+ /* highest 32 bits */
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+ if (!(data & DMA_FRCD_F))
+ break;
+
+ fault_reason = dma_frcd_fault_reason(data);
+ type = dma_frcd_type(data);
+
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 8);
+ source_id = dma_frcd_source_id(data);
+
+ guest_addr = dmar_readq(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN);
+ guest_addr = dma_frcd_page_addr(guest_addr);
+ /* clear the fault */
+ writel(DMA_FRCD_F, iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+ iommu_page_fault_do_one(iommu, type, fault_reason,
+ source_id, guest_addr);
+
+ fault_index++;
+ if (fault_index > cap_num_fault_regs(iommu->cap))
+ fault_index = 0;
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ }
+clear_overflow:
+ /* clear primary fault overflow */
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+ if (fault_status & DMA_FSTS_PFO)
+ writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+ int irq, ret;
+
+ irq = create_irq();
+ if (!irq) {
+ printk(KERN_ERR "IOMMU: no free vectors\n");
+ return -EINVAL;
+ }
+
+ set_irq_data(irq, iommu);
+ iommu->irq = irq;
+
+ ret = arch_setup_dmar_msi(irq);
+ if (ret) {
+ set_irq_data(irq, NULL);
+ iommu->irq = 0;
+ destroy_irq(irq);
+ return 0;
+ }
+
+ /* Force fault register is cleared */
+ iommu_page_fault(irq, iommu);
+
+ ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
+ if (ret)
+ printk(KERN_ERR "IOMMU: can't request irq\n");
+ return ret;
+}
+
+static int iommu_init_domains(struct intel_iommu *iommu)
+{
+ unsigned long ndomains;
+ unsigned long nlongs;
+
+ ndomains = cap_ndoms(iommu->cap);
+ pr_debug("Number of Domains supportd <%ld>\n", ndomains);
+ nlongs = BITS_TO_LONGS(ndomains);
+
+ /* TBD: there might be 64K domains,
+ * consider other allocation for future chip
+ */
+ iommu->domain_ids = kcalloc(nlongs, sizeof(unsigned long), GFP_KERNEL);
+ if (!iommu->domain_ids) {
+ printk(KERN_ERR "Allocating domain id array failed\n");
+ return -ENOMEM;
+ }
+ iommu->domains = kcalloc(ndomains, sizeof(struct dmar_domain *),
+ GFP_KERNEL);
+ if (!iommu->domains) {
+ printk(KERN_ERR "Allocating domain array failed\n");
+ kfree(iommu->domain_ids);
+ return -ENOMEM;
+ }
+
+ /*
+ * if Caching mode is set, then invalid translations are tagged
+ * with domainid 0. Hence we need to pre-allocate it.
+ */
+ if (cap_caching_mode(iommu->cap))
+ set_bit(0, iommu->domain_ids);
+ return 0;
+}
+
+static struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
+{
+ struct intel_iommu *iommu;
+ int ret;
+ int map_size;
+ u32 ver;
+
+ iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+ if (!iommu)
+ return NULL;
+ iommu->reg = ioremap(drhd->reg_base_addr, PAGE_SIZE_4K);
+ if (!iommu->reg) {
+ printk(KERN_ERR "IOMMU: can't map the region\n");
+ goto error;
+ }
+ iommu->cap = dmar_readq(iommu->reg + DMAR_CAP_REG);
+ iommu->ecap = dmar_readq(iommu->reg + DMAR_ECAP_REG);
+
+ /* the registers might be more than one page */
+ map_size = max_t(int, ecap_max_iotlb_offset(iommu->ecap),
+ cap_max_fault_reg_offset(iommu->cap));
+ map_size = PAGE_ALIGN_4K(map_size);
+ if (map_size > PAGE_SIZE_4K) {
+ iounmap(iommu->reg);
+ iommu->reg = ioremap(drhd->reg_base_addr, map_size);
+ if (!iommu->reg) {
+ printk(KERN_ERR "IOMMU: can't map the region\n");
+ goto error;
+ }
+ }
+
+ ver = readl(iommu->reg + DMAR_VER_REG);
+ pr_debug("IOMMU %llx: ver %d:%d cap %llx ecap %llx\n",
+ drhd->reg_base_addr, DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver),
+ iommu->cap, iommu->ecap);
+ ret = iommu_init_domains(iommu);
+ if (ret)
+ goto error_unmap;
+ spin_lock_init(&iommu->lock);
+ spin_lock_init(&iommu->register_lock);
+
+ drhd->iommu = iommu;
+ return iommu;
+error_unmap:
+ iounmap(iommu->reg);
+ iommu->reg = 0;
+error:
+ kfree(iommu);
+ return NULL;
+}
+
+static void domain_exit(struct dmar_domain *domain);
+static void free_iommu(struct intel_iommu *iommu)
+{
+ struct dmar_domain *domain;
+ int i;
+
+ if (!iommu)
+ return;
+
+ i = find_first_bit(iommu->domain_ids, cap_ndoms(iommu->cap));
+ for (; i < cap_ndoms(iommu->cap); ) {
+ domain = iommu->domains[i];
+ clear_bit(i, iommu->domain_ids);
+ domain_exit(domain);
+ i = find_next_bit(iommu->domain_ids,
+ cap_ndoms(iommu->cap), i+1);
+ }
+
+ if (iommu->gcmd & DMA_GCMD_TE)
+ iommu_disable_translation(iommu);
+
+ if (iommu->irq) {
+ set_irq_data(iommu->irq, NULL);
+ /* This will mask the irq */
+ free_irq(iommu->irq, iommu);
+ destroy_irq(iommu->irq);
+ }
+
+ kfree(iommu->domains);
+ kfree(iommu->domain_ids);
+
+ /* free context mapping */
+ free_context_table(iommu);
+
+ if (iommu->reg)
+ iounmap(iommu->reg);
+ kfree(iommu);
+}
+
+static struct dmar_domain * iommu_alloc_domain(struct intel_iommu *iommu)
+{
+ unsigned long num;
+ unsigned long ndomains;
+ struct dmar_domain *domain;
+ unsigned long flags;
+
+ domain = alloc_domain_mem();
+ if (!domain)
+ return NULL;
+
+ ndomains = cap_ndoms(iommu->cap);
+
+ spin_lock_irqsave(&iommu->lock, flags);
+ num = find_first_zero_bit(iommu->domain_ids, ndomains);
+ if (num >= ndomains) {
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ free_domain_mem(domain);
+ printk(KERN_ERR "IOMMU: no free domain ids\n");
+ return NULL;
+ }
+
+ set_bit(num, iommu->domain_ids);
+ domain->id = num;
+ domain->iommu = iommu;
+ iommu->domains[num] = domain;
+ spin_unlock_irqrestore(&iommu->lock, flags);
+
+ return domain;
+}
+
+static void iommu_free_domain(struct dmar_domain *domain)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&domain->iommu->lock, flags);
+ clear_bit(domain->id, domain->iommu->domain_ids);
+ spin_unlock_irqrestore(&domain->iommu->lock, flags);
+}
+
+static struct iova_domain reserved_iova_list;
+
+static void dmar_init_reserved_ranges(void)
+{
+ struct pci_dev *pdev = NULL;
+ struct iova *iova;
+ int i;
+ u64 addr, size;
+
+ init_iova_domain(&reserved_iova_list);
+
+ /* IOAPIC ranges shouldn't be accessed by DMA */
+ iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
+ IOVA_PFN(IOAPIC_RANGE_END));
+ if (!iova)
+ printk(KERN_ERR "Reserve IOAPIC range failed\n");
+
+ /* Reserve all PCI MMIO to avoid peer-to-peer access */
+ for_each_pci_dev(pdev) {
+ struct resource *r;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ r = &pdev->resource[i];
+ if (!r->flags || !(r->flags & IORESOURCE_MEM))
+ continue;
+ addr = r->start;
+ addr &= PAGE_MASK_4K;
+ size = r->end - addr;
+ size = PAGE_ALIGN_4K(size);
+ iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
+ IOVA_PFN(size + addr) - 1);
+ if (!iova)
+ printk(KERN_ERR "Reserve iova failed\n");
+ }
+ }
+
+}
+
+static void domain_reserve_special_ranges(struct dmar_domain *domain)
+{
+ copy_reserved_iova(&reserved_iova_list, &domain->iovad);
+}
+
+static inline int guestwidth_to_adjustwidth(int gaw)
+{
+ int agaw;
+ int r = (gaw - 12) % 9;
+
+ if (r == 0)
+ agaw = gaw;
+ else
+ agaw = gaw + 9 - r;
+ if (agaw > 64)
+ agaw = 64;
+ return agaw;
+}
+
+static int domain_init(struct dmar_domain *domain, int guest_width)
+{
+ struct intel_iommu *iommu;
+ int adjust_width, agaw;
+ unsigned long sagaw;
+
+ init_iova_domain(&domain->iovad);
+ spin_lock_init(&domain->mapping_lock);
+
+ domain_reserve_special_ranges(domain);
+
+ /* calculate AGAW */
+ iommu = domain->iommu;
+ if (guest_width > cap_mgaw(iommu->cap))
+ guest_width = cap_mgaw(iommu->cap);
+ domain->gaw = guest_width;
+ adjust_width = guestwidth_to_adjustwidth(guest_width);
+ agaw = width_to_agaw(adjust_width);
+ sagaw = cap_sagaw(iommu->cap);
+ if (!test_bit(agaw, &sagaw)) {
+ /* hardware doesn't support it, choose a bigger one */
+ pr_debug("IOMMU: hardware doesn't support agaw %d\n", agaw);
+ agaw = find_next_bit(&sagaw, 5, agaw);
+ if (agaw >= 5)
+ return -ENODEV;
+ }
+ domain->agaw = agaw;
+ INIT_LIST_HEAD(&domain->devices);
+
+ /* always allocate the top pgd */
+ domain->pgd = (struct dma_pte *)alloc_pgtable_page();
+ if (!domain->pgd)
+ return -ENOMEM;
+ __iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE_4K);
+ return 0;
+}
+
+static void domain_exit(struct dmar_domain *domain)
+{
+ u64 end;
+
+ /* Domain 0 is reserved, so dont process it */
+ if (!domain)
+ return;
+
+ domain_remove_dev_info(domain);
+ /* destroy iovas */
+ put_iova_domain(&domain->iovad);
+ end = DOMAIN_MAX_ADDR(domain->gaw);
+ end = end & (~PAGE_MASK_4K);
+
+ /* clear ptes */
+ dma_pte_clear_range(domain, 0, end);
+
+ /* free page tables */
+ dma_pte_free_pagetable(domain, 0, end);
+
+ iommu_free_domain(domain);
+ free_domain_mem(domain);
+}
+
+static int domain_context_mapping_one(struct dmar_domain *domain,
+ u8 bus, u8 devfn)
+{
+ struct context_entry *context;
+ struct intel_iommu *iommu = domain->iommu;
+ unsigned long flags;
+
+ pr_debug("Set context mapping for %02x:%02x.%d\n",
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ BUG_ON(!domain->pgd);
+ context = device_to_context_entry(iommu, bus, devfn);
+ if (!context)
+ return -ENOMEM;
+ spin_lock_irqsave(&iommu->lock, flags);
+ if (context_present(*context)) {
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return 0;
+ }
+
+ context_set_domain_id(*context, domain->id);
+ context_set_address_width(*context, domain->agaw);
+ context_set_address_root(*context, virt_to_phys(domain->pgd));
+ context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
+ context_set_fault_enable(*context);
+ context_set_present(*context);
+ __iommu_flush_cache(iommu, context, sizeof(*context));
+
+ /* it's a non-present to present mapping */
+ if (iommu_flush_context_device(iommu, domain->id,
+ (((u16)bus) << 8) | devfn, DMA_CCMD_MASK_NOBIT, 1))
+ iommu_flush_write_buffer(iommu);
+ else
+ iommu_flush_iotlb_dsi(iommu, 0, 0);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return 0;
+}
+
+static int
+domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
+{
+ int ret;
+ struct pci_dev *tmp, *parent;
+
+ ret = domain_context_mapping_one(domain, pdev->bus->number,
+ pdev->devfn);
+ if (ret)
+ return ret;
+
+ /* dependent device mapping */
+ tmp = pci_find_upstream_pcie_bridge(pdev);
+ if (!tmp)
+ return 0;
+ /* Secondary interface's bus number and devfn 0 */
+ parent = pdev->bus->self;
+ while (parent != tmp) {
+ ret = domain_context_mapping_one(domain, parent->bus->number,
+ parent->devfn);
+ if (ret)
+ return ret;
+ parent = parent->bus->self;
+ }
+ if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+ return domain_context_mapping_one(domain,
+ tmp->subordinate->number, 0);
+ else /* this is a legacy PCI bridge */
+ return domain_context_mapping_one(domain,
+ tmp->bus->number, tmp->devfn);
+}
+
+static int domain_context_mapped(struct dmar_domain *domain,
+ struct pci_dev *pdev)
+{
+ int ret;
+ struct pci_dev *tmp, *parent;
+
+ ret = device_context_mapped(domain->iommu,
+ pdev->bus->number, pdev->devfn);
+ if (!ret)
+ return ret;
+ /* dependent device mapping */
+ tmp = pci_find_upstream_pcie_bridge(pdev);
+ if (!tmp)
+ return ret;
+ /* Secondary interface's bus number and devfn 0 */
+ parent = pdev->bus->self;
+ while (parent != tmp) {
+ ret = device_context_mapped(domain->iommu, parent->bus->number,
+ parent->devfn);
+ if (!ret)
+ return ret;
+ parent = parent->bus->self;
+ }
+ if (tmp->is_pcie)
+ return device_context_mapped(domain->iommu,
+ tmp->subordinate->number, 0);
+ else
+ return device_context_mapped(domain->iommu,
+ tmp->bus->number, tmp->devfn);
+}
+
+static int
+domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
+ u64 hpa, size_t size, int prot)
+{
+ u64 start_pfn, end_pfn;
+ struct dma_pte *pte;
+ int index;
+
+ if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
+ return -EINVAL;
+ iova &= PAGE_MASK_4K;
+ start_pfn = ((u64)hpa) >> PAGE_SHIFT_4K;
+ end_pfn = (PAGE_ALIGN_4K(((u64)hpa) + size)) >> PAGE_SHIFT_4K;
+ index = 0;
+ while (start_pfn < end_pfn) {
+ pte = addr_to_dma_pte(domain, iova + PAGE_SIZE_4K * index);
+ if (!pte)
+ return -ENOMEM;
+ /* We don't need lock here, nobody else
+ * touches the iova range
+ */
+ BUG_ON(dma_pte_addr(*pte));
+ dma_set_pte_addr(*pte, start_pfn << PAGE_SHIFT_4K);
+ dma_set_pte_prot(*pte, prot);
+ __iommu_flush_cache(domain->iommu, pte, sizeof(*pte));
+ start_pfn++;
+ index++;
+ }
+ return 0;
+}
+
+static void detach_domain_for_dev(struct dmar_domain *domain, u8 bus, u8 devfn)
+{
+ clear_context_table(domain->iommu, bus, devfn);
+ iommu_flush_context_global(domain->iommu, 0);
+ iommu_flush_iotlb_global(domain->iommu, 0);
+}
+
+static void domain_remove_dev_info(struct dmar_domain *domain)
+{
+ struct device_domain_info *info;
+ unsigned long flags;
+
+ spin_lock_irqsave(&device_domain_lock, flags);
+ while (!list_empty(&domain->devices)) {
+ info = list_entry(domain->devices.next,
+ struct device_domain_info, link);
+ list_del(&info->link);
+ list_del(&info->global);
+ if (info->dev)
+ info->dev->dev.archdata.iommu = NULL;
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+
+ detach_domain_for_dev(info->domain, info->bus, info->devfn);
+ free_devinfo_mem(info);
+
+ spin_lock_irqsave(&device_domain_lock, flags);
+ }
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+}
+
+/*
+ * find_domain
+ * Note: we use struct pci_dev->dev.archdata.iommu stores the info
+ */
+struct dmar_domain *
+find_domain(struct pci_dev *pdev)
+{
+ struct device_domain_info *info;
+
+ /* No lock here, assumes no domain exit in normal case */
+ info = pdev->dev.archdata.iommu;
+ if (info)
+ return info->domain;
+ return NULL;
+}
+
+static int dmar_pci_device_match(struct pci_dev *devices[], int cnt,
+ struct pci_dev *dev)
+{
+ int index;
+
+ while (dev) {
+ for (index = 0; index < cnt; index ++)
+ if (dev == devices[index])
+ return 1;
+
+ /* Check our parent */
+ dev = dev->bus->self;
+ }
+
+ return 0;
+}
+
+static struct dmar_drhd_unit *
+dmar_find_matched_drhd_unit(struct pci_dev *dev)
+{
+ struct dmar_drhd_unit *drhd = NULL;
+
+ list_for_each_entry(drhd, &dmar_drhd_units, list) {
+ if (drhd->include_all || dmar_pci_device_match(drhd->devices,
+ drhd->devices_cnt, dev))
+ return drhd;
+ }
+
+ return NULL;
+}
+
+/* domain is initialized */
+static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
+{
+ struct dmar_domain *domain, *found = NULL;
+ struct intel_iommu *iommu;
+ struct dmar_drhd_unit *drhd;
+ struct device_domain_info *info, *tmp;
+ struct pci_dev *dev_tmp;
+ unsigned long flags;
+ int bus = 0, devfn = 0;
+
+ domain = find_domain(pdev);
+ if (domain)
+ return domain;
+
+ dev_tmp = pci_find_upstream_pcie_bridge(pdev);
+ if (dev_tmp) {
+ if (dev_tmp->is_pcie) {
+ bus = dev_tmp->subordinate->number;
+ devfn = 0;
+ } else {
+ bus = dev_tmp->bus->number;
+ devfn = dev_tmp->devfn;
+ }
+ spin_lock_irqsave(&device_domain_lock, flags);
+ list_for_each_entry(info, &device_domain_list, global) {
+ if (info->bus == bus && info->devfn == devfn) {
+ found = info->domain;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+ /* pcie-pci bridge already has a domain, uses it */
+ if (found) {
+ domain = found;
+ goto found_domain;
+ }
+ }
+
+ /* Allocate new domain for the device */
+ drhd = dmar_find_matched_drhd_unit(pdev);
+ if (!drhd) {
+ printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n",
+ pci_name(pdev));
+ return NULL;
+ }
+ iommu = drhd->iommu;
+
+ domain = iommu_alloc_domain(iommu);
+ if (!domain)
+ goto error;
+
+ if (domain_init(domain, gaw)) {
+ domain_exit(domain);
+ goto error;
+ }
+
+ /* register pcie-to-pci device */
+ if (dev_tmp) {
+ info = alloc_devinfo_mem();
+ if (!info) {
+ domain_exit(domain);
+ goto error;
+ }
+ info->bus = bus;
+ info->devfn = devfn;
+ info->dev = NULL;
+ info->domain = domain;
+ /* This domain is shared by devices under p2p bridge */
+ domain->flags |= DOMAIN_FLAG_MULTIPLE_DEVICES;
+
+ /* pcie-to-pci bridge already has a domain, uses it */
+ found = NULL;
+ spin_lock_irqsave(&device_domain_lock, flags);
+ list_for_each_entry(tmp, &device_domain_list, global) {
+ if (tmp->bus == bus && tmp->devfn == devfn) {
+ found = tmp->domain;
+ break;
+ }
+ }
+ if (found) {
+ free_devinfo_mem(info);
+ domain_exit(domain);
+ domain = found;
+ } else {
+ list_add(&info->link, &domain->devices);
+ list_add(&info->global, &device_domain_list);
+ }
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+ }
+
+found_domain:
+ info = alloc_devinfo_mem();
+ if (!info)
+ goto error;
+ info->bus = pdev->bus->number;
+ info->devfn = pdev->devfn;
+ info->dev = pdev;
+ info->domain = domain;
+ spin_lock_irqsave(&device_domain_lock, flags);
+ /* somebody is fast */
+ found = find_domain(pdev);
+ if (found != NULL) {
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+ if (found != domain) {
+ domain_exit(domain);
+ domain = found;
+ }
+ free_devinfo_mem(info);
+ return domain;
+ }
+ list_add(&info->link, &domain->devices);
+ list_add(&info->global, &device_domain_list);
+ pdev->dev.archdata.iommu = info;
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+ return domain;
+error:
+ /* recheck it here, maybe others set it */
+ return find_domain(pdev);
+}
+
+static int iommu_prepare_identity_map(struct pci_dev *pdev, u64 start, u64 end)
+{
+ struct dmar_domain *domain;
+ unsigned long size;
+ u64 base;
+ int ret;
+
+ printk(KERN_INFO
+ "IOMMU: Setting identity map for device %s [0x%Lx - 0x%Lx]\n",
+ pci_name(pdev), start, end);
+ /* page table init */
+ domain = get_domain_for_dev(pdev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ if (!domain)
+ return -ENOMEM;
+
+ /* The address might not be aligned */
+ base = start & PAGE_MASK_4K;
+ size = end - base;
+ size = PAGE_ALIGN_4K(size);
+ if (!reserve_iova(&domain->iovad, IOVA_PFN(base),
+ IOVA_PFN(base + size) - 1)) {
+ printk(KERN_ERR "IOMMU: reserve iova failed\n");
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ pr_debug("Mapping reserved region %lx@%llx for %s\n",
+ size, base, pci_name(pdev));
+ /*
+ * RMRR range might have overlap with physical memory range,
+ * clear it first
+ */
+ dma_pte_clear_range(domain, base, base + size);
+
+ ret = domain_page_mapping(domain, base, base, size,
+ DMA_PTE_READ|DMA_PTE_WRITE);
+ if (ret)
+ goto error;
+
+ /* context entry init */
+ ret = domain_context_mapping(domain, pdev);
+ if (!ret)
+ return 0;
+error:
+ domain_exit(domain);
+ return ret;
+
+}
+
+static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
+ struct pci_dev *pdev)
+{
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+ return 0;
+ return iommu_prepare_identity_map(pdev, rmrr->base_address,
+ rmrr->end_address + 1);
+}
+
+#ifdef CONFIG_DMAR_GFX_WA
+extern int arch_get_ram_range(int slot, u64 *addr, u64 *size);
+static void __init iommu_prepare_gfx_mapping(void)
+{
+ struct pci_dev *pdev = NULL;
+ u64 base, size;
+ int slot;
+ int ret;
+
+ for_each_pci_dev(pdev) {
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO ||
+ !IS_GFX_DEVICE(pdev))
+ continue;
+ printk(KERN_INFO "IOMMU: gfx device %s 1-1 mapping\n",
+ pci_name(pdev));
+ slot = arch_get_ram_range(0, &base, &size);
+ while (slot >= 0) {
+ ret = iommu_prepare_identity_map(pdev,
+ base, base + size);
+ if (ret)
+ goto error;
+ slot = arch_get_ram_range(slot, &base, &size);
+ }
+ continue;
+error:
+ printk(KERN_ERR "IOMMU: mapping reserved region failed\n");
+ }
+}
+#endif
+
+#ifdef CONFIG_DMAR_FLOPPY_WA
+static inline void iommu_prepare_isa(void)
+{
+ struct pci_dev *pdev;
+ int ret;
+
+ pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+ if (!pdev)
+ return;
+
+ printk(KERN_INFO "IOMMU: Prepare 0-16M unity mapping for LPC\n");
+ ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
+
+ if (ret)
+ printk("IOMMU: Failed to create 0-64M identity map, "
+ "floppy might not work\n");
+
+}
+#else
+static inline void iommu_prepare_isa(void)
+{
+ return;
+}
+#endif /* !CONFIG_DMAR_FLPY_WA */
+
+int __init init_dmars(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct dmar_rmrr_unit *rmrr;
+ struct pci_dev *pdev;
+ struct intel_iommu *iommu;
+ int ret, unit = 0;
+
+ /*
+ * for each drhd
+ * allocate root
+ * initialize and program root entry to not present
+ * endfor
+ */
+ for_each_drhd_unit(drhd) {
+ if (drhd->ignored)
+ continue;
+ iommu = alloc_iommu(drhd);
+ if (!iommu) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ /*
+ * TBD:
+ * we could share the same root & context tables
+ * amoung all IOMMU's. Need to Split it later.
+ */
+ ret = iommu_alloc_root_entry(iommu);
+ if (ret) {
+ printk(KERN_ERR "IOMMU: allocate root entry failed\n");
+ goto error;
+ }
+ }
+
+ /*
+ * For each rmrr
+ * for each dev attached to rmrr
+ * do
+ * locate drhd for dev, alloc domain for dev
+ * allocate free domain
+ * allocate page table entries for rmrr
+ * if context not allocated for bus
+ * allocate and init context
+ * set present in root table for this bus
+ * init context with domain, translation etc
+ * endfor
+ * endfor
+ */
+ for_each_rmrr_units(rmrr) {
+ int i;
+ for (i = 0; i < rmrr->devices_cnt; i++) {
+ pdev = rmrr->devices[i];
+ /* some BIOS lists non-exist devices in DMAR table */
+ if (!pdev)
+ continue;
+ ret = iommu_prepare_rmrr_dev(rmrr, pdev);
+ if (ret)
+ printk(KERN_ERR
+ "IOMMU: mapping reserved region failed\n");
+ }
+ }
+
+ iommu_prepare_gfx_mapping();
+
+ iommu_prepare_isa();
+
+ /*
+ * for each drhd
+ * enable fault log
+ * global invalidate context cache
+ * global invalidate iotlb
+ * enable translation
+ */
+ for_each_drhd_unit(drhd) {
+ if (drhd->ignored)
+ continue;
+ iommu = drhd->iommu;
+ sprintf (iommu->name, "dmar%d", unit++);
+
+ iommu_flush_write_buffer(iommu);
+
+ ret = dmar_set_interrupt(iommu);
+ if (ret)
+ goto error;
+
+ iommu_set_root_entry(iommu);
+
+ iommu_flush_context_global(iommu, 0);
+ iommu_flush_iotlb_global(iommu, 0);
+
+ ret = iommu_enable_translation(iommu);
+ if (ret)
+ goto error;
+ }
+
+ return 0;
+error:
+ for_each_drhd_unit(drhd) {
+ if (drhd->ignored)
+ continue;
+ iommu = drhd->iommu;
+ free_iommu(iommu);
+ }
+ return ret;
+}
+
+static inline u64 aligned_size(u64 host_addr, size_t size)
+{
+ u64 addr;
+ addr = (host_addr & (~PAGE_MASK_4K)) + size;
+ return PAGE_ALIGN_4K(addr);
+}
+
+struct iova *
+iommu_alloc_iova(struct dmar_domain *domain, size_t size, u64 end)
+{
+ struct iova *piova;
+
+ /* Make sure it's in range */
+ end = min_t(u64, DOMAIN_MAX_ADDR(domain->gaw), end);
+ if (!size || (IOVA_START_ADDR + size > end))
+ return NULL;
+
+ piova = alloc_iova(&domain->iovad,
+ size >> PAGE_SHIFT_4K, IOVA_PFN(end), 1);
+ return piova;
+}
+
+static struct iova *
+__intel_alloc_iova(struct device *dev, struct dmar_domain *domain,
+ size_t size)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct iova *iova = NULL;
+
+ if ((pdev->dma_mask <= DMA_32BIT_MASK) || (dmar_forcedac)) {
+ iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+ } else {
+ /*
+ * First try to allocate an io virtual address in
+ * DMA_32BIT_MASK and if that fails then try allocating
+ * from higer range
+ */
+ iova = iommu_alloc_iova(domain, size, DMA_32BIT_MASK);
+ if (!iova)
+ iova = iommu_alloc_iova(domain, size, pdev->dma_mask);
+ }
+
+ if (!iova) {
+ printk(KERN_ERR"Allocating iova for %s failed", pci_name(pdev));
+ return NULL;
+ }
+
+ return iova;
+}
+
+static struct dmar_domain *
+get_valid_domain_for_dev(struct pci_dev *pdev)
+{
+ struct dmar_domain *domain;
+ int ret;
+
+ domain = get_domain_for_dev(pdev,
+ DEFAULT_DOMAIN_ADDRESS_WIDTH);
+ if (!domain) {
+ printk(KERN_ERR
+ "Allocating domain for %s failed", pci_name(pdev));
+ return 0;
+ }
+
+ /* make sure context mapping is ok */
+ if (unlikely(!domain_context_mapped(domain, pdev))) {
+ ret = domain_context_mapping(domain, pdev);
+ if (ret) {
+ printk(KERN_ERR
+ "Domain context map for %s failed",
+ pci_name(pdev));
+ return 0;
+ }
+ }
+
+ return domain;
+}
+
+static dma_addr_t intel_map_single(struct device *hwdev, void *addr,
+ size_t size, int dir)
+{
+ struct pci_dev *pdev = to_pci_dev(hwdev);
+ int ret;
+ struct dmar_domain *domain;
+ unsigned long start_addr;
+ struct iova *iova;
+ int prot = 0;
+
+ BUG_ON(dir == DMA_NONE);
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+ return virt_to_bus(addr);
+
+ domain = get_valid_domain_for_dev(pdev);
+ if (!domain)
+ return 0;
+
+ addr = (void *)virt_to_phys(addr);
+ size = aligned_size((u64)addr, size);
+
+ iova = __intel_alloc_iova(hwdev, domain, size);
+ if (!iova)
+ goto error;
+
+ start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+ /*
+ * Check if DMAR supports zero-length reads on write only
+ * mappings..
+ */
+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+ !cap_zlr(domain->iommu->cap))
+ prot |= DMA_PTE_READ;
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+ prot |= DMA_PTE_WRITE;
+ /*
+ * addr - (addr + size) might be partial page, we should map the whole
+ * page. Note: if two part of one page are separately mapped, we
+ * might have two guest_addr mapping to the same host addr, but this
+ * is not a big problem
+ */
+ ret = domain_page_mapping(domain, start_addr,
+ ((u64)addr) & PAGE_MASK_4K, size, prot);
+ if (ret)
+ goto error;
+
+ pr_debug("Device %s request: %lx@%llx mapping: %lx@%llx, dir %d\n",
+ pci_name(pdev), size, (u64)addr,
+ size, (u64)start_addr, dir);
+
+ /* it's a non-present to present mapping */
+ ret = iommu_flush_iotlb_psi(domain->iommu, domain->id,
+ start_addr, size >> PAGE_SHIFT_4K, 1);
+ if (ret)
+ iommu_flush_write_buffer(domain->iommu);
+
+ return (start_addr + ((u64)addr & (~PAGE_MASK_4K)));
+
+error:
+ if (iova)
+ __free_iova(&domain->iovad, iova);
+ printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+ pci_name(pdev), size, (u64)addr, dir);
+ return 0;
+}
+
+static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr,
+ size_t size, int dir)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct dmar_domain *domain;
+ unsigned long start_addr;
+ struct iova *iova;
+
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+ return;
+ domain = find_domain(pdev);
+ BUG_ON(!domain);
+
+ iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr));
+ if (!iova)
+ return;
+
+ start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+ size = aligned_size((u64)dev_addr, size);
+
+ pr_debug("Device %s unmapping: %lx@%llx\n",
+ pci_name(pdev), size, (u64)start_addr);
+
+ /* clear the whole page */
+ dma_pte_clear_range(domain, start_addr, start_addr + size);
+ /* free page tables */
+ dma_pte_free_pagetable(domain, start_addr, start_addr + size);
+
+ if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
+ size >> PAGE_SHIFT_4K, 0))
+ iommu_flush_write_buffer(domain->iommu);
+
+ /* free iova */
+ __free_iova(&domain->iovad, iova);
+}
+
+static void * intel_alloc_coherent(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags)
+{
+ void *vaddr;
+ int order;
+
+ size = PAGE_ALIGN_4K(size);
+ order = get_order(size);
+ flags &= ~(GFP_DMA | GFP_DMA32);
+
+ vaddr = (void *)__get_free_pages(flags, order);
+ if (!vaddr)
+ return NULL;
+ memset(vaddr, 0, size);
+
+ *dma_handle = intel_map_single(hwdev, vaddr, size, DMA_BIDIRECTIONAL);
+ if (*dma_handle)
+ return vaddr;
+ free_pages((unsigned long)vaddr, order);
+ return NULL;
+}
+
+static void intel_free_coherent(struct device *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ int order;
+
+ size = PAGE_ALIGN_4K(size);
+ order = get_order(size);
+
+ intel_unmap_single(hwdev, dma_handle, size, DMA_BIDIRECTIONAL);
+ free_pages((unsigned long)vaddr, order);
+}
+
+#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+ int nelems, int dir)
+{
+ int i;
+ struct pci_dev *pdev = to_pci_dev(hwdev);
+ struct dmar_domain *domain;
+ unsigned long start_addr;
+ struct iova *iova;
+ size_t size = 0;
+ void *addr;
+ struct scatterlist *sg;
+
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+ return;
+
+ domain = find_domain(pdev);
+
+ iova = find_iova(&domain->iovad, IOVA_PFN(sglist[0].dma_address));
+ if (!iova)
+ return;
+ for_each_sg(sglist, sg, nelems, i) {
+ addr = SG_ENT_VIRT_ADDRESS(sg);
+ size += aligned_size((u64)addr, sg->length);
+ }
+
+ start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+
+ /* clear the whole page */
+ dma_pte_clear_range(domain, start_addr, start_addr + size);
+ /* free page tables */
+ dma_pte_free_pagetable(domain, start_addr, start_addr + size);
+
+ if (iommu_flush_iotlb_psi(domain->iommu, domain->id, start_addr,
+ size >> PAGE_SHIFT_4K, 0))
+ iommu_flush_write_buffer(domain->iommu);
+
+ /* free iova */
+ __free_iova(&domain->iovad, iova);
+}
+
+static int intel_nontranslate_map_sg(struct device *hddev,
+ struct scatterlist *sglist, int nelems, int dir)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sglist, sg, nelems, i) {
+ BUG_ON(!sg->page);
+ sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+ sg->dma_length = sg->length;
+ }
+ return nelems;
+}
+
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist,
+ int nelems, int dir)
+{
+ void *addr;
+ int i;
+ struct pci_dev *pdev = to_pci_dev(hwdev);
+ struct dmar_domain *domain;
+ size_t size = 0;
+ int prot = 0;
+ size_t offset = 0;
+ struct iova *iova = NULL;
+ int ret;
+ struct scatterlist *sg;
+ unsigned long start_addr;
+
+ BUG_ON(dir == DMA_NONE);
+ if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
+ return intel_nontranslate_map_sg(hwdev, sglist, nelems, dir);
+
+ domain = get_valid_domain_for_dev(pdev);
+ if (!domain)
+ return 0;
+
+ for_each_sg(sglist, sg, nelems, i) {
+ addr = SG_ENT_VIRT_ADDRESS(sg);
+ addr = (void *)virt_to_phys(addr);
+ size += aligned_size((u64)addr, sg->length);
+ }
+
+ iova = __intel_alloc_iova(hwdev, domain, size);
+ if (!iova) {
+ sglist->dma_length = 0;
+ return 0;
+ }
+
+ /*
+ * Check if DMAR supports zero-length reads on write only
+ * mappings..
+ */
+ if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL || \
+ !cap_zlr(domain->iommu->cap))
+ prot |= DMA_PTE_READ;
+ if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+ prot |= DMA_PTE_WRITE;
+
+ start_addr = iova->pfn_lo << PAGE_SHIFT_4K;
+ offset = 0;
+ for_each_sg(sglist, sg, nelems, i) {
+ addr = SG_ENT_VIRT_ADDRESS(sg);
+ addr = (void *)virt_to_phys(addr);
+ size = aligned_size((u64)addr, sg->length);
+ ret = domain_page_mapping(domain, start_addr + offset,
+ ((u64)addr) & PAGE_MASK_4K,
+ size, prot);
+ if (ret) {
+ /* clear the page */
+ dma_pte_clear_range(domain, start_addr,
+ start_addr + offset);
+ /* free page tables */
+ dma_pte_free_pagetable(domain, start_addr,
+ start_addr + offset);
+ /* free iova */
+ __free_iova(&domain->iovad, iova);
+ return 0;
+ }
+ sg->dma_address = start_addr + offset +
+ ((u64)addr & (~PAGE_MASK_4K));
+ sg->dma_length = sg->length;
+ offset += size;
+ }
+
+ /* it's a non-present to present mapping */
+ if (iommu_flush_iotlb_psi(domain->iommu, domain->id,
+ start_addr, offset >> PAGE_SHIFT_4K, 1))
+ iommu_flush_write_buffer(domain->iommu);
+ return nelems;
+}
+
+static struct dma_mapping_ops intel_dma_ops = {
+ .alloc_coherent = intel_alloc_coherent,
+ .free_coherent = intel_free_coherent,
+ .map_single = intel_map_single,
+ .unmap_single = intel_unmap_single,
+ .map_sg = intel_map_sg,
+ .unmap_sg = intel_unmap_sg,
+};
+
+static inline int iommu_domain_cache_init(void)
+{
+ int ret = 0;
+
+ iommu_domain_cache = kmem_cache_create("iommu_domain",
+ sizeof(struct dmar_domain),
+ 0,
+ SLAB_HWCACHE_ALIGN,
+
+ NULL);
+ if (!iommu_domain_cache) {
+ printk(KERN_ERR "Couldn't create iommu_domain cache\n");
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+static inline int iommu_devinfo_cache_init(void)
+{
+ int ret = 0;
+
+ iommu_devinfo_cache = kmem_cache_create("iommu_devinfo",
+ sizeof(struct device_domain_info),
+ 0,
+ SLAB_HWCACHE_ALIGN,
+
+ NULL);
+ if (!iommu_devinfo_cache) {
+ printk(KERN_ERR "Couldn't create devinfo cache\n");
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+static inline int iommu_iova_cache_init(void)
+{
+ int ret = 0;
+
+ iommu_iova_cache = kmem_cache_create("iommu_iova",
+ sizeof(struct iova),
+ 0,
+ SLAB_HWCACHE_ALIGN,
+
+ NULL);
+ if (!iommu_iova_cache) {
+ printk(KERN_ERR "Couldn't create iova cache\n");
+ ret = -ENOMEM;
+ }
+
+ return ret;
+}
+
+static int __init iommu_init_mempool(void)
+{
+ int ret;
+ ret = iommu_iova_cache_init();
+ if (ret)
+ return ret;
+
+ ret = iommu_domain_cache_init();
+ if (ret)
+ goto domain_error;
+
+ ret = iommu_devinfo_cache_init();
+ if (!ret)
+ return ret;
+
+ kmem_cache_destroy(iommu_domain_cache);
+domain_error:
+ kmem_cache_destroy(iommu_iova_cache);
+
+ return -ENOMEM;
+}
+
+static void __init iommu_exit_mempool(void)
+{
+ kmem_cache_destroy(iommu_devinfo_cache);
+ kmem_cache_destroy(iommu_domain_cache);
+ kmem_cache_destroy(iommu_iova_cache);
+
+}
+
+void __init detect_intel_iommu(void)
+{
+ if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
+ return;
+ if (early_dmar_detect()) {
+ iommu_detected = 1;
+ }
+}
+
+static void __init init_no_remapping_devices(void)
+{
+ struct dmar_drhd_unit *drhd;
+
+ for_each_drhd_unit(drhd) {
+ if (!drhd->include_all) {
+ int i;
+ for (i = 0; i < drhd->devices_cnt; i++)
+ if (drhd->devices[i] != NULL)
+ break;
+ /* ignore DMAR unit if no pci devices exist */
+ if (i == drhd->devices_cnt)
+ drhd->ignored = 1;
+ }
+ }
+
+ if (dmar_map_gfx)
+ return;
+
+ for_each_drhd_unit(drhd) {
+ int i;
+ if (drhd->ignored || drhd->include_all)
+ continue;
+
+ for (i = 0; i < drhd->devices_cnt; i++)
+ if (drhd->devices[i] &&
+ !IS_GFX_DEVICE(drhd->devices[i]))
+ break;
+
+ if (i < drhd->devices_cnt)
+ continue;
+
+ /* bypass IOMMU if it is just for gfx devices */
+ drhd->ignored = 1;
+ for (i = 0; i < drhd->devices_cnt; i++) {
+ if (!drhd->devices[i])
+ continue;
+ drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ }
+ }
+}
+
+int __init intel_iommu_init(void)
+{
+ int ret = 0;
+
+ if (no_iommu || swiotlb || dmar_disabled)
+ return -ENODEV;
+
+ if (dmar_table_init())
+ return -ENODEV;
+
+ iommu_init_mempool();
+ dmar_init_reserved_ranges();
+
+ init_no_remapping_devices();
+
+ ret = init_dmars();
+ if (ret) {
+ printk(KERN_ERR "IOMMU: dmar init failed\n");
+ put_iova_domain(&reserved_iova_list);
+ iommu_exit_mempool();
+ return ret;
+ }
+ printk(KERN_INFO
+ "PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
+
+ force_iommu = 1;
+ dma_ops = &intel_dma_ops;
+ return 0;
+}
+
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h
new file mode 100644
index 00000000000..ee88dd2400c
--- /dev/null
+++ b/drivers/pci/intel-iommu.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#ifndef _INTEL_IOMMU_H_
+#define _INTEL_IOMMU_H_
+
+#include <linux/types.h>
+#include <linux/msi.h>
+#include "iova.h"
+#include <linux/io.h>
+
+/*
+ * Intel IOMMU register specification per version 1.0 public spec.
+ */
+
+#define DMAR_VER_REG 0x0 /* Arch version supported by this IOMMU */
+#define DMAR_CAP_REG 0x8 /* Hardware supported capabilities */
+#define DMAR_ECAP_REG 0x10 /* Extended capabilities supported */
+#define DMAR_GCMD_REG 0x18 /* Global command register */
+#define DMAR_GSTS_REG 0x1c /* Global status register */
+#define DMAR_RTADDR_REG 0x20 /* Root entry table */
+#define DMAR_CCMD_REG 0x28 /* Context command reg */
+#define DMAR_FSTS_REG 0x34 /* Fault Status register */
+#define DMAR_FECTL_REG 0x38 /* Fault control register */
+#define DMAR_FEDATA_REG 0x3c /* Fault event interrupt data register */
+#define DMAR_FEADDR_REG 0x40 /* Fault event interrupt addr register */
+#define DMAR_FEUADDR_REG 0x44 /* Upper address register */
+#define DMAR_AFLOG_REG 0x58 /* Advanced Fault control */
+#define DMAR_PMEN_REG 0x64 /* Enable Protected Memory Region */
+#define DMAR_PLMBASE_REG 0x68 /* PMRR Low addr */
+#define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */
+#define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */
+#define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */
+
+#define OFFSET_STRIDE (9)
+/*
+#define dmar_readl(dmar, reg) readl(dmar + reg)
+#define dmar_readq(dmar, reg) ({ \
+ u32 lo, hi; \
+ lo = readl(dmar + reg); \
+ hi = readl(dmar + reg + 4); \
+ (((u64) hi) << 32) + lo; })
+*/
+static inline u64 dmar_readq(void *addr)
+{
+ u32 lo, hi;
+ lo = readl(addr);
+ hi = readl(addr + 4);
+ return (((u64) hi) << 32) + lo;
+}
+
+static inline void dmar_writeq(void __iomem *addr, u64 val)
+{
+ writel((u32)val, addr);
+ writel((u32)(val >> 32), addr + 4);
+}
+
+#define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4)
+#define DMAR_VER_MINOR(v) ((v) & 0x0f)
+
+/*
+ * Decoding Capability Register
+ */
+#define cap_read_drain(c) (((c) >> 55) & 1)
+#define cap_write_drain(c) (((c) >> 54) & 1)
+#define cap_max_amask_val(c) (((c) >> 48) & 0x3f)
+#define cap_num_fault_regs(c) ((((c) >> 40) & 0xff) + 1)
+#define cap_pgsel_inv(c) (((c) >> 39) & 1)
+
+#define cap_super_page_val(c) (((c) >> 34) & 0xf)
+#define cap_super_offset(c) (((find_first_bit(&cap_super_page_val(c), 4)) \
+ * OFFSET_STRIDE) + 21)
+
+#define cap_fault_reg_offset(c) ((((c) >> 24) & 0x3ff) * 16)
+#define cap_max_fault_reg_offset(c) \
+ (cap_fault_reg_offset(c) + cap_num_fault_regs(c) * 16)
+
+#define cap_zlr(c) (((c) >> 22) & 1)
+#define cap_isoch(c) (((c) >> 23) & 1)
+#define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1)
+#define cap_sagaw(c) (((c) >> 8) & 0x1f)
+#define cap_caching_mode(c) (((c) >> 7) & 1)
+#define cap_phmr(c) (((c) >> 6) & 1)
+#define cap_plmr(c) (((c) >> 5) & 1)
+#define cap_rwbf(c) (((c) >> 4) & 1)
+#define cap_afl(c) (((c) >> 3) & 1)
+#define cap_ndoms(c) (((unsigned long)1) << (4 + 2 * ((c) & 0x7)))
+/*
+ * Extended Capability Register
+ */
+
+#define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1)
+#define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16)
+#define ecap_max_iotlb_offset(e) \
+ (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16)
+#define ecap_coherent(e) ((e) & 0x1)
+
+
+/* IOTLB_REG */
+#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60)
+#define DMA_TLB_DSI_FLUSH (((u64)2) << 60)
+#define DMA_TLB_PSI_FLUSH (((u64)3) << 60)
+#define DMA_TLB_IIRG(type) ((type >> 60) & 7)
+#define DMA_TLB_IAIG(val) (((val) >> 57) & 7)
+#define DMA_TLB_READ_DRAIN (((u64)1) << 49)
+#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48)
+#define DMA_TLB_DID(id) (((u64)((id) & 0xffff)) << 32)
+#define DMA_TLB_IVT (((u64)1) << 63)
+#define DMA_TLB_IH_NONLEAF (((u64)1) << 6)
+#define DMA_TLB_MAX_SIZE (0x3f)
+
+/* GCMD_REG */
+#define DMA_GCMD_TE (((u32)1) << 31)
+#define DMA_GCMD_SRTP (((u32)1) << 30)
+#define DMA_GCMD_SFL (((u32)1) << 29)
+#define DMA_GCMD_EAFL (((u32)1) << 28)
+#define DMA_GCMD_WBF (((u32)1) << 27)
+
+/* GSTS_REG */
+#define DMA_GSTS_TES (((u32)1) << 31)
+#define DMA_GSTS_RTPS (((u32)1) << 30)
+#define DMA_GSTS_FLS (((u32)1) << 29)
+#define DMA_GSTS_AFLS (((u32)1) << 28)
+#define DMA_GSTS_WBFS (((u32)1) << 27)
+
+/* CCMD_REG */
+#define DMA_CCMD_ICC (((u64)1) << 63)
+#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61)
+#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61)
+#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61)
+#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32)
+#define DMA_CCMD_MASK_NOBIT 0
+#define DMA_CCMD_MASK_1BIT 1
+#define DMA_CCMD_MASK_2BIT 2
+#define DMA_CCMD_MASK_3BIT 3
+#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16)
+#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff))
+
+/* FECTL_REG */
+#define DMA_FECTL_IM (((u32)1) << 31)
+
+/* FSTS_REG */
+#define DMA_FSTS_PPF ((u32)2)
+#define DMA_FSTS_PFO ((u32)1)
+#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff)
+
+/* FRCD_REG, 32 bits access */
+#define DMA_FRCD_F (((u32)1) << 31)
+#define dma_frcd_type(d) ((d >> 30) & 1)
+#define dma_frcd_fault_reason(c) (c & 0xff)
+#define dma_frcd_source_id(c) (c & 0xffff)
+#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */
+
+/*
+ * 0: Present
+ * 1-11: Reserved
+ * 12-63: Context Ptr (12 - (haw-1))
+ * 64-127: Reserved
+ */
+struct root_entry {
+ u64 val;
+ u64 rsvd1;
+};
+#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry))
+static inline bool root_present(struct root_entry *root)
+{
+ return (root->val & 1);
+}
+static inline void set_root_present(struct root_entry *root)
+{
+ root->val |= 1;
+}
+static inline void set_root_value(struct root_entry *root, unsigned long value)
+{
+ root->val |= value & PAGE_MASK_4K;
+}
+
+struct context_entry;
+static inline struct context_entry *
+get_context_addr_from_root(struct root_entry *root)
+{
+ return (struct context_entry *)
+ (root_present(root)?phys_to_virt(
+ root->val & PAGE_MASK_4K):
+ NULL);
+}
+
+/*
+ * low 64 bits:
+ * 0: present
+ * 1: fault processing disable
+ * 2-3: translation type
+ * 12-63: address space root
+ * high 64 bits:
+ * 0-2: address width
+ * 3-6: aval
+ * 8-23: domain id
+ */
+struct context_entry {
+ u64 lo;
+ u64 hi;
+};
+#define context_present(c) ((c).lo & 1)
+#define context_fault_disable(c) (((c).lo >> 1) & 1)
+#define context_translation_type(c) (((c).lo >> 2) & 3)
+#define context_address_root(c) ((c).lo & PAGE_MASK_4K)
+#define context_address_width(c) ((c).hi & 7)
+#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1))
+
+#define context_set_present(c) do {(c).lo |= 1;} while (0)
+#define context_set_fault_enable(c) \
+ do {(c).lo &= (((u64)-1) << 2) | 1;} while (0)
+#define context_set_translation_type(c, val) \
+ do { \
+ (c).lo &= (((u64)-1) << 4) | 3; \
+ (c).lo |= ((val) & 3) << 2; \
+ } while (0)
+#define CONTEXT_TT_MULTI_LEVEL 0
+#define context_set_address_root(c, val) \
+ do {(c).lo |= (val) & PAGE_MASK_4K;} while (0)
+#define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0)
+#define context_set_domain_id(c, val) \
+ do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0)
+#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0)
+
+/*
+ * 0: readable
+ * 1: writable
+ * 2-6: reserved
+ * 7: super page
+ * 8-11: available
+ * 12-63: Host physcial address
+ */
+struct dma_pte {
+ u64 val;
+};
+#define dma_clear_pte(p) do {(p).val = 0;} while (0)
+
+#define DMA_PTE_READ (1)
+#define DMA_PTE_WRITE (2)
+
+#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0)
+#define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0)
+#define dma_set_pte_prot(p, prot) \
+ do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0)
+#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K)
+#define dma_set_pte_addr(p, addr) do {\
+ (p).val |= ((addr) & PAGE_MASK_4K); } while (0)
+#define dma_pte_present(p) (((p).val & 3) != 0)
+
+struct intel_iommu;
+
+struct dmar_domain {
+ int id; /* domain id */
+ struct intel_iommu *iommu; /* back pointer to owning iommu */
+
+ struct list_head devices; /* all devices' list */
+ struct iova_domain iovad; /* iova's that belong to this domain */
+
+ struct dma_pte *pgd; /* virtual address */
+ spinlock_t mapping_lock; /* page table lock */
+ int gaw; /* max guest address width */
+
+ /* adjusted guest address width, 0 is level 2 30-bit */
+ int agaw;
+
+#define DOMAIN_FLAG_MULTIPLE_DEVICES 1
+ int flags;
+};
+
+/* PCI domain-device relationship */
+struct device_domain_info {
+ struct list_head link; /* link to domain siblings */
+ struct list_head global; /* link to global list */
+ u8 bus; /* PCI bus numer */
+ u8 devfn; /* PCI devfn number */
+ struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
+ struct dmar_domain *domain; /* pointer to domain */
+};
+
+extern int init_dmars(void);
+
+struct intel_iommu {
+ void __iomem *reg; /* Pointer to hardware regs, virtual addr */
+ u64 cap;
+ u64 ecap;
+ unsigned long *domain_ids; /* bitmap of domains */
+ struct dmar_domain **domains; /* ptr to domains */
+ int seg;
+ u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
+ spinlock_t lock; /* protect context, domain ids */
+ spinlock_t register_lock; /* protect register handling */
+ struct root_entry *root_entry; /* virtual address */
+
+ unsigned int irq;
+ unsigned char name[7]; /* Device Name */
+ struct msi_msg saved_msg;
+ struct sys_device sysdev;
+};
+
+#ifndef CONFIG_DMAR_GFX_WA
+static inline void iommu_prepare_gfx_mapping(void)
+{
+ return;
+}
+#endif /* !CONFIG_DMAR_GFX_WA */
+
+#endif
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c
new file mode 100644
index 00000000000..a84571c2936
--- /dev/null
+++ b/drivers/pci/iova.c
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ */
+
+#include "iova.h"
+
+void
+init_iova_domain(struct iova_domain *iovad)
+{
+ spin_lock_init(&iovad->iova_alloc_lock);
+ spin_lock_init(&iovad->iova_rbtree_lock);
+ iovad->rbroot = RB_ROOT;
+ iovad->cached32_node = NULL;
+
+}
+
+static struct rb_node *
+__get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
+{
+ if ((*limit_pfn != DMA_32BIT_PFN) ||
+ (iovad->cached32_node == NULL))
+ return rb_last(&iovad->rbroot);
+ else {
+ struct rb_node *prev_node = rb_prev(iovad->cached32_node);
+ struct iova *curr_iova =
+ container_of(iovad->cached32_node, struct iova, node);
+ *limit_pfn = curr_iova->pfn_lo - 1;
+ return prev_node;
+ }
+}
+
+static void
+__cached_rbnode_insert_update(struct iova_domain *iovad,
+ unsigned long limit_pfn, struct iova *new)
+{
+ if (limit_pfn != DMA_32BIT_PFN)
+ return;
+ iovad->cached32_node = &new->node;
+}
+
+static void
+__cached_rbnode_delete_update(struct iova_domain *iovad, struct iova *free)
+{
+ struct iova *cached_iova;
+ struct rb_node *curr;
+
+ if (!iovad->cached32_node)
+ return;
+ curr = iovad->cached32_node;
+ cached_iova = container_of(curr, struct iova, node);
+
+ if (free->pfn_lo >= cached_iova->pfn_lo)
+ iovad->cached32_node = rb_next(&free->node);
+}
+
+/* Computes the padding size required, to make the
+ * the start address naturally aligned on its size
+ */
+static int
+iova_get_pad_size(int size, unsigned int limit_pfn)
+{
+ unsigned int pad_size = 0;
+ unsigned int order = ilog2(size);
+
+ if (order)
+ pad_size = (limit_pfn + 1) % (1 << order);
+
+ return pad_size;
+}
+
+static int __alloc_iova_range(struct iova_domain *iovad, unsigned long size,
+ unsigned long limit_pfn, struct iova *new, bool size_aligned)
+{
+ struct rb_node *curr = NULL;
+ unsigned long flags;
+ unsigned long saved_pfn;
+ unsigned int pad_size = 0;
+
+ /* Walk the tree backwards */
+ spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+ saved_pfn = limit_pfn;
+ curr = __get_cached_rbnode(iovad, &limit_pfn);
+ while (curr) {
+ struct iova *curr_iova = container_of(curr, struct iova, node);
+ if (limit_pfn < curr_iova->pfn_lo)
+ goto move_left;
+ else if (limit_pfn < curr_iova->pfn_hi)
+ goto adjust_limit_pfn;
+ else {
+ if (size_aligned)
+ pad_size = iova_get_pad_size(size, limit_pfn);
+ if ((curr_iova->pfn_hi + size + pad_size) <= limit_pfn)
+ break; /* found a free slot */
+ }
+adjust_limit_pfn:
+ limit_pfn = curr_iova->pfn_lo - 1;
+move_left:
+ curr = rb_prev(curr);
+ }
+
+ if (!curr) {
+ if (size_aligned)
+ pad_size = iova_get_pad_size(size, limit_pfn);
+ if ((IOVA_START_PFN + size + pad_size) > limit_pfn) {
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+ return -ENOMEM;
+ }
+ }
+
+ /* pfn_lo will point to size aligned address if size_aligned is set */
+ new->pfn_lo = limit_pfn - (size + pad_size) + 1;
+ new->pfn_hi = new->pfn_lo + size - 1;
+
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+ return 0;
+}
+
+static void
+iova_insert_rbtree(struct rb_root *root, struct iova *iova)
+{
+ struct rb_node **new = &(root->rb_node), *parent = NULL;
+ /* Figure out where to put new node */
+ while (*new) {
+ struct iova *this = container_of(*new, struct iova, node);
+ parent = *new;
+
+ if (iova->pfn_lo < this->pfn_lo)
+ new = &((*new)->rb_left);
+ else if (iova->pfn_lo > this->pfn_lo)
+ new = &((*new)->rb_right);
+ else
+ BUG(); /* this should not happen */
+ }
+ /* Add new node and rebalance tree. */
+ rb_link_node(&iova->node, parent, new);
+ rb_insert_color(&iova->node, root);
+}
+
+/**
+ * alloc_iova - allocates an iova
+ * @iovad - iova domain in question
+ * @size - size of page frames to allocate
+ * @limit_pfn - max limit address
+ * @size_aligned - set if size_aligned address range is required
+ * This function allocates an iova in the range limit_pfn to IOVA_START_PFN
+ * looking from limit_pfn instead from IOVA_START_PFN. If the size_aligned
+ * flag is set then the allocated address iova->pfn_lo will be naturally
+ * aligned on roundup_power_of_two(size).
+ */
+struct iova *
+alloc_iova(struct iova_domain *iovad, unsigned long size,
+ unsigned long limit_pfn,
+ bool size_aligned)
+{
+ unsigned long flags;
+ struct iova *new_iova;
+ int ret;
+
+ new_iova = alloc_iova_mem();
+ if (!new_iova)
+ return NULL;
+
+ /* If size aligned is set then round the size to
+ * to next power of two.
+ */
+ if (size_aligned)
+ size = __roundup_pow_of_two(size);
+
+ spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+ ret = __alloc_iova_range(iovad, size, limit_pfn, new_iova,
+ size_aligned);
+
+ if (ret) {
+ spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+ free_iova_mem(new_iova);
+ return NULL;
+ }
+
+ /* Insert the new_iova into domain rbtree by holding writer lock */
+ spin_lock(&iovad->iova_rbtree_lock);
+ iova_insert_rbtree(&iovad->rbroot, new_iova);
+ __cached_rbnode_insert_update(iovad, limit_pfn, new_iova);
+ spin_unlock(&iovad->iova_rbtree_lock);
+
+ spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+
+ return new_iova;
+}
+
+/**
+ * find_iova - find's an iova for a given pfn
+ * @iovad - iova domain in question.
+ * pfn - page frame number
+ * This function finds and returns an iova belonging to the
+ * given doamin which matches the given pfn.
+ */
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+ unsigned long flags;
+ struct rb_node *node;
+
+ /* Take the lock so that no other thread is manipulating the rbtree */
+ spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+ node = iovad->rbroot.rb_node;
+ while (node) {
+ struct iova *iova = container_of(node, struct iova, node);
+
+ /* If pfn falls within iova's range, return iova */
+ if ((pfn >= iova->pfn_lo) && (pfn <= iova->pfn_hi)) {
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+ /* We are not holding the lock while this iova
+ * is referenced by the caller as the same thread
+ * which called this function also calls __free_iova()
+ * and it is by desing that only one thread can possibly
+ * reference a particular iova and hence no conflict.
+ */
+ return iova;
+ }
+
+ if (pfn < iova->pfn_lo)
+ node = node->rb_left;
+ else if (pfn > iova->pfn_lo)
+ node = node->rb_right;
+ }
+
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+ return NULL;
+}
+
+/**
+ * __free_iova - frees the given iova
+ * @iovad: iova domain in question.
+ * @iova: iova in question.
+ * Frees the given iova belonging to the giving domain
+ */
+void
+__free_iova(struct iova_domain *iovad, struct iova *iova)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+ __cached_rbnode_delete_update(iovad, iova);
+ rb_erase(&iova->node, &iovad->rbroot);
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+ free_iova_mem(iova);
+}
+
+/**
+ * free_iova - finds and frees the iova for a given pfn
+ * @iovad: - iova domain in question.
+ * @pfn: - pfn that is allocated previously
+ * This functions finds an iova for a given pfn and then
+ * frees the iova from that domain.
+ */
+void
+free_iova(struct iova_domain *iovad, unsigned long pfn)
+{
+ struct iova *iova = find_iova(iovad, pfn);
+ if (iova)
+ __free_iova(iovad, iova);
+
+}
+
+/**
+ * put_iova_domain - destroys the iova doamin
+ * @iovad: - iova domain in question.
+ * All the iova's in that domain are destroyed.
+ */
+void put_iova_domain(struct iova_domain *iovad)
+{
+ struct rb_node *node;
+ unsigned long flags;
+
+ spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
+ node = rb_first(&iovad->rbroot);
+ while (node) {
+ struct iova *iova = container_of(node, struct iova, node);
+ rb_erase(node, &iovad->rbroot);
+ free_iova_mem(iova);
+ node = rb_first(&iovad->rbroot);
+ }
+ spin_unlock_irqrestore(&iovad->iova_rbtree_lock, flags);
+}
+
+static int
+__is_range_overlap(struct rb_node *node,
+ unsigned long pfn_lo, unsigned long pfn_hi)
+{
+ struct iova *iova = container_of(node, struct iova, node);
+
+ if ((pfn_lo <= iova->pfn_hi) && (pfn_hi >= iova->pfn_lo))
+ return 1;
+ return 0;
+}
+
+static struct iova *
+__insert_new_range(struct iova_domain *iovad,
+ unsigned long pfn_lo, unsigned long pfn_hi)
+{
+ struct iova *iova;
+
+ iova = alloc_iova_mem();
+ if (!iova)
+ return iova;
+
+ iova->pfn_hi = pfn_hi;
+ iova->pfn_lo = pfn_lo;
+ iova_insert_rbtree(&iovad->rbroot, iova);
+ return iova;
+}
+
+static void
+__adjust_overlap_range(struct iova *iova,
+ unsigned long *pfn_lo, unsigned long *pfn_hi)
+{
+ if (*pfn_lo < iova->pfn_lo)
+ iova->pfn_lo = *pfn_lo;
+ if (*pfn_hi > iova->pfn_hi)
+ *pfn_lo = iova->pfn_hi + 1;
+}
+
+/**
+ * reserve_iova - reserves an iova in the given range
+ * @iovad: - iova domain pointer
+ * @pfn_lo: - lower page frame address
+ * @pfn_hi:- higher pfn adderss
+ * This function allocates reserves the address range from pfn_lo to pfn_hi so
+ * that this address is not dished out as part of alloc_iova.
+ */
+struct iova *
+reserve_iova(struct iova_domain *iovad,
+ unsigned long pfn_lo, unsigned long pfn_hi)
+{
+ struct rb_node *node;
+ unsigned long flags;
+ struct iova *iova;
+ unsigned int overlap = 0;
+
+ spin_lock_irqsave(&iovad->iova_alloc_lock, flags);
+ spin_lock(&iovad->iova_rbtree_lock);
+ for (node = rb_first(&iovad->rbroot); node; node = rb_next(node)) {
+ if (__is_range_overlap(node, pfn_lo, pfn_hi)) {
+ iova = container_of(node, struct iova, node);
+ __adjust_overlap_range(iova, &pfn_lo, &pfn_hi);
+ if ((pfn_lo >= iova->pfn_lo) &&
+ (pfn_hi <= iova->pfn_hi))
+ goto finish;
+ overlap = 1;
+
+ } else if (overlap)
+ break;
+ }
+
+ /* We are here either becasue this is the first reserver node
+ * or need to insert remaining non overlap addr range
+ */
+ iova = __insert_new_range(iovad, pfn_lo, pfn_hi);
+finish:
+
+ spin_unlock(&iovad->iova_rbtree_lock);
+ spin_unlock_irqrestore(&iovad->iova_alloc_lock, flags);
+ return iova;
+}
+
+/**
+ * copy_reserved_iova - copies the reserved between domains
+ * @from: - source doamin from where to copy
+ * @to: - destination domin where to copy
+ * This function copies reserved iova's from one doamin to
+ * other.
+ */
+void
+copy_reserved_iova(struct iova_domain *from, struct iova_domain *to)
+{
+ unsigned long flags;
+ struct rb_node *node;
+
+ spin_lock_irqsave(&from->iova_alloc_lock, flags);
+ spin_lock(&from->iova_rbtree_lock);
+ for (node = rb_first(&from->rbroot); node; node = rb_next(node)) {
+ struct iova *iova = container_of(node, struct iova, node);
+ struct iova *new_iova;
+ new_iova = reserve_iova(to, iova->pfn_lo, iova->pfn_hi);
+ if (!new_iova)
+ printk(KERN_ERR "Reserve iova range %lx@%lx failed\n",
+ iova->pfn_lo, iova->pfn_lo);
+ }
+ spin_unlock(&from->iova_rbtree_lock);
+ spin_unlock_irqrestore(&from->iova_alloc_lock, flags);
+}
diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h
new file mode 100644
index 00000000000..ae3028d5a94
--- /dev/null
+++ b/drivers/pci/iova.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This file is released under the GPLv2.
+ *
+ * Copyright (C) 2006 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
+ *
+ */
+
+#ifndef _IOVA_H_
+#define _IOVA_H_
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/rbtree.h>
+#include <linux/dma-mapping.h>
+
+/*
+ * We need a fixed PAGE_SIZE of 4K irrespective of
+ * arch PAGE_SIZE for IOMMU page tables.
+ */
+#define PAGE_SHIFT_4K (12)
+#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K)
+#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K)
+#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K)
+
+/* IO virtual address start page frame number */
+#define IOVA_START_PFN (1)
+
+#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K)
+#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK)
+#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK)
+
+/* iova structure */
+struct iova {
+ struct rb_node node;
+ unsigned long pfn_hi; /* IOMMU dish out addr hi */
+ unsigned long pfn_lo; /* IOMMU dish out addr lo */
+};
+
+/* holds all the iova translations for a domain */
+struct iova_domain {
+ spinlock_t iova_alloc_lock;/* Lock to protect iova allocation */
+ spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */
+ struct rb_root rbroot; /* iova domain rbtree root */
+ struct rb_node *cached32_node; /* Save last alloced node */
+};
+
+struct iova *alloc_iova_mem(void);
+void free_iova_mem(struct iova *iova);
+void free_iova(struct iova_domain *iovad, unsigned long pfn);
+void __free_iova(struct iova_domain *iovad, struct iova *iova);
+struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size,
+ unsigned long limit_pfn,
+ bool size_aligned);
+struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo,
+ unsigned long pfn_hi);
+void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
+void init_iova_domain(struct iova_domain *iovad);
+struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
+void put_iova_domain(struct iova_domain *iovad);
+
+#endif
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 6fda33de84e..fc87e14b50d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -90,3 +90,4 @@ pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
return NULL;
}
+struct pci_dev *pci_find_upstream_pcie_bridge(struct pci_dev *pdev);
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 5db6b6690b5..463a5a9d583 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -837,6 +837,19 @@ static void pci_release_dev(struct device *dev)
kfree(pci_dev);
}
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+ int pos;
+ u16 reg16;
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!pos)
+ return;
+ pdev->is_pcie = 1;
+ pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+ pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device
@@ -951,6 +964,7 @@ pci_scan_device(struct pci_bus *bus, int devfn)
dev->device = (l >> 16) & 0xffff;
dev->cfg_size = pci_cfg_space_size(dev);
dev->error_state = pci_channel_io_normal;
+ set_pcie_port_type(dev);
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index c6e79d01ce3..b001b5922e3 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -14,6 +14,40 @@
#include "pci.h"
DECLARE_RWSEM(pci_bus_sem);
+/*
+ * find the upstream PCIE-to-PCI bridge of a PCI device
+ * if the device is PCIE, return NULL
+ * if the device isn't connected to a PCIE bridge (that is its parent is a
+ * legacy PCI bridge and the bridge is directly connected to bus 0), return its
+ * parent
+ */
+struct pci_dev *
+pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
+{
+ struct pci_dev *tmp = NULL;
+
+ if (pdev->is_pcie)
+ return NULL;
+ while (1) {
+ if (!pdev->bus->self)
+ break;
+ pdev = pdev->bus->self;
+ /* a p2p bridge */
+ if (!pdev->is_pcie) {
+ tmp = pdev;
+ continue;
+ }
+ /* PCI device should connect to a PCIE bridge */
+ if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) {
+ /* Busted hardware? */
+ WARN_ON_ONCE(1);
+ return NULL;
+ }
+ return pdev;
+ }
+
+ return tmp;
+}
static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr)
{
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 67d28ee80f2..c5e0d89c3ec 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -22,9 +22,9 @@
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/bitops.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/bitops.h>
#include <asm/system.h>
#include <asm/addrspace.h>
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c
index b0198549846..d182760f035 100644
--- a/drivers/pcmcia/m8xx_pcmcia.c
+++ b/drivers/pcmcia/m8xx_pcmcia.c
@@ -48,9 +48,9 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/fsl_devices.h>
+#include <linux/bitops.h>
#include <asm/io.h>
-#include <asm/bitops.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/mpc8xx.h>
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
index 39a90a6f0f8..bbf3ee10da0 100644
--- a/drivers/power/apm_power.c
+++ b/drivers/power/apm_power.c
@@ -26,65 +26,124 @@ static struct power_supply *main_battery;
static void find_main_battery(void)
{
struct device *dev;
- struct power_supply *bat, *batm;
+ struct power_supply *bat = NULL;
+ struct power_supply *max_charge_bat = NULL;
+ struct power_supply *max_energy_bat = NULL;
union power_supply_propval full;
int max_charge = 0;
+ int max_energy = 0;
main_battery = NULL;
- batm = NULL;
+
list_for_each_entry(dev, &power_supply_class->devices, node) {
bat = dev_get_drvdata(dev);
- /* If none of battery devices cantains 'use_for_apm' flag,
- choice one with maximum design charge */
- if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full)) {
+
+ if (bat->use_for_apm) {
+ /* nice, we explicitly asked to report this battery. */
+ main_battery = bat;
+ return;
+ }
+
+ if (!PSY_PROP(bat, CHARGE_FULL_DESIGN, &full) ||
+ !PSY_PROP(bat, CHARGE_FULL, &full)) {
if (full.intval > max_charge) {
- batm = bat;
+ max_charge_bat = bat;
max_charge = full.intval;
}
+ } else if (!PSY_PROP(bat, ENERGY_FULL_DESIGN, &full) ||
+ !PSY_PROP(bat, ENERGY_FULL, &full)) {
+ if (full.intval > max_energy) {
+ max_energy_bat = bat;
+ max_energy = full.intval;
+ }
}
+ }
- if (bat->use_for_apm)
- main_battery = bat;
+ if ((max_energy_bat && max_charge_bat) &&
+ (max_energy_bat != max_charge_bat)) {
+ /* try guess battery with more capacity */
+ if (!PSY_PROP(max_charge_bat, VOLTAGE_MAX_DESIGN, &full)) {
+ if (max_energy > max_charge * full.intval)
+ main_battery = max_energy_bat;
+ else
+ main_battery = max_charge_bat;
+ } else if (!PSY_PROP(max_energy_bat, VOLTAGE_MAX_DESIGN,
+ &full)) {
+ if (max_charge > max_energy / full.intval)
+ main_battery = max_charge_bat;
+ else
+ main_battery = max_energy_bat;
+ } else {
+ /* give up, choice any */
+ main_battery = max_energy_bat;
+ }
+ } else if (max_charge_bat) {
+ main_battery = max_charge_bat;
+ } else if (max_energy_bat) {
+ main_battery = max_energy_bat;
+ } else {
+ /* give up, try the last if any */
+ main_battery = bat;
}
- if (!main_battery)
- main_battery = batm;
}
-static int calculate_time(int status)
+static int calculate_time(int status, int using_charge)
{
- union power_supply_propval charge_full, charge_empty;
- union power_supply_propval charge, I;
+ union power_supply_propval full;
+ union power_supply_propval empty;
+ union power_supply_propval cur;
+ union power_supply_propval I;
+ enum power_supply_property full_prop;
+ enum power_supply_property full_design_prop;
+ enum power_supply_property empty_prop;
+ enum power_supply_property empty_design_prop;
+ enum power_supply_property cur_avg_prop;
+ enum power_supply_property cur_now_prop;
- if (MPSY_PROP(CHARGE_FULL, &charge_full)) {
- /* if battery can't report this property, use design value */
- if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full))
+ if (MPSY_PROP(CURRENT_AVG, &I)) {
+ /* if battery can't report average value, use momentary */
+ if (MPSY_PROP(CURRENT_NOW, &I))
return -1;
}
- if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) {
- /* if battery can't report this property, use design value */
- if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty))
- charge_empty.intval = 0;
+ if (using_charge) {
+ full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
+ full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
+ empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
+ cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
+ } else {
+ full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
+ full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
+ empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
+ empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
+ cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
+ cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
}
- if (MPSY_PROP(CHARGE_AVG, &charge)) {
- /* if battery can't report average value, use momentary */
- if (MPSY_PROP(CHARGE_NOW, &charge))
+ if (_MPSY_PROP(full_prop, &full)) {
+ /* if battery can't report this property, use design value */
+ if (_MPSY_PROP(full_design_prop, &full))
return -1;
}
- if (MPSY_PROP(CURRENT_AVG, &I)) {
+ if (_MPSY_PROP(empty_prop, &empty)) {
+ /* if battery can't report this property, use design value */
+ if (_MPSY_PROP(empty_design_prop, &empty))
+ empty.intval = 0;
+ }
+
+ if (_MPSY_PROP(cur_avg_prop, &cur)) {
/* if battery can't report average value, use momentary */
- if (MPSY_PROP(CURRENT_NOW, &I))
+ if (_MPSY_PROP(cur_now_prop, &cur))
return -1;
}
if (status == POWER_SUPPLY_STATUS_CHARGING)
- return ((charge.intval - charge_full.intval) * 60L) /
- I.intval;
+ return ((cur.intval - full.intval) * 60L) / I.intval;
else
- return -((charge.intval - charge_empty.intval) * 60L) /
- I.intval;
+ return -((cur.intval - empty.intval) * 60L) / I.intval;
}
static int calculate_capacity(int using_charge)
@@ -200,18 +259,22 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info)
info->units = APM_UNITS_MINS;
if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
- if (MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full)) {
- if (MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full))
- info->time = calculate_time(status.intval);
- else
- info->time = time_to_full.intval / 60;
+ if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) ||
+ !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) {
+ info->time = time_to_full.intval / 60;
+ } else {
+ info->time = calculate_time(status.intval, 0);
+ if (info->time == -1)
+ info->time = calculate_time(status.intval, 1);
}
} else {
- if (MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty)) {
- if (MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty))
- info->time = calculate_time(status.intval);
- else
- info->time = time_to_empty.intval / 60;
+ if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) ||
+ !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) {
+ info->time = time_to_empty.intval / 60;
+ } else {
+ info->time = calculate_time(status.intval, 0);
+ if (info->time == -1)
+ info->time = calculate_time(status.intval, 1);
}
}
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 397f4ce849d..87b3493d88e 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -729,7 +729,7 @@ static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *
static const struct ps3av_monitor_quirk {
const char *monitor_name;
- u32 clear_60, clear_50, clear_vesa;
+ u32 clear_60;
} ps3av_monitor_quirks[] = {
{
.monitor_name = "DELL 2007WFP",
@@ -757,10 +757,6 @@ static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
quirk->monitor_name);
info->res_60.res_bits &= ~quirk->clear_60;
info->res_60.native &= ~quirk->clear_60;
- info->res_50.res_bits &= ~quirk->clear_50;
- info->res_50.native &= ~quirk->clear_50;
- info->res_vesa.res_bits &= ~quirk->clear_vesa;
- info->res_vesa.native &= ~quirk->clear_vesa;
break;
}
}
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index bea25a1391e..9dea585ef80 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -22,11 +22,11 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
+#include <linux/bitops.h>
#include <asm/ps3.h>
#include <asm/firmware.h>
#include <asm/lv1call.h>
-#include <asm/bitops.h>
#include "vuart.h"
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 6420a90a4a9..cbde770eb12 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -240,7 +240,7 @@ config RTC_DRV_TWL92330
depends on MENELAUS
help
If you say yes here you get support for the RTC on the
- TWL92330 "Menelaus" power mangement chip, used with OMAP2
+ TWL92330 "Menelaus" power management chip, used with OMAP2
platforms. The support is integrated with the rest of
the Menelaus driver; it's not separate module.
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index e4bf68ca96f..2fd49edcc71 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -21,11 +21,11 @@
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <linux/bitops.h>
#include <linux/amba/bus.h>
#include <asm/io.h>
-#include <asm/bitops.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/rtc.h>
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 0918b787c4d..6f1e9a9804b 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -29,8 +29,8 @@
#include <linux/interrupt.h>
#include <linux/string.h>
#include <linux/pm.h>
+#include <linux/bitops.h>
-#include <asm/bitops.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/rtc.h>
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c
index 8b9d68f6e01..5b7385e430e 100644
--- a/drivers/s390/block/dasd_3990_erp.c
+++ b/drivers/s390/block/dasd_3990_erp.c
@@ -40,7 +40,7 @@ struct DCTL_data {
*
* Each bit configuration leading to an action code 2 (Exit with
* programming error or unusual condition indication)
- * are handled as fatal errors.
+ * are handled as fatal errors.
*
* All other configurations are handled as recoverable errors.
*
@@ -2001,7 +2001,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense)
switch (sense[28]) {
case 0x17:
/* issue a Diagnostic Control command with an
- * Inhibit Write subcommand and controler modifier */
+ * Inhibit Write subcommand and controller modifier */
erp = dasd_3990_erp_DCTL(erp, 0x20);
break;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 2edd5fb6d3d..8d1c64a24de 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -48,8 +48,8 @@ struct raw3270 {
struct timer_list timer; /* Device timer. */
unsigned char *ascebc; /* ascii -> ebcdic table */
- struct class_device *clttydev; /* 3270-class tty device ptr */
- struct class_device *cltubdev; /* 3270-class tub device ptr */
+ struct device *clttydev; /* 3270-class tty device ptr */
+ struct device *cltubdev; /* 3270-class tub device ptr */
struct raw3270_request init_request;
unsigned char init_data[256];
@@ -1107,11 +1107,9 @@ raw3270_delete_device(struct raw3270 *rp)
/* Remove from device chain. */
mutex_lock(&raw3270_mutex);
if (rp->clttydev && !IS_ERR(rp->clttydev))
- class_device_destroy(class3270,
- MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+ device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
if (rp->cltubdev && !IS_ERR(rp->cltubdev))
- class_device_destroy(class3270,
- MKDEV(IBM_FS3270_MAJOR, rp->minor));
+ device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor));
list_del_init(&rp->list);
mutex_unlock(&raw3270_mutex);
@@ -1181,24 +1179,22 @@ static int raw3270_create_attributes(struct raw3270 *rp)
if (rc)
goto out;
- rp->clttydev = class_device_create(class3270, NULL,
- MKDEV(IBM_TTY3270_MAJOR, rp->minor),
- &rp->cdev->dev, "tty%s",
- rp->cdev->dev.bus_id);
+ rp->clttydev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+ "tty%s", rp->cdev->dev.bus_id);
if (IS_ERR(rp->clttydev)) {
rc = PTR_ERR(rp->clttydev);
goto out_ttydev;
}
- rp->cltubdev = class_device_create(class3270, NULL,
- MKDEV(IBM_FS3270_MAJOR, rp->minor),
- &rp->cdev->dev, "tub%s",
- rp->cdev->dev.bus_id);
+ rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor),
+ "tub%s", rp->cdev->dev.bus_id);
if (!IS_ERR(rp->cltubdev))
goto out;
rc = PTR_ERR(rp->cltubdev);
- class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
+ device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor));
out_ttydev:
sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c
index 29fe2a5ec2f..82a13d9fdfe 100644
--- a/drivers/s390/char/sclp_cpi.c
+++ b/drivers/s390/char/sclp_cpi.c
@@ -157,7 +157,7 @@ cpi_prepare_req(void)
sclp_ascebc_str(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
EBC_TOUPPER(evb->system_name, CPI_LENGTH_SYSTEM_NAME);
- /* set sytem level */
+ /* set system level */
evb->system_level = LINUX_VERSION_CODE;
/* set sysplex name */
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 2e0d29730b6..aa7f166f403 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -69,12 +69,9 @@ struct tape_class_device *register_tape_dev(
if (rc)
goto fail_with_cdev;
- tcd->class_device = class_device_create(
- tape_class,
- NULL,
- tcd->char_device->dev,
- device,
- "%s", tcd->device_name
+ tcd->class_device = device_create(tape_class, device,
+ tcd->char_device->dev,
+ "%s", tcd->device_name
);
rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
if (rc)
@@ -90,7 +87,7 @@ struct tape_class_device *register_tape_dev(
return tcd;
fail_with_class_device:
- class_device_destroy(tape_class, tcd->char_device->dev);
+ device_destroy(tape_class, tcd->char_device->dev);
fail_with_cdev:
cdev_del(tcd->char_device);
@@ -105,11 +102,9 @@ EXPORT_SYMBOL(register_tape_dev);
void unregister_tape_dev(struct tape_class_device *tcd)
{
if (tcd != NULL && !IS_ERR(tcd)) {
- sysfs_remove_link(
- &tcd->class_device->dev->kobj,
- tcd->mode_name
- );
- class_device_destroy(tape_class, tcd->char_device->dev);
+ sysfs_remove_link(&tcd->class_device->kobj,
+ tcd->mode_name);
+ device_destroy(tape_class, tcd->char_device->dev);
cdev_del(tcd->char_device);
kfree(tcd);
}
diff --git a/drivers/s390/char/tape_class.h b/drivers/s390/char/tape_class.h
index a8bd9b47fad..e2b5ac918ac 100644
--- a/drivers/s390/char/tape_class.h
+++ b/drivers/s390/char/tape_class.h
@@ -24,8 +24,8 @@
#define TAPECLASS_NAME_LEN 32
struct tape_class_device {
- struct cdev * char_device;
- struct class_device * class_device;
+ struct cdev *char_device;
+ struct device *class_device;
char device_name[TAPECLASS_NAME_LEN];
char mode_name[TAPECLASS_NAME_LEN];
};
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 12f7a4ce82c..e0c4c508e12 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -74,7 +74,7 @@ struct vmlogrdr_priv_t {
int dev_in_use; /* 1: already opened, 0: not opened*/
spinlock_t priv_lock;
struct device *device;
- struct class_device *class_device;
+ struct device *class_device;
int autorecording;
int autopurge;
};
@@ -762,12 +762,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
device_unregister(dev);
return ret;
}
- priv->class_device = class_device_create(
- vmlogrdr_class,
- NULL,
- MKDEV(vmlogrdr_major, priv->minor_num),
- dev,
- "%s", dev->bus_id );
+ priv->class_device = device_create(vmlogrdr_class, dev,
+ MKDEV(vmlogrdr_major,
+ priv->minor_num),
+ "%s", dev->bus_id);
if (IS_ERR(priv->class_device)) {
ret = PTR_ERR(priv->class_device);
priv->class_device=NULL;
@@ -783,8 +781,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
static int vmlogrdr_unregister_device(struct vmlogrdr_priv_t *priv)
{
- class_device_destroy(vmlogrdr_class,
- MKDEV(vmlogrdr_major, priv->minor_num));
+ device_destroy(vmlogrdr_class, MKDEV(vmlogrdr_major, priv->minor_num));
if (priv->device != NULL) {
sysfs_remove_group(&priv->device->kobj, &vmlogrdr_attr_group);
device_unregister(priv->device);
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 42c1f4659ad..297cdceb0ca 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -246,7 +246,7 @@ int chp_add_cmg_attr(struct channel_path *chp)
static ssize_t chp_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct channel_path *chp = container_of(dev, struct channel_path, dev);
+ struct channel_path *chp = to_channelpath(dev);
if (!chp)
return 0;
@@ -258,7 +258,7 @@ static ssize_t chp_status_write(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- struct channel_path *cp = container_of(dev, struct channel_path, dev);
+ struct channel_path *cp = to_channelpath(dev);
char cmd[10];
int num_args;
int error;
@@ -286,7 +286,7 @@ static ssize_t chp_configure_show(struct device *dev,
struct channel_path *cp;
int status;
- cp = container_of(dev, struct channel_path, dev);
+ cp = to_channelpath(dev);
status = chp_info_get_status(cp->chpid);
if (status < 0)
return status;
@@ -308,7 +308,7 @@ static ssize_t chp_configure_write(struct device *dev,
return -EINVAL;
if (val != 0 && val != 1)
return -EINVAL;
- cp = container_of(dev, struct channel_path, dev);
+ cp = to_channelpath(dev);
chp_cfg_schedule(cp->chpid, val);
cfg_wait_idle();
@@ -320,7 +320,7 @@ static DEVICE_ATTR(configure, 0644, chp_configure_show, chp_configure_write);
static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct channel_path *chp = container_of(dev, struct channel_path, dev);
+ struct channel_path *chp = to_channelpath(dev);
if (!chp)
return 0;
@@ -374,7 +374,7 @@ static void chp_release(struct device *dev)
{
struct channel_path *cp;
- cp = container_of(dev, struct channel_path, dev);
+ cp = to_channelpath(dev);
kfree(cp);
}
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index b960f66843e..725b0dd1426 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -158,7 +158,7 @@ static inline u64 time_to_avg_nsec(u32 value, u32 count)
if (count == 0)
return 0;
- /* value comes in units of 128 sec */
+ /* value comes in units of 128 µsec */
ret = time_to_nsec(value);
do_div(ret, count);
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 5d83dd47146..838f7ac0dc3 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -182,6 +182,15 @@ static int css_register_subchannel(struct subchannel *sch)
sch->dev.bus = &css_bus_type;
sch->dev.release = &css_subchannel_release;
sch->dev.groups = subch_attr_groups;
+ /*
+ * We don't want to generate uevents for I/O subchannels that don't
+ * have a working ccw device behind them since they will be
+ * unregistered before they can be used anyway, so we delay the add
+ * uevent until after device recognition was successful.
+ */
+ if (!cio_is_console(sch->schid))
+ /* Console is special, no need to suppress. */
+ sch->dev.uevent_suppress = 1;
css_update_ssd_info(sch);
/* make it known to the system */
ret = css_sch_device_register(sch);
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index 16ea828e99f..ef7bc0a125e 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -6,7 +6,7 @@
*/
#include <linux/slab.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include "idset.h"
#include "css.h"
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 399695f7b1a..3561982749e 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -59,13 +59,13 @@
* 1.15 Changed for 2.6 Kernel No longer compiles on 2.4 or lower
* 1.25 Added Packing support
*/
-#include <asm/bitops.h>
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include <asm/debug.h>
#include <asm/idals.h>
#include <asm/io.h>
+#include <linux/bitops.h>
#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/errno.h>
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
index 44993723373..6bf3ebbe985 100644
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
- * Fixes by : Jochen Rhrig (roehrig@de.ibm.com)
+ * Fixes by : Jochen Röhrig (roehrig@de.ibm.com)
* Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Peter Tiedemann (ptiedem@de.ibm.com)
* Driver Model stuff by : Cornelia Huck <cornelia.huck@de.ibm.com>
@@ -19,7 +19,7 @@
* Dieter Wellerdiek (wel@de.ibm.com)
* Martin Schwidefsky (schwidefsky@de.ibm.com)
* Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
- * Jochen Rhrig (roehrig@de.ibm.com)
+ * Jochen Röhrig (roehrig@de.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -885,7 +885,7 @@ ch_action_firstio(fsm_instance * fi, int event, void *arg)
}
/**
- * Dont setup a timer for receiving the initial RX frame
+ * Don't setup a timer for receiving the initial RX frame
* if in compatibility mode, since VM TCP delays the initial
* frame until it has some data to send.
*/
@@ -905,10 +905,10 @@ ch_action_firstio(fsm_instance * fi, int event, void *arg)
ccw_check_return_code(ch, rc, "init IO");
}
/**
- * If in compatibility mode since we dont setup a timer, we
+ * If in compatibility mode since we don't setup a timer, we
* also signal RX channel up immediately. This enables us
* to send packets early which in turn usually triggers some
- * reply from VM TCP which brings up the RX channel to its
+ * reply from VM TCP which brings up the RX channel to it's
* final state.
*/
if ((CHANNEL_DIRECTION(ch->flags) == READ) &&
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index a2d08c9ba3c..ff999ff0b62 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -6643,7 +6643,8 @@ qeth_netdev_init(struct net_device *dev)
dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
#endif
- dev->header_ops = &qeth_null_ops;
+ if (qeth_get_netdev_flags(card) & IFF_NOARP)
+ dev->header_ops = &qeth_null_ops;
#ifdef CONFIG_QETH_IPV6
/*IPv6 address autoconfiguration stuff*/
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index e7a1642b2aa..d4f8fcded51 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -134,7 +134,7 @@ int init_vfc_hw(struct vfc_dev *dev)
int init_vfc_devstruct(struct vfc_dev *dev, int instance)
{
dev->instance=instance;
- init_MUTEX(&dev->device_lock_sem);
+ mutex_init(&dev->device_lock_mtx);
dev->control_reg=0;
dev->busy=0;
return 0;
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index fb14014ee16..afb262b4be1 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1840,7 +1840,7 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
(scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
struct scatterlist *sg = scsi_sglist(srb);
- char *buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
@@ -1919,7 +1919,7 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
char *buf;
unsigned long flags = 0;
local_irq_save(flags);
- buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
local_irq_restore(flags);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index a64153b9603..59716ebeb10 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1469,7 +1469,7 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
struct scatterlist *sg = scsi_sglist(cmd);
local_irq_save(flags);
- buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
transfer_len = min(sg->length, len);
memcpy(buf, data, transfer_len);
diff --git a/drivers/scsi/FlashPoint.c b/drivers/scsi/FlashPoint.c
index a7f916c0c9c..1c9078191d9 100644
--- a/drivers/scsi/FlashPoint.c
+++ b/drivers/scsi/FlashPoint.c
@@ -25,9 +25,6 @@
#define FAILURE 0xFFFFFFFFL
-#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
-#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
-
struct sccb;
typedef void (*CALL_BK_FN) (struct sccb *);
@@ -374,9 +371,9 @@ typedef struct SCCBscam_info {
#define SCAM_ENABLED BIT(2)
#define SCAM_LEVEL2 BIT(3)
-#define RENEGO_ENA BITW(10)
-#define CONNIO_ENA BITW(11)
-#define GREEN_PC_ENA BITW(12)
+#define RENEGO_ENA BIT(10)
+#define CONNIO_ENA BIT(11)
+#define GREEN_PC_ENA BIT(12)
#define AUTO_RATE_00 00
#define AUTO_RATE_05 01
@@ -511,23 +508,23 @@ typedef struct SCCBscam_info {
#define hp_intena 0x40
-#define RESET BITW(7)
-#define PROG_HLT BITW(6)
-#define PARITY BITW(5)
-#define FIFO BITW(4)
-#define SEL BITW(3)
-#define SCAM_SEL BITW(2)
-#define RSEL BITW(1)
-#define TIMEOUT BITW(0)
-#define BUS_FREE BITW(15)
-#define XFER_CNT_0 BITW(14)
-#define PHASE BITW(13)
-#define IUNKWN BITW(12)
-#define ICMD_COMP BITW(11)
-#define ITICKLE BITW(10)
-#define IDO_STRT BITW(9)
-#define ITAR_DISC BITW(8)
-#define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
+#define RESET BIT(7)
+#define PROG_HLT BIT(6)
+#define PARITY BIT(5)
+#define FIFO BIT(4)
+#define SEL BIT(3)
+#define SCAM_SEL BIT(2)
+#define RSEL BIT(1)
+#define TIMEOUT BIT(0)
+#define BUS_FREE BIT(15)
+#define XFER_CNT_0 BIT(14)
+#define PHASE BIT(13)
+#define IUNKWN BIT(12)
+#define ICMD_COMP BIT(11)
+#define ITICKLE BIT(10)
+#define IDO_STRT BIT(9)
+#define ITAR_DISC BIT(8)
+#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
#define CLR_ALL_INT 0xFFFF
#define CLR_ALL_INT_1 0xFF00
@@ -674,37 +671,37 @@ typedef struct SCCBscam_info {
#define BIOS_DATA_OFFSET 0x60
#define BIOS_RELATIVE_CARD 0x64
-#define AR3 (BITW(9) + BITW(8))
-#define SDATA BITW(10)
+#define AR3 (BIT(9) + BIT(8))
+#define SDATA BIT(10)
-#define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
+#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
-#define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
+#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
-#define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
+#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
-#define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
+#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
#define ADATA_OUT 0x00
-#define ADATA_IN BITW(8)
-#define ACOMMAND BITW(10)
-#define ASTATUS (BITW(10)+BITW(8))
-#define AMSG_OUT (BITW(10)+BITW(9))
-#define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
+#define ADATA_IN BIT(8)
+#define ACOMMAND BIT(10)
+#define ASTATUS (BIT(10)+BIT(8))
+#define AMSG_OUT (BIT(10)+BIT(9))
+#define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
-#define BRH_OP BITW(13) /* Branch */
+#define BRH_OP BIT(13) /* Branch */
#define ALWAYS 0x00
-#define EQUAL BITW(8)
-#define NOT_EQ BITW(9)
+#define EQUAL BIT(8)
+#define NOT_EQ BIT(9)
-#define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
+#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
-#define FIFO_0 BITW(10)
+#define FIFO_0 BIT(10)
-#define MPM_OP BITW(15) /* Match phase and move data */
+#define MPM_OP BIT(15) /* Match phase and move data */
-#define MRR_OP BITW(14) /* Move DReg. to Reg. */
+#define MRR_OP BIT(14) /* Move DReg. to Reg. */
#define S_IDREG (BIT(2)+BIT(1)+BIT(0))
@@ -712,9 +709,9 @@ typedef struct SCCBscam_info {
#define D_AR1 BIT(0)
#define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
-#define RAT_OP (BITW(14)+BITW(13)+BITW(11))
+#define RAT_OP (BIT(14)+BIT(13)+BIT(11))
-#define SSI_OP (BITW(15)+BITW(11))
+#define SSI_OP (BIT(15)+BIT(11))
#define SSI_ITAR_DISC (ITAR_DISC >> 8)
#define SSI_IDO_STRT (IDO_STRT >> 8)
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 30905cebefb..a5763c6e936 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -521,7 +521,7 @@ config SCSI_DPT_I2O
config SCSI_ADVANSYS
tristate "AdvanSys SCSI support"
- depends on SCSI
+ depends on SCSI && VIRT_TO_BUS
depends on ISA || EISA || PCI
help
This is a driver for all SCSI host adapters manufactured by
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 988f0bc5eda..2597209183d 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -298,8 +298,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd * cmd)
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
} else {
cmd->SCp.buffer = NULL;
@@ -2143,8 +2142,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
++cmd->SCp.buffer;
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page)+
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
dprintk(NDEBUG_INFORMATION, ("scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual));
}
/*
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c
index 96e8e29aa05..5b0efc90391 100644
--- a/drivers/scsi/NCR53C9x.c
+++ b/drivers/scsi/NCR53C9x.c
@@ -927,7 +927,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp)
esp->dma_mmu_get_scsi_sgl(esp, sp);
else
sp->SCp.ptr =
- (char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+ (char *) virt_to_phys(sg_virt(sp->SCp.buffer));
}
}
@@ -1748,7 +1748,7 @@ static inline void advance_sg(struct NCR_ESP *esp, Scsi_Cmnd *sp)
if (esp->dma_advance_sg)
esp->dma_advance_sg (sp);
else
- sp->SCp.ptr = (char *) virt_to_phys((page_address(sp->SCp.buffer->page) + sp->SCp.buffer->offset));
+ sp->SCp.ptr = (char *) virt_to_phys(sg_virt(sp->SCp.buffer));
}
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 3168a179484..137d065db3d 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -875,8 +875,7 @@ static void NCR53c406a_intr(void *dev_id)
outb(TRANSFER_INFO | DMA_OP, CMD_REG);
#if USE_PIO
scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
- NCR53c406a_pio_write(page_address(sg->page) + sg->offset,
- sg->length);
+ NCR53c406a_pio_write(sg_virt(sg), sg->length);
}
REG0;
#endif /* USE_PIO */
@@ -897,8 +896,7 @@ static void NCR53c406a_intr(void *dev_id)
outb(TRANSFER_INFO | DMA_OP, CMD_REG);
#if USE_PIO
scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) {
- NCR53c406a_pio_read(page_address(sg->page) + sg->offset,
- sg->length);
+ NCR53c406a_pio_read(sg_virt(sg), sg->length);
}
REG0;
#endif /* USE_PIO */
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 80e448d0f3d..a77ab8d693d 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -356,7 +356,7 @@ static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigne
int transfer_len;
struct scatterlist *sg = scsi_sglist(scsicmd);
- buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
transfer_len = min(sg->length, len + offset);
transfer_len -= offset;
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 03b51025a8f..9abba8b90f7 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1526,7 +1526,7 @@ struct aac_mntent {
__le32 capacityhigh;
};
-#define FSCS_NOTCLEAN 0x0001 /* fsck is neccessary before mounting */
+#define FSCS_NOTCLEAN 0x0001 /* fsck is necessary before mounting */
#define FSCS_READONLY 0x0002 /* possible result of broken mirror */
#define FSCS_HIDDEN 0x0004 /* should be ignored - set during a clear */
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index f08e71e0205..ea8c6994764 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1,6 +1,6 @@
/* aha152x.c -- Adaptec AHA-152x driver
- * Author: Jrgen E. Fischer, fischer@norbit.de
- * Copyright 1993-2004 Jrgen E. Fischer
+ * Author: Jürgen E. Fischer, fischer@norbit.de
+ * Copyright 1993-2004 Jürgen E. Fischer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -357,7 +357,7 @@ enum {
check_condition = 0x0800, /* requesting sense after CHECK CONDITION */
};
-MODULE_AUTHOR("Jrgen Fischer");
+MODULE_AUTHOR("Jürgen Fischer");
MODULE_DESCRIPTION(AHA152X_REVID);
MODULE_LICENSE("GPL");
@@ -613,7 +613,7 @@ struct aha152x_scdata {
#define SCNEXT(SCpnt) SCDATA(SCpnt)->next
#define SCSEM(SCpnt) SCDATA(SCpnt)->done
-#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer) ((char *) sg_virt((buffer)))
/* state handling */
static void seldi_run(struct Scsi_Host *shpnt);
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 961a1882cb7..bbcc2c52d79 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -49,7 +49,7 @@
#include "aha1542.h"
#define SCSI_BUF_PA(address) isa_virt_to_bus(address)
-#define SCSI_SG_PA(sgent) (isa_page_to_bus((sgent)->page) + (sgent)->offset)
+#define SCSI_SG_PA(sgent) (isa_page_to_bus(sg_page((sgent))) + (sgent)->offset)
static void BAD_DMA(void *address, unsigned int length)
{
@@ -66,8 +66,7 @@ static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
int badseg)
{
printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
- badseg, nseg,
- page_address(sgp->page) + sgp->offset,
+ badseg, nseg, sg_virt(sgp),
(unsigned long long)SCSI_SG_PA(sgp),
sgp->length);
@@ -712,8 +711,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
printk(KERN_CRIT "%d: %p %d\n", i,
- (page_address(sg->page) +
- sg->offset), sg->length);
+ sg_virt(sg), sg->length);
};
printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
ptr = (unsigned char *) &cptr[i];
diff --git a/drivers/scsi/aic7xxx/cam.h b/drivers/scsi/aic7xxx/cam.h
index 26f17e3fc45..687aef6ef18 100644
--- a/drivers/scsi/aic7xxx/cam.h
+++ b/drivers/scsi/aic7xxx/cam.h
@@ -48,7 +48,7 @@ typedef enum {
CAM_REQ_ABORTED, /* CCB request aborted by the host */
CAM_UA_ABORT, /* Unable to abort CCB request */
CAM_REQ_CMP_ERR, /* CCB request completed with an error */
- CAM_BUSY, /* CAM subsytem is busy */
+ CAM_BUSY, /* CAM subsystem is busy */
CAM_REQ_INVALID, /* CCB request was invalid */
CAM_PATH_INVALID, /* Supplied Path ID is invalid */
CAM_SEL_TIMEOUT, /* Target Selection Timeout */
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f81777586b8..f7a252885a5 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1343,7 +1343,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
/* 4 bytes: Areca io control code */
sg = scsi_sglist(cmd);
- buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
if (scsi_sg_count(cmd) > 1) {
retvalue = ARCMSR_MESSAGE_FAIL;
goto message_out;
@@ -1593,7 +1593,7 @@ static void arcmsr_handle_virtual_command(struct AdapterControlBlock *acb,
strncpy(&inqdata[32], "R001", 4); /* Product Revision */
sg = scsi_sglist(cmd);
- buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
memcpy(buffer, inqdata, sizeof(inqdata));
sg = scsi_sglist(cmd);
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c
index 52d0b87e9aa..d1780980fb2 100644
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -515,8 +515,7 @@ static inline void initialize_SCp(Scsi_Cmnd *cmd)
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *)cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
/* ++roman: Try to merge some scatter-buffers if they are at
* contiguous physical addresses.
@@ -2054,8 +2053,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
++cmd->SCp.buffer;
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
/* ++roman: Try to merge some scatter-buffers if
* they are at contiguous physical addresses.
*/
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index fd42d478920..a9def6e1d30 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1808,12 +1808,12 @@ static irqreturn_t dc395x_interrupt(int irq, void *dev_id)
irqreturn_t handled = IRQ_NONE;
/*
- * Check for pending interupt
+ * Check for pending interrupt
*/
scsi_status = DC395x_read16(acb, TRM_S1040_SCSI_STATUS);
dma_status = DC395x_read8(acb, TRM_S1040_DMA_STATUS);
if (scsi_status & SCSIINTERRUPT) {
- /* interupt pending - let's process it! */
+ /* interrupt pending - let's process it! */
dc395x_handle_interrupt(acb, scsi_status);
handled = IRQ_HANDLED;
}
@@ -4579,7 +4579,7 @@ static void adapter_uninit_chip(struct AdapterCtlBlk *acb)
if (acb->config & HCC_SCSI_RESET)
reset_scsi_bus(acb);
- /* clear any pending interupt state */
+ /* clear any pending interrupt state */
DC395x_read8(acb, TRM_S1040_SCSI_INTSTATUS);
}
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 96180bb47e4..982c5092be1 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -172,7 +172,7 @@ static void IncStat(struct scsi_pointer *SCp, unsigned int Increment)
SCp->Status = 0;
else {
SCp->buffer++;
- SCp->ptr = page_address(SCp->buffer->page) + SCp->buffer->offset;
+ SCp->ptr = sg_virt(SCp->buffer);
SCp->this_residual = SCp->buffer->length;
}
}
@@ -410,7 +410,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd,
} else {
cmd->SCp.buffer = cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
}
cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes
diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
index 668569e8856..8335b608e57 100644
--- a/drivers/scsi/fd_mcs.c
+++ b/drivers/scsi/fd_mcs.c
@@ -973,7 +973,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
if (current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
} else
break;
@@ -1006,7 +1006,7 @@ static irqreturn_t fd_mcs_intr(int irq, void *dev_id)
if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
}
}
@@ -1109,7 +1109,7 @@ static int fd_mcs_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
if (current_SC->use_sg) {
current_SC->SCp.buffer = (struct scatterlist *) current_SC->request_buffer;
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
current_SC->SCp.buffers_residual = current_SC->use_sg - 1;
} else {
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index 5d282e6a6ae..2cd6b4959eb 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1321,7 +1321,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
if (current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
} else
break;
@@ -1354,7 +1354,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id)
&& current_SC->SCp.buffers_residual) {
--current_SC->SCp.buffers_residual;
++current_SC->SCp.buffer;
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
}
}
@@ -1439,8 +1439,7 @@ static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt,
if (scsi_sg_count(current_SC)) {
current_SC->SCp.buffer = scsi_sglist(current_SC);
- current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page)
- + current_SC->SCp.buffer->offset;
+ current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer);
current_SC->SCp.this_residual = current_SC->SCp.buffer->length;
current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
} else {
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 3ac080ee6e2..5ab3ce76248 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -2374,18 +2374,18 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
if (cpsum+cpnow > cpcount)
cpnow = cpcount - cpsum;
cpsum += cpnow;
- if (!sl->page) {
+ if (!sg_page(sl)) {
printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n",
ha->hanum);
return;
}
local_irq_save(flags);
- address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset;
+ address = kmap_atomic(sg_page(sl), KM_BIO_SRC_IRQ) + sl->offset;
if (to_buffer)
memcpy(buffer, address, cpnow);
else
memcpy(address, buffer, cpnow);
- flush_dcache_page(sl->page);
+ flush_dcache_page(sg_page(sl));
kunmap_atomic(address, KM_BIO_SRC_IRQ);
local_irq_restore(flags);
if (cpsum == cpcount)
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 714e6273a70..db004a45073 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1828,7 +1828,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
BUG_ON(scsi_sg_count(cmd) > 16);
scsi_for_each_sg(cmd, sg, scsi_sg_count(cmd), i) {
- ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg->page) + sg->offset);
+ ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sg_page(sg)) + sg->offset);
ld(shpnt)[ldn].sge[i].byte_length = sg->length;
}
scb->enable |= IM_POINTER_TO_LIST;
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index fa7ba64483f..8d0244c2e7d 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -47,9 +47,9 @@
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/mutex.h>
+#include <linux/bitops.h>
#include <asm/io.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <scsi/scsi.h>
@@ -175,18 +175,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
while (bcount) {
count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(pc->sg->page)) {
+ if (PageHighMem(sg_page(pc->sg))) {
unsigned long flags;
local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+ buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
pc->sg->offset;
drive->hwif->atapi_input_bytes(drive,
buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
- buf = page_address(pc->sg->page) + pc->sg->offset;
+ buf = sg_virt(pc->sg);
drive->hwif->atapi_input_bytes(drive,
buf + pc->b_count, count);
}
@@ -212,18 +212,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
while (bcount) {
count = min(pc->sg->length - pc->b_count, bcount);
- if (PageHighMem(pc->sg->page)) {
+ if (PageHighMem(sg_page(pc->sg))) {
unsigned long flags;
local_irq_save(flags);
- buf = kmap_atomic(pc->sg->page, KM_IRQ0) +
+ buf = kmap_atomic(sg_page(pc->sg), KM_IRQ0) +
pc->sg->offset;
drive->hwif->atapi_output_bytes(drive,
buf + pc->b_count, count);
kunmap_atomic(buf - pc->sg->offset, KM_IRQ0);
local_irq_restore(flags);
} else {
- buf = page_address(pc->sg->page) + pc->sg->offset;
+ buf = sg_virt(pc->sg);
drive->hwif->atapi_output_bytes(drive,
buf + pc->b_count, count);
}
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 74cdc1f0a78..a3d0c6b1495 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -705,9 +705,7 @@ static int imm_completion(struct scsi_cmnd *cmd)
cmd->SCp.buffer++;
cmd->SCp.this_residual =
cmd->SCp.buffer->length;
- cmd->SCp.ptr =
- page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
/*
* Make sure that we transfer even number of bytes
@@ -844,9 +842,7 @@ static int imm_engine(imm_struct *dev, struct scsi_cmnd *cmd)
cmd->SCp.buffer =
(struct scatterlist *) cmd->request_buffer;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr =
- page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
} else {
/* else fill the only available buffer */
cmd->SCp.buffer = NULL;
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c
index ab7cbf3449c..c8b452f2878 100644
--- a/drivers/scsi/in2000.c
+++ b/drivers/scsi/in2000.c
@@ -372,7 +372,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = (char *) page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
} else {
cmd->SCp.buffer = NULL;
@@ -764,7 +764,7 @@ static void transfer_bytes(Scsi_Cmnd * cmd, int data_in_dir)
++cmd->SCp.buffer;
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
}
/* Set up hardware registers */
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index c316a0bcae6..439b97a6a26 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -2872,6 +2872,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
}
scatterlist = sglist->scatterlist;
+ sg_init_table(scatterlist, num_elem);
sglist->order = order;
sglist->num_sg = num_elem;
@@ -2884,12 +2885,12 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
/* Free up what we already allocated */
for (j = i - 1; j >= 0; j--)
- __free_pages(scatterlist[j].page, order);
+ __free_pages(sg_page(&scatterlist[j]), order);
kfree(sglist);
return NULL;
}
- scatterlist[i].page = page;
+ sg_set_page(&scatterlist[i], page);
}
return sglist;
@@ -2910,7 +2911,7 @@ static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
int i;
for (i = 0; i < sglist->num_sg; i++)
- __free_pages(sglist->scatterlist[i].page, sglist->order);
+ __free_pages(sg_page(&sglist->scatterlist[i]), sglist->order);
kfree(sglist);
}
@@ -2940,9 +2941,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
scatterlist = sglist->scatterlist;
for (i = 0; i < (len / bsize_elem); i++, buffer += bsize_elem) {
- kaddr = kmap(scatterlist[i].page);
+ struct page *page = sg_page(&scatterlist[i]);
+
+ kaddr = kmap(page);
memcpy(kaddr, buffer, bsize_elem);
- kunmap(scatterlist[i].page);
+ kunmap(page);
scatterlist[i].length = bsize_elem;
@@ -2953,9 +2956,11 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist,
}
if (len % bsize_elem) {
- kaddr = kmap(scatterlist[i].page);
+ struct page *page = sg_page(&scatterlist[i]);
+
+ kaddr = kmap(page);
memcpy(kaddr, buffer, len % bsize_elem);
- kunmap(scatterlist[i].page);
+ kunmap(page);
scatterlist[i].length = len % bsize_elem;
}
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index edaac2714c5..5c5a9b2628f 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -1515,7 +1515,7 @@ static int ips_is_passthru(struct scsi_cmnd *SC)
/* kmap_atomic() ensures addressability of the user buffer.*/
/* local_irq_save() protects the KM_IRQ0 address slot. */
local_irq_save(flags);
- buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
buffer[2] == 'P' && buffer[3] == 'P') {
kunmap_atomic(buffer - sg->offset, KM_IRQ0);
@@ -3523,7 +3523,7 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
/* kmap_atomic() ensures addressability of the data buffer.*/
/* local_irq_save() protects the KM_IRQ0 address slot. */
local_irq_save(flags);
- buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+ buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
memcpy(buffer, &cdata[xfer_cnt], min_cnt);
kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
local_irq_restore(flags);
@@ -3556,7 +3556,7 @@ ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
/* kmap_atomic() ensures addressability of the data buffer.*/
/* local_irq_save() protects the KM_IRQ0 address slot. */
local_irq_save(flags);
- buffer = kmap_atomic(sg[i].page, KM_IRQ0) + sg[i].offset;
+ buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
memcpy(&cdata[xfer_cnt], buffer, min_cnt);
kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
local_irq_restore(flags);
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index a21455d0274..6ce4109efdf 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -70,9 +70,7 @@ module_param_named(max_lun, iscsi_max_lun, uint, S_IRUGO);
static inline void
iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
{
- ibuf->sg.page = virt_to_page(vbuf);
- ibuf->sg.offset = offset_in_page(vbuf);
- ibuf->sg.length = size;
+ sg_init_one(&ibuf->sg, vbuf, size);
ibuf->sent = 0;
ibuf->use_sendmsg = 1;
}
@@ -80,13 +78,14 @@ iscsi_buf_init_iov(struct iscsi_buf *ibuf, char *vbuf, int size)
static inline void
iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
{
- ibuf->sg.page = sg->page;
+ sg_init_table(&ibuf->sg, 1);
+ sg_set_page(&ibuf->sg, sg_page(sg));
ibuf->sg.offset = sg->offset;
ibuf->sg.length = sg->length;
/*
* Fastpath: sg element fits into single page
*/
- if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg->page))
+ if (sg->length + sg->offset <= PAGE_SIZE && !PageSlab(sg_page(sg)))
ibuf->use_sendmsg = 0;
else
ibuf->use_sendmsg = 1;
@@ -716,7 +715,7 @@ static int iscsi_scsi_data_in(struct iscsi_conn *conn)
for (i = tcp_ctask->sg_count; i < scsi_sg_count(sc); i++) {
char *dest;
- dest = kmap_atomic(sg[i].page, KM_SOFTIRQ0);
+ dest = kmap_atomic(sg_page(&sg[i]), KM_SOFTIRQ0);
rc = iscsi_ctask_copy(tcp_conn, ctask, dest + sg[i].offset,
sg[i].length, offset);
kunmap_atomic(dest, KM_SOFTIRQ0);
@@ -1103,9 +1102,9 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags)
* slab case.
*/
if (buf->use_sendmsg)
- res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags);
+ res = sock_no_sendpage(sk, sg_page(&buf->sg), offset, size, flags);
else
- res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags);
+ res = tcp_conn->sendpage(sk, sg_page(&buf->sg), offset, size, flags);
if (res >= 0) {
conn->txdata_octets += res;
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c
index 7ef0afc3cd6..5f3a0d7b18d 100644
--- a/drivers/scsi/libsas/sas_discover.c
+++ b/drivers/scsi/libsas/sas_discover.c
@@ -285,7 +285,7 @@ static void sas_discover_domain(struct work_struct *work)
dev = port->port_dev;
SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id,
- current->pid);
+ task_pid_nr(current));
switch (dev->dev_type) {
case SAS_END_DEV:
@@ -320,7 +320,7 @@ static void sas_discover_domain(struct work_struct *work)
}
SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
- current->pid, error);
+ task_pid_nr(current), error);
}
static void sas_revalidate_domain(struct work_struct *work)
@@ -334,12 +334,12 @@ static void sas_revalidate_domain(struct work_struct *work)
&port->disc.pending);
SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id,
- current->pid);
+ task_pid_nr(current));
if (port->port_dev)
res = sas_ex_revalidate_domain(port->port_dev);
SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n",
- port->id, current->pid, res);
+ port->id, task_pid_nr(current), res);
}
/* ---------- Events ---------- */
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 10d1aff9938..66c65203573 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -658,7 +658,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
struct scatterlist *sg;
sg = scsi_sglist(cmd);
- buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+ buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
memset(buf, 0, cmd->cmnd[4]);
kunmap_atomic(buf - sg->offset, KM_IRQ0);
@@ -1542,10 +1542,8 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
if( cmd->cmnd[0] == INQUIRY && !islogical ) {
sgl = scsi_sglist(cmd);
- if( sgl->page ) {
- c = *(unsigned char *)
- page_address((&sgl[0])->page) +
- (&sgl[0])->offset;
+ if( sg_page(sgl) ) {
+ c = *(unsigned char *) sg_virt(&sgl[0]);
} else {
printk(KERN_WARNING
"megaraid: invalid sg.\n");
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index e4e4c6a39ed..c8923108183 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -427,7 +427,7 @@ megaraid_exit(void)
* @id : pci device id of the class of controllers
*
* This routine should be called whenever a new adapter is detected by the
- * PCI hotplug susbsytem.
+ * PCI hotplug susbsystem.
*/
static int __devinit
megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -1584,10 +1584,8 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, int *busy)
caddr_t vaddr;
sgl = scsi_sglist(scp);
- if (sgl->page) {
- vaddr = (caddr_t)
- (page_address((&sgl[0])->page)
- + (&sgl[0])->offset);
+ if (sg_page(sgl)) {
+ vaddr = (caddr_t) sg_virt(&sgl[0]);
memset(vaddr, 0, scp->cmnd[4]);
}
@@ -2328,10 +2326,8 @@ megaraid_mbox_dpc(unsigned long devp)
&& IS_RAID_CH(raid_dev, scb->dev_channel)) {
sgl = scsi_sglist(scp);
- if (sgl->page) {
- c = *(unsigned char *)
- (page_address((&sgl[0])->page) +
- (&sgl[0])->offset);
+ if (sg_page(sgl)) {
+ c = *(unsigned char *) sg_virt(&sgl[0]);
} else {
con_log(CL_ANN, (KERN_WARNING
"megaraid mailbox: invalid sg:%d\n",
diff --git a/drivers/scsi/nsp32.h b/drivers/scsi/nsp32.h
index a976e8193d1..6715ecb3bfc 100644
--- a/drivers/scsi/nsp32.h
+++ b/drivers/scsi/nsp32.h
@@ -69,11 +69,6 @@ typedef u32 u32_le;
typedef u16 u16_le;
/*
- * MACRO
- */
-#define BIT(x) (1UL << (x))
-
-/*
* BASIC Definitions
*/
#ifndef TRUE
diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c
index 26a6d55faf3..8e5eadbd5c5 100644
--- a/drivers/scsi/oktagon_esp.c
+++ b/drivers/scsi/oktagon_esp.c
@@ -550,8 +550,7 @@ void dma_mmu_get_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
void dma_mmu_get_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
{
- sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
- sp->SCp.buffer->offset;
+ sp->SCp.ptr = sg_virt(sp->SCp.buffer);
}
void dma_mmu_release_scsi_one(struct NCR_ESP *esp, Scsi_Cmnd *sp)
@@ -564,8 +563,7 @@ void dma_mmu_release_scsi_sgl(struct NCR_ESP *esp, Scsi_Cmnd *sp)
void dma_advance_sg(Scsi_Cmnd *sp)
{
- sp->SCp.ptr = page_address(sp->SCp.buffer->page)+
- sp->SCp.buffer->offset;
+ sp->SCp.ptr = sg_virt(sp->SCp.buffer);
}
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 331b789937c..1c5c4b68f20 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -542,7 +542,7 @@ static int osst_verify_frame(struct osst_tape * STp, int frame_seq_number, int q
if (STp->raw) {
if (STp->buffer->syscall_result) {
for (i=0; i < STp->buffer->sg_segs; i++)
- memset(page_address(STp->buffer->sg[i].page),
+ memset(page_address(sg_page(&STp->buffer->sg[i])),
0, STp->buffer->sg[i].length);
strcpy(STp->buffer->b_data, "READ ERROR ON FRAME");
} else
@@ -4437,7 +4437,7 @@ static int os_scsi_tape_open(struct inode * inode, struct file * filp)
for (i = 0, b_size = 0;
(i < STp->buffer->sg_segs) && ((b_size + STp->buffer->sg[i].length) <= OS_DATA_SIZE);
b_size += STp->buffer->sg[i++].length);
- STp->buffer->aux = (os_aux_t *) (page_address(STp->buffer->sg[i].page) + OS_DATA_SIZE - b_size);
+ STp->buffer->aux = (os_aux_t *) (page_address(sg_page(&STp->buffer->sg[i])) + OS_DATA_SIZE - b_size);
#if DEBUG
printk(OSST_DEB_MSG "%s:D: b_data points to %p in segment 0 at %p\n", name,
STp->buffer->b_data, page_address(STp->buffer->sg[0].page));
@@ -5252,25 +5252,26 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
/* Try to allocate the first segment up to OS_DATA_SIZE and the others
big enough to reach the goal (code assumes no segments in place) */
for (b_size = OS_DATA_SIZE, order = OSST_FIRST_ORDER; b_size >= PAGE_SIZE; order--, b_size /= 2) {
- STbuffer->sg[0].page = alloc_pages(priority, order);
+ struct page *page = alloc_pages(priority, order);
+
STbuffer->sg[0].offset = 0;
- if (STbuffer->sg[0].page != NULL) {
+ if (page != NULL) {
+ sg_set_page(&STbuffer->sg[0], page);
STbuffer->sg[0].length = b_size;
- STbuffer->b_data = page_address(STbuffer->sg[0].page);
+ STbuffer->b_data = page_address(page);
break;
}
}
- if (STbuffer->sg[0].page == NULL) {
+ if (sg_page(&STbuffer->sg[0]) == NULL) {
printk(KERN_NOTICE "osst :I: Can't allocate tape buffer main segment.\n");
return 0;
}
/* Got initial segment of 'bsize,order', continue with same size if possible, except for AUX */
for (segs=STbuffer->sg_segs=1, got=b_size;
segs < max_segs && got < OS_FRAME_SIZE; ) {
- STbuffer->sg[segs].page =
- alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
+ struct page *page = alloc_pages(priority, (OS_FRAME_SIZE - got <= PAGE_SIZE) ? 0 : order);
STbuffer->sg[segs].offset = 0;
- if (STbuffer->sg[segs].page == NULL) {
+ if (page == NULL) {
if (OS_FRAME_SIZE - got <= (max_segs - segs) * b_size / 2 && order) {
b_size /= 2; /* Large enough for the rest of the buffers */
order--;
@@ -5284,6 +5285,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
normalize_buffer(STbuffer);
return 0;
}
+ sg_set_page(&STbuffer->sg[segs], page);
STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
got += STbuffer->sg[segs].length;
STbuffer->buffer_size = got;
@@ -5316,7 +5318,7 @@ static void normalize_buffer(struct osst_buffer *STbuffer)
b_size < STbuffer->sg[i].length;
b_size *= 2, order++);
- __free_pages(STbuffer->sg[i].page, order);
+ __free_pages(sg_page(&STbuffer->sg[i]), order);
STbuffer->buffer_size -= STbuffer->sg[i].length;
}
#if DEBUG
@@ -5344,7 +5346,7 @@ static int append_to_buffer(const char __user *ubp, struct osst_buffer *st_bp, i
for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count;
- res = copy_from_user(page_address(st_bp->sg[i].page) + offset, ubp, cnt);
+ res = copy_from_user(page_address(sg_page(&st_bp->sg[i])) + offset, ubp, cnt);
if (res)
return (-EFAULT);
do_count -= cnt;
@@ -5377,7 +5379,7 @@ static int from_buffer(struct osst_buffer *st_bp, char __user *ubp, int do_count
for ( ; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count;
- res = copy_to_user(ubp, page_address(st_bp->sg[i].page) + offset, cnt);
+ res = copy_to_user(ubp, page_address(sg_page(&st_bp->sg[i])) + offset, cnt);
if (res)
return (-EFAULT);
do_count -= cnt;
@@ -5410,7 +5412,7 @@ static int osst_zero_buffer_tail(struct osst_buffer *st_bp)
i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length - offset < do_count ?
st_bp->sg[i].length - offset : do_count ;
- memset(page_address(st_bp->sg[i].page) + offset, 0, cnt);
+ memset(page_address(sg_page(&st_bp->sg[i])) + offset, 0, cnt);
do_count -= cnt;
offset = 0;
}
@@ -5430,7 +5432,7 @@ static int osst_copy_to_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length < do_count ?
st_bp->sg[i].length : do_count ;
- memcpy(page_address(st_bp->sg[i].page), ptr, cnt);
+ memcpy(page_address(sg_page(&st_bp->sg[i])), ptr, cnt);
do_count -= cnt;
ptr += cnt;
}
@@ -5451,7 +5453,7 @@ static int osst_copy_from_buffer(struct osst_buffer *st_bp, unsigned char *ptr)
for (i = 0; i < st_bp->sg_segs && do_count > 0; i++) {
cnt = st_bp->sg[i].length < do_count ?
st_bp->sg[i].length : do_count ;
- memcpy(ptr, page_address(st_bp->sg[i].page), cnt);
+ memcpy(ptr, page_address(sg_page(&st_bp->sg[i])), cnt);
do_count -= cnt;
ptr += cnt;
}
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index b7f0fa24641..7db28cd4944 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -24,7 +24,6 @@
/************************************
* Some useful macros...
*/
-#define BIT(x) (1L << (x))
/* SCSI initiator must be ID 7 */
#define NSP_INITIATOR_ID 7
@@ -394,7 +393,7 @@ enum _burst_mode {
#define MSG_EXT_SDTR 0x01
/* scatter-gather table */
-# define BUFFER_ADDR ((char *)((unsigned int)(SCpnt->SCp.buffer->page) + SCpnt->SCp.buffer->offset))
+# define BUFFER_ADDR ((char *)((sg_virt(SCpnt->SCp.buffer))))
#endif /*__nsp_cs__*/
/* end */
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 190e2a7d706..969b9387a0c 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -443,8 +443,7 @@ SYM53C500_intr(int irq, void *dev_id)
scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
SYM53C500_pio_write(fast_pio, port_base,
- page_address(sg->page) + sg->offset,
- sg->length);
+ sg_virt(sg), sg->length);
}
REG0(port_base);
}
@@ -463,8 +462,7 @@ SYM53C500_intr(int irq, void *dev_id)
scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
SYM53C500_pio_read(fast_pio, port_base,
- page_address(sg->page) + sg->offset,
- sg->length);
+ sg_virt(sg), sg->length);
}
REG0(port_base);
}
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 67b6d76a6c8..67ee51a3d7e 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -608,9 +608,7 @@ static int ppa_completion(struct scsi_cmnd *cmd)
cmd->SCp.buffer++;
cmd->SCp.this_residual =
cmd->SCp.buffer->length;
- cmd->SCp.ptr =
- page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
}
}
/* Now check to see if the drive is ready to comunicate */
@@ -756,8 +754,7 @@ static int ppa_engine(ppa_struct *dev, struct scsi_cmnd *cmd)
/* if many buffers are available, start filling the first */
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
} else {
/* else fill the only available buffer */
cmd->SCp.buffer = NULL;
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c
index 0f43d1d046d..03f19b8d19c 100644
--- a/drivers/scsi/ps3rom.c
+++ b/drivers/scsi/ps3rom.c
@@ -111,14 +111,14 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
req_len = act_len = 0;
scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
if (active) {
- kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+ kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
len = sgpnt->length;
if ((req_len + len) > buflen) {
active = 0;
len = buflen - req_len;
}
memcpy(kaddr + sgpnt->offset, buf + req_len, len);
- flush_kernel_dcache_page(sgpnt->page);
+ flush_kernel_dcache_page(sg_page(sgpnt));
kunmap_atomic(kaddr, KM_IRQ0);
act_len += len;
}
@@ -147,7 +147,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
req_len = fin = 0;
scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
- kaddr = kmap_atomic(sgpnt->page, KM_IRQ0);
+ kaddr = kmap_atomic(sg_page(sgpnt->page), KM_IRQ0);
len = sgpnt->length;
if ((req_len + len) > buflen) {
len = buflen - req_len;
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 9bb3d1d2a92..fe415ec8565 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -671,7 +671,7 @@ struct continuation_t1_entry {
#define ET_CONTINUE ET_CONT_T1
/* Marker entry structure*/
-struct marker_entry {
+struct qla4_marker_entry {
struct qla4_header hdr; /* 00-03 */
uint32_t system_defined; /* 04-07 */
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 1e29f51d596..d692c713416 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -1006,7 +1006,7 @@ int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
* qla4xxx_start_firmware - starts qla4xxx firmware
* @ha: Pointer to host adapter structure.
*
- * This routine performs the neccessary steps to start the firmware for
+ * This routine performs the necessary steps to start the firmware for
* the QLA4010 adapter.
**/
static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c
index 5006ecb3ef5..e4461b5d767 100644
--- a/drivers/scsi/qla4xxx/ql4_iocb.c
+++ b/drivers/scsi/qla4xxx/ql4_iocb.c
@@ -69,7 +69,7 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha,
static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry, int lun)
{
- struct marker_entry *marker_entry;
+ struct qla4_marker_entry *marker_entry;
unsigned long flags = 0;
uint8_t status = QLA_SUCCESS;
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 2bfbf26c00e..de7b3bc2cbc 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -317,7 +317,7 @@ static unsigned int ql_pcmd(struct scsi_cmnd *cmd)
return ((priv->qabort == 1 ?
DID_ABORT : DID_RESET) << 16);
}
- buf = page_address(sg->page) + sg->offset;
+ buf = sg_virt(sg);
if (ql_pdma(priv, phase, buf, sg->length))
break;
}
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 72ee4c9cfb1..46cae5a212d 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -625,7 +625,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
scsi_for_each_sg(scp, sg, scp->use_sg, k) {
if (active) {
kaddr = (unsigned char *)
- kmap_atomic(sg->page, KM_USER0);
+ kmap_atomic(sg_page(sg), KM_USER0);
if (NULL == kaddr)
return (DID_ERROR << 16);
kaddr_off = (unsigned char *)kaddr + sg->offset;
@@ -672,7 +672,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
sg = scsi_sglist(scp);
req_len = fin = 0;
for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
- kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
+ kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0);
if (NULL == kaddr)
return -1;
kaddr_off = (unsigned char *)kaddr + sg->offset;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index aac8a02cbe8..61fdaf02f25 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -295,7 +295,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
int i, err, nr_vecs = 0;
for_each_sg(sgl, sg, nsegs, i) {
- page = sg->page;
+ page = sg_page(sg);
off = sg->offset;
len = sg->length;
data_len += len;
@@ -764,7 +764,7 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
if (unlikely(!sgl))
goto enomem;
- memset(sgl, 0, sizeof(*sgl) * sgp->size);
+ sg_init_table(sgl, sgp->size);
/*
* first loop through, set initial index and return value
@@ -781,6 +781,13 @@ struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
/*
+ * if we have nothing left, mark the last segment as
+ * end-of-list
+ */
+ if (!left)
+ sg_mark_end(sgl, this);
+
+ /*
* don't allow subsequent mempool allocs to sleep, it would
* violate the mempool principle.
*/
@@ -2353,7 +2360,7 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
*offset = *offset - len_complete + sg->offset;
/* Assumption: contiguous pages can be accessed as "page + i" */
- page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
+ page = nth_page(sg_page(sg), (*offset >> PAGE_SHIFT));
*offset &= ~PAGE_MASK;
/* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 69f542c4923..a69b155f39a 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -676,7 +676,7 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
* success as well). Returns a negated errno value in case of error.
*
* Note: most ioctls are forward onto the block subsystem or further
- * down in the scsi subsytem.
+ * down in the scsi subsystem.
**/
static int sd_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
index ce80fa9ad81..b11324479b5 100644
--- a/drivers/scsi/seagate.c
+++ b/drivers/scsi/seagate.c
@@ -999,14 +999,14 @@ connect_loop:
for (i = 0; i < nobuffs; ++i)
printk("scsi%d : buffer %d address = %p length = %d\n",
hostno, i,
- page_address(buffer[i].page) + buffer[i].offset,
+ sg_virt(&buffer[i]),
buffer[i].length);
}
#endif
buffer = (struct scatterlist *) SCint->request_buffer;
len = buffer->length;
- data = page_address(buffer->page) + buffer->offset;
+ data = sg_virt(buffer);
} else {
DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
buffer = NULL;
@@ -1239,7 +1239,7 @@ connect_loop:
--nobuffs;
++buffer;
len = buffer->length;
- data = page_address(buffer->page) + buffer->offset;
+ data = sg_virt(buffer);
DPRINTK (DEBUG_SG,
"scsi%d : next scatter-gather buffer len = %d address = %08x\n",
hostno, len, data);
@@ -1396,7 +1396,7 @@ connect_loop:
--nobuffs;
++buffer;
len = buffer->length;
- data = page_address(buffer->page) + buffer->offset;
+ data = sg_virt(buffer);
DPRINTK (DEBUG_SG, "scsi%d : next scatter-gather buffer len = %d address = %08x\n", hostno, len, data);
}
break;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 7238b2dfc49..cc197100284 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1169,7 +1169,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
len = vma->vm_end - sa;
len = (len < sg->length) ? len : sg->length;
if (offset < len) {
- page = virt_to_page(page_address(sg->page) + offset);
+ page = virt_to_page(page_address(sg_page(sg)) + offset);
get_page(page); /* increment page count */
break;
}
@@ -1717,13 +1717,13 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
goto out_unlock; */
}
- sgl[0].page = pages[0];
+ sg_set_page(sgl, pages[0]);
sgl[0].offset = uaddr & ~PAGE_MASK;
if (nr_pages > 1) {
sgl[0].length = PAGE_SIZE - sgl[0].offset;
count -= sgl[0].length;
for (i=1; i < nr_pages ; i++) {
- sgl[i].page = pages[i];
+ sg_set_page(&sgl[i], pages[i]);
sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
count -= PAGE_SIZE;
}
@@ -1754,7 +1754,7 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages,
int i;
for (i=0; i < nr_pages; i++) {
- struct page *page = sgl[i].page;
+ struct page *page = sg_page(&sgl[i]);
if (dirtied)
SetPageDirty(page);
@@ -1854,7 +1854,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
scatter_elem_sz_prev = ret_sz;
}
}
- sg->page = p;
+ sg_set_page(sg, p);
sg->length = (ret_sz > num) ? num : ret_sz;
SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
@@ -1907,14 +1907,14 @@ sg_write_xfer(Sg_request * srp)
onum = 1;
ksglen = sg->length;
- p = page_address(sg->page);
+ p = page_address(sg_page(sg));
for (j = 0, k = 0; j < onum; ++j) {
res = sg_u_iovec(hp, iovec_count, j, 1, &usglen, &up);
if (res)
return res;
for (; p; sg = sg_next(sg), ksglen = sg->length,
- p = page_address(sg->page)) {
+ p = page_address(sg_page(sg))) {
if (usglen <= 0)
break;
if (ksglen > usglen) {
@@ -1991,12 +1991,12 @@ sg_remove_scat(Sg_scatter_hold * schp)
} else {
int k;
- for (k = 0; (k < schp->k_use_sg) && sg->page;
+ for (k = 0; (k < schp->k_use_sg) && sg_page(sg);
++k, sg = sg_next(sg)) {
SCSI_LOG_TIMEOUT(5, printk(
"sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
- k, sg->page, sg->length));
- sg_page_free(sg->page, sg->length);
+ k, sg_page(sg), sg->length));
+ sg_page_free(sg_page(sg), sg->length);
}
}
kfree(schp->buffer);
@@ -2038,7 +2038,7 @@ sg_read_xfer(Sg_request * srp)
} else
onum = 1;
- p = page_address(sg->page);
+ p = page_address(sg_page(sg));
ksglen = sg->length;
for (j = 0, k = 0; j < onum; ++j) {
res = sg_u_iovec(hp, iovec_count, j, 0, &usglen, &up);
@@ -2046,7 +2046,7 @@ sg_read_xfer(Sg_request * srp)
return res;
for (; p; sg = sg_next(sg), ksglen = sg->length,
- p = page_address(sg->page)) {
+ p = page_address(sg_page(sg))) {
if (usglen <= 0)
break;
if (ksglen > usglen) {
@@ -2092,15 +2092,15 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
if ((!outp) || (num_read_xfer <= 0))
return 0;
- for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
+ for (k = 0; (k < schp->k_use_sg) && sg_page(sg); ++k, sg = sg_next(sg)) {
num = sg->length;
if (num > num_read_xfer) {
- if (__copy_to_user(outp, page_address(sg->page),
+ if (__copy_to_user(outp, page_address(sg_page(sg)),
num_read_xfer))
return -EFAULT;
break;
} else {
- if (__copy_to_user(outp, page_address(sg->page),
+ if (__copy_to_user(outp, page_address(sg_page(sg)),
num))
return -EFAULT;
num_read_xfer -= num;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 73c44cbdea4..ce69b9efc10 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3797,7 +3797,7 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
sg = &(STbp->sg[0]);
frp = STbp->frp;
for (i=count=0; count < length; i++) {
- sg[i].page = frp[i].page;
+ sg_set_page(&sg[i], frp[i].page);
if (length - count > frp[i].length)
sg[i].length = frp[i].length;
else
@@ -4446,14 +4446,14 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
}
/* Populate the scatter/gather list */
- sgl[0].page = pages[0];
+ sg_set_page(&sgl[0], pages[0]);
sgl[0].offset = uaddr & ~PAGE_MASK;
if (nr_pages > 1) {
sgl[0].length = PAGE_SIZE - sgl[0].offset;
count -= sgl[0].length;
for (i=1; i < nr_pages ; i++) {
+ sg_set_page(&sgl[i], pages[i]);;
sgl[i].offset = 0;
- sgl[i].page = pages[i];
sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
count -= PAGE_SIZE;
}
@@ -4483,7 +4483,7 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p
int i;
for (i=0; i < nr_pages; i++) {
- struct page *page = sgl[i].page;
+ struct page *page = sg_page(&sgl[i]);
if (dirtied)
SetPageDirty(page);
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c
index dc15a22105f..2dcde373b20 100644
--- a/drivers/scsi/sun3_NCR5380.c
+++ b/drivers/scsi/sun3_NCR5380.c
@@ -272,8 +272,7 @@ static struct scsi_host_template *the_template = NULL;
#define HOSTNO instance->host_no
#define H_NO(cmd) (cmd)->device->host->host_no
-#define SGADDR(buffer) (void *)(((unsigned long)page_address((buffer)->page)) + \
- (buffer)->offset)
+#define SGADDR(buffer) (void *)(((unsigned long)sg_virt(((buffer)))))
#ifdef SUPPORT_TAGS
@@ -1596,7 +1595,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
* IO while SEL is true. But again, there are some disks out the in the
* world that do that nevertheless. (Somebody claimed that this announces
* reselection capability of the target.) So we better skip that test and
- * only wait for BSY... (Famous german words: Der Klgere gibt nach :-)
+ * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
*/
while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 8befab7e983..90cee94d952 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -196,7 +196,7 @@ static unsigned int sym53c416_base_3[2] = {0,0};
#define MAXHOSTS 4
-#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
+#define SG_ADDRESS(buffer) ((char *) sg_virt((buffer)))
enum phases
{
diff --git a/drivers/scsi/sym53c8xx_2/sym_fw2.h b/drivers/scsi/sym53c8xx_2/sym_fw2.h
index 6e5b952312e..ae1fb179b88 100644
--- a/drivers/scsi/sym53c8xx_2/sym_fw2.h
+++ b/drivers/scsi/sym53c8xx_2/sym_fw2.h
@@ -1781,7 +1781,7 @@ static struct SYM_FWB_SCR SYM_FWB_SCR = {
* While testing with bogus QUANTUM drives, the C1010
* sometimes raised a spurious phase mismatch with
* WSR and the CHMOV(1) triggered another PM.
- * Waiting explicitely for the PHASE seemed to avoid
+ * Waiting explicitly for the PHASE seemed to avoid
* the nested phase mismatch. Btw, this didn't happen
* using my IBM drives.
*/
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c
index 5c72ca31a47..44193049c4a 100644
--- a/drivers/scsi/tmscsim.c
+++ b/drivers/scsi/tmscsim.c
@@ -430,10 +430,7 @@ static __inline__ void dc390_Going_remove (struct dc390_dcb* pDCB, struct dc390_
static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length)
{
- memset(sg, 0, sizeof(struct scatterlist));
- sg->page = virt_to_page(addr);
- sg->length = length;
- sg->offset = (unsigned long)addr & ~PAGE_MASK;
+ sg_init_one(sg, addr, length);
return sg;
}
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index ea72bbeb8f9..6d1f0edd798 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -681,7 +681,7 @@ static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
max = scsi_sg_count(SCpnt);
scsi_for_each_sg(SCpnt, sg, max, i) {
- mscp->sglist[i].address = isa_page_to_bus(sg->page) + sg->offset;
+ mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
mscp->sglist[i].num_bytes = sg->length;
transfer_length += sg->length;
}
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 0e8e642fd3b..fdbb92d1f72 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -410,8 +410,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd,
if (cmd->use_sg) {
cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer;
cmd->SCp.buffers_residual = cmd->use_sg - 1;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length;
} else {
cmd->SCp.buffer = NULL;
@@ -745,8 +744,7 @@ transfer_bytes(const wd33c93_regs regs, struct scsi_cmnd *cmd,
++cmd->SCp.buffer;
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
- cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) +
- cmd->SCp.buffer->offset;
+ cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
}
if (!cmd->SCp.this_residual) /* avoid bogus setups */
return;
diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
index 61ffb860dac..00123f2383d 100644
--- a/drivers/scsi/wd33c93.h
+++ b/drivers/scsi/wd33c93.h
@@ -155,7 +155,7 @@
#define WD33C93_FS_12_15 OWNID_FS_12
#define WD33C93_FS_16_20 OWNID_FS_16
- /* pass input-clock explicitely. accepted mhz values are 8-10,12-20 */
+ /* pass input-clock explicitly. accepted mhz values are 8-10,12-20 */
#define WD33C93_FS_MHZ(mhz) (mhz)
/* Control register */
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index 255c611e78b..03cd44f231d 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1123,7 +1123,7 @@ static int wd7000_queuecommand(struct scsi_cmnd *SCpnt,
any2scsi(scb->maxlen, nseg * sizeof(Sgb));
scsi_for_each_sg(SCpnt, sg, nseg, i) {
- any2scsi(sgb[i].ptr, isa_page_to_bus(sg->page) + sg->offset);
+ any2scsi(sgb[i].ptr, isa_page_to_bus(sg_page(sg)) + sg->offset);
any2scsi(sgb[i].len, sg->length);
}
} else {
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d6ae38e55d0..ed438bc7e98 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -62,11 +62,11 @@ config SERIAL_8250_CONSOLE
kernel will automatically use the first serial line, /dev/ttyS0, as
system console.
- you can set that using a kernel command line option such as
+ You can set that using a kernel command line option such as
"console=uart8250,io,0x3f8,9600n8"
"console=uart8250,mmio,0xff5e0000,115200n8".
- and it will switch to normal serial console when correponding port is
- ready.
+ and it will switch to normal serial console when the corresponding
+ port is ready.
"earlycon=uart8250,io,0x3f8,9600n8"
"earlycon=uart8250,mmio,0xff5e0000,115200n8".
it will not only setup early console.
@@ -624,7 +624,7 @@ choice
config SERIAL_BFIN_DMA
bool "DMA mode"
- depends on DMA_UNCACHED_1M && !KGDB_UART
+ depends on !DMA_UNCACHED_NONE && !KGDB_UART
help
This driver works under DMA mode. If this option is selected, the
blackfin simple dma driver is also enabled.
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 72229df9dc1..40604a09292 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -263,15 +263,15 @@ static unsigned int pl01x_get_mctrl(struct uart_port *port)
unsigned int result = 0;
unsigned int status = readw(uap->port.membase + UART01x_FR);
-#define BIT(uartbit, tiocmbit) \
+#define TIOCMBIT(uartbit, tiocmbit) \
if (status & uartbit) \
result |= tiocmbit
- BIT(UART01x_FR_DCD, TIOCM_CAR);
- BIT(UART01x_FR_DSR, TIOCM_DSR);
- BIT(UART01x_FR_CTS, TIOCM_CTS);
- BIT(UART011_FR_RI, TIOCM_RNG);
-#undef BIT
+ TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
+ TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
+ TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
+ TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
+#undef TIOCMBIT
return result;
}
@@ -282,18 +282,18 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
cr = readw(uap->port.membase + UART011_CR);
-#define BIT(tiocmbit, uartbit) \
+#define TIOCMBIT(tiocmbit, uartbit) \
if (mctrl & tiocmbit) \
cr |= uartbit; \
else \
cr &= ~uartbit
- BIT(TIOCM_RTS, UART011_CR_RTS);
- BIT(TIOCM_DTR, UART011_CR_DTR);
- BIT(TIOCM_OUT1, UART011_CR_OUT1);
- BIT(TIOCM_OUT2, UART011_CR_OUT2);
- BIT(TIOCM_LOOP, UART011_CR_LBE);
-#undef BIT
+ TIOCMBIT(TIOCM_RTS, UART011_CR_RTS);
+ TIOCMBIT(TIOCM_DTR, UART011_CR_DTR);
+ TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
+ TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
+ TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
+#undef TIOCMBIT
writew(cr, uap->port.membase + UART011_CR);
}
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 7e8724d3571..f523cdf4b02 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -442,11 +442,11 @@ static char *serial_version = "$Revision: 1.25 $";
#include <asm/uaccess.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-#include <asm/bitops.h>
#include <linux/delay.h>
#include <asm/arch/svinto.h>
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 3f26c4b2f32..e773c8e1496 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -20,8 +20,8 @@
* - S3C2410 and S3C2440 serial support
* - Power Management support
* - Fix console via IrDA devices
- * - SysReq (Herbert Ptzl)
- * - Break character handling (Herbert Ptzl)
+ * - SysReq (Herbert Pötzl)
+ * - Break character handling (Herbert Pötzl)
* - spin-lock initialisation (Dimitry Andric)
* - added clock control
* - updated init code to use platform_device info
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index e9aba932f21..7051e6c5edc 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -181,7 +181,7 @@ static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
}
- /* enable interupts and wait for wake up
+ /* enable interrupts and wait for wake up
* if just one byte is expected the Rx FIFO genererates no
* FFULL interrupt, so activate the RxRDY interrupt
*/
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index f013b4012c9..1f4f6d02fe2 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -460,7 +460,7 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum)
return 0;
/* if not yet claimed, claim it for the driver */
dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n",
- current->pid, current->comm, ifnum);
+ task_pid_nr(current), current->comm, ifnum);
return claimintf(ps, ifnum);
}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 8dd5a6afd51..90d64a80846 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -437,13 +437,11 @@ int usb_sg_init (
#if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU)
io->urbs[i]->transfer_buffer = NULL;
#else
- io->urbs[i]->transfer_buffer =
- page_address(sg[i].page) + sg[i].offset;
+ io->urbs[i]->transfer_buffer = sg_virt(&sg[i]);
#endif
} else {
/* hc may use _only_ transfer_buffer */
- io->urbs [i]->transfer_buffer =
- page_address (sg [i].page) + sg [i].offset;
+ io->urbs [i]->transfer_buffer = sg_virt(&sg[i]);
len = sg [i].length;
}
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 73726c570a6..1d174dcb3ac 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -4006,7 +4006,7 @@ static int __init fsg_bind(struct usb_gadget *gadget)
DBG(fsg, "removable=%d, stall=%d, buflen=%u\n",
mod_data.removable, mod_data.can_stall,
mod_data.buflen);
- DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid);
+ DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task));
set_bit(REGISTERED, &fsg->atomic_bitflags);
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c
index e78c2ddc1f8..367b75c0b25 100644
--- a/drivers/usb/gadget/lh7a40x_udc.c
+++ b/drivers/usb/gadget/lh7a40x_udc.c
@@ -1272,7 +1272,7 @@ static int lh7a40x_set_halt(struct usb_ep *_ep, int value)
/*
* Attempts to halt IN endpoints will fail (returning -EAGAIN)
* if any transfer requests are still queued, or if the controller
- * FIFO still holds bytes that the host hasnt collected.
+ * FIFO still holds bytes that the host hasn't collected.
*/
spin_unlock_irqrestore(&ep->dev->lock, flags);
DEBUG
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 0dcb4164dc8..735db4aec83 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -451,7 +451,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
/* Some boards (mostly VIA?) report bogus overcurrent indications,
* causing massive log spam unless we completely ignore them. It
- * may be relevant that VIA VT8235 controlers, where PORT_POWER is
+ * may be relevant that VIA VT8235 controllers, where PORT_POWER is
* always set, seem to clear PORT_OCC and PORT_CSC when writing to
* PORT_POWER; that's surprising, but maybe within-spec.
*/
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 94d859aa73f..ba370c56172 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1556,7 +1556,7 @@ sl811h_start(struct usb_hcd *hcd)
hcd->power_budget = sl811->board->power * 2;
}
- /* enable power and interupts */
+ /* enable power and interrupts */
port_power(sl811, 1);
return 0;
diff --git a/drivers/usb/image/Kconfig b/drivers/usb/image/Kconfig
index 95ce703110d..7595dfb38e3 100644
--- a/drivers/usb/image/Kconfig
+++ b/drivers/usb/image/Kconfig
@@ -1,5 +1,5 @@
#
-# USB Imageing devices configuration
+# USB Imaging devices configuration
#
comment "USB Imaging devices"
depends on USB
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index e7d982a7154..91e999c9f68 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -519,8 +519,7 @@ static void mts_do_sg (struct urb* transfer)
context->fragment++;
mts_int_submit_urb(transfer,
context->data_pipe,
- page_address(sg[context->fragment].page) +
- sg[context->fragment].offset,
+ sg_virt(&sg[context->fragment]),
sg[context->fragment].length,
context->fragment + 1 == scsi_sg_count(context->srb) ?
mts_data_done : mts_do_sg);
@@ -557,7 +556,7 @@ mts_build_transfer_context(struct scsi_cmnd *srb, struct mts_desc* desc)
return;
} else {
sg = scsi_sglist(srb);
- desc->context.data = page_address(sg[0].page) + sg[0].offset;
+ desc->context.data = sg_virt(&sg[0]);
desc->context.data_length = sg[0].length;
}
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 04e87acd6e4..2677fea147d 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -118,7 +118,7 @@ static ssize_t set_brightness(struct device *dev, struct device_attribute *attr,
cytherm->brightness, buffer, 8);
if (retval)
dev_dbg(&cytherm->udev->dev, "retval = %d\n", retval);
- /* Inform C that we have changed the brightness setting */
+ /* Inform µC that we have changed the brightness setting */
retval = vendor_command(cytherm->udev, WRITE_RAM, BRIGHTNESS_SEM,
0x01, buffer, 8);
if (retval)
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index 5c0a26cbd12..cd137577bb2 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -1,7 +1,7 @@
/*
* Emagic EMI 2|6 usb audio interface firmware loader.
* Copyright (C) 2002
- * Tapio Laxstrm (tapio.laxstrom@iptime.fi)
+ * Tapio Laxström (tapio.laxstrom@iptime.fi)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, as published by
@@ -249,7 +249,7 @@ static void __exit emi26_exit (void)
module_init(emi26_init);
module_exit(emi26_exit);
-MODULE_AUTHOR("tapio laxstrm");
+MODULE_AUTHOR("Tapio Laxström");
MODULE_DESCRIPTION("Emagic EMI 2|6 firmware loader.");
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 23153eac0df..4758cc5cceb 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -1,7 +1,7 @@
/*
* Emagic EMI 2|6 usb audio interface firmware loader.
* Copyright (C) 2002
- * Tapio Laxstrm (tapio.laxstrom@iptime.fi)
+ * Tapio Laxström (tapio.laxstrom@iptime.fi)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, as published by
@@ -292,7 +292,7 @@ static void __exit emi62_exit (void)
module_init(emi62_init);
module_exit(emi62_exit);
-MODULE_AUTHOR("tapio laxstrm");
+MODULE_AUTHOR("Tapio Laxström");
MODULE_DESCRIPTION("Emagic EMI 6|2m firmware loader.");
MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index e901d31e051..ea316214648 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -360,9 +360,9 @@ static void free_sglist (struct scatterlist *sg, int nents)
if (!sg)
return;
for (i = 0; i < nents; i++) {
- if (!sg [i].page)
+ if (!sg_page(&sg[i]))
continue;
- kfree (page_address (sg [i].page) + sg [i].offset);
+ kfree (sg_virt(&sg[i]));
}
kfree (sg);
}
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
index 52c4f7bd7a8..c1b279939bb 100644
--- a/drivers/usb/serial/ChangeLog.history
+++ b/drivers/usb/serial/ChangeLog.history
@@ -400,7 +400,7 @@ visor.c Change Log comments:
(11/11/2001) gkh
Added support for the m125 devices, and added check to prevent oopses
- for Cli devices that lie about the number of ports they have.
+ for Clié devices that lie about the number of ports they have.
(08/30/2001) gkh
Added support for the Clie devices, both the 3.5 and 4.0 os versions.
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index 99fefed7791..4a86696e6c7 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -527,7 +527,7 @@ config USB_SERIAL_CYBERJACK
depends on USB_SERIAL && EXPERIMENTAL
---help---
Say Y here if you want to use a cyberJack pinpad/e-com USB chipcard
- reader. This is an interface to ISO 7816 compatible contactbased
+ reader. This is an interface to ISO 7816 compatible contact-based
chipcards, e.g. GSM SIMs.
To compile this driver as a module, choose M here: the
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 65257867b34..8a8a6b9fb05 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -83,7 +83,7 @@
*
* (18/Jun/2003) Ian Abbott
* Added Device ID of the USB relais from Rudolf Gugler (backported from
- * Philipp Ghring's patch for 2.5.x kernel).
+ * Philipp Gühring's patch for 2.5.x kernel).
* Moved read transfer buffer reallocation into startup function.
* Free existing write urb and transfer buffer in startup function.
* Only use urbs in write urb pool that were successfully allocated.
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index b57b90ae9f9..b51cbb0eaa0 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -17,7 +17,7 @@
* Bill Ryder - bryder@sgi.com formerly of Silicon Graphics, Inc.- wrote the
* FTDI_SIO implementation.
*
- * Philipp Ghring - pg@futureware.at - added the Device ID of the USB relais
+ * Philipp Gühring - pg@futureware.at - added the Device ID of the USB relais
* from Rudolf Gugler
*
*/
@@ -44,7 +44,7 @@
#define FTDI_ACTZWAVE_PID 0xF2D0
-/* www.starting-point-systems.com Chameleon device */
+/* www.starting-point-systems.com µChameleon device */
#define FTDI_MICRO_CHAMELEON_PID 0xCAA0 /* Product Id */
/* www.irtrans.de device */
@@ -419,7 +419,7 @@
/*
* Teratronik product ids.
- * Submitted by O. Wlfelschneider.
+ * Submitted by O. Wölfelschneider.
*/
#define FTDI_TERATRONIK_VCP_PID 0xEC88 /* Teratronik device (preferring VCP driver on windows) */
#define FTDI_TERATRONIK_D2XX_PID 0xEC89 /* Teratronik device (preferring D2XX driver on windows) */
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index e836ad07fdb..9b38a08ac83 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -306,7 +306,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x0930, 0x0705) }, /* TOSHIBA Pocket PC e310 */
{ USB_DEVICE(0x0930, 0x0706) }, /* TOSHIBA Pocket PC e740 */
{ USB_DEVICE(0x0930, 0x0707) }, /* TOSHIBA Pocket PC e330 Series */
- { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350Series */
+ { USB_DEVICE(0x0930, 0x0708) }, /* TOSHIBA Pocket PC e350 Series */
{ USB_DEVICE(0x0930, 0x0709) }, /* TOSHIBA Pocket PC e750 Series */
{ USB_DEVICE(0x0930, 0x070A) }, /* TOSHIBA Pocket PC e400 Series */
{ USB_DEVICE(0x0930, 0x070B) }, /* TOSHIBA Pocket PC e800 Series */
@@ -488,7 +488,7 @@ static struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
{ USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
{ USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
- { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PCDevice */
+ { USB_DEVICE(0x0CAD, 0x9001) }, /* Motorola PowerPad Pocket PC Device */
{ USB_DEVICE(0x0F4E, 0x0200) }, /* Freedom Scientific USB Sync */
{ USB_DEVICE(0x0F98, 0x0201) }, /* Cyberbank USB Sync */
{ USB_DEVICE(0x0FB8, 0x3001) }, /* Wistron USB Sync */
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 6831dca93c1..93a7724e167 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -3,7 +3,7 @@
* $Id: isd200.c,v 1.16 2002/04/22 03:39:43 mdharm Exp $
*
* Current development and maintenance:
- * (C) 2001-2002 Bjrn Stenberg (bjorn@haxx.se)
+ * (C) 2001-2002 Björn Stenberg (bjorn@haxx.se)
*
* Developed with the assistance of:
* (C) 2002 Alan Stern <stern@rowland.org>
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index cc8f7c52c72..889622baac2 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -195,7 +195,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
* the *offset and *index values for the next loop. */
cnt = 0;
while (cnt < buflen) {
- struct page *page = sg->page +
+ struct page *page = sg_page(sg) +
((sg->offset + *offset) >> PAGE_SHIFT);
unsigned int poff =
(sg->offset + *offset) & (PAGE_SIZE-1);
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index 9b656ec427d..22ab2380367 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -407,7 +407,7 @@ UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210,
"FinePix 1400Zoom",
US_SC_UFI, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY | US_FL_SINGLE_LUN),
-/* Reported by Peter Wchtler <pwaechtler@loewe-komp.de>
+/* Reported by Peter Wächtler <pwaechtler@loewe-komp.de>
* The device needs the flags only.
*/
UNUSUAL_DEV( 0x04ce, 0x0002, 0x0074, 0x0074,
@@ -1551,7 +1551,7 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999,
US_FL_GO_SLOW ),
/*
- * David Hrdeman <david@2gen.com>
+ * David Härdeman <david@2gen.com>
* The key makes the SCSI stack print confusing (but harmless) messages
*/
UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100,
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index b3bf4ecc983..fb9d8d0b2c0 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -661,7 +661,7 @@ config FB_HECUBA
help
This enables support for the Hecuba board. This driver was tested
with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
- interface (8 bit data, 4 bit control). If you anticpate using
+ interface (8 bit data, 4 bit control). If you anticipate using
this driver, say Y or M; otherwise say N. You must specify the
GPIO IO address to be used for setting control and data.
@@ -815,7 +815,7 @@ config FB_XVR500
help
This is the framebuffer device for the Sun XVR-500 and similar
graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
+ only works on sparc64 systems where the system firmware has
mostly initialized the card already. It is treated as a
completely dumb framebuffer device.
@@ -828,7 +828,7 @@ config FB_XVR2500
help
This is the framebuffer device for the Sun XVR-2500 and similar
graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firwmare has
+ only works on sparc64 systems where the system firmware has
mostly initialized the card already. It is treated as a
completely dumb framebuffer device.
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index f2e243c353f..4c9ec3f58c5 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -112,7 +112,7 @@
+----------+---------------------------------------------+----------+-------+
| | ^ | | |
| | |upper_margin | | |
- | | | | |
+ | | v | | |
+----------###############################################----------+-------+
| # ^ # | |
| # | # | |
@@ -133,15 +133,15 @@
| # | # | |
| # | # | |
| # | # | |
- | # # | |
+ | # v # | |
+----------###############################################----------+-------+
| | ^ | | |
| | |lower_margin | | |
- | | | | |
+ | | v | | |
+----------+---------------------------------------------+----------+-------+
| | ^ | | |
| | |vsync_len | | |
- | | | | |
+ | | v | | |
+----------+---------------------------------------------+----------+-------+
@@ -325,7 +325,7 @@
CCIR -> PAL
-----------
- - a scanline is 64 s long, of which 52.48 s are visible. This is about
+ - a scanline is 64 µs long, of which 52.48 µs are visible. This is about
736 visible 70 ns pixels per line.
- we have 625 scanlines, of which 575 are visible (interlaced); after
rounding this becomes 576.
@@ -333,7 +333,7 @@
RETMA -> NTSC
-------------
- - a scanline is 63.5 s long, of which 53.5 s are visible. This is about
+ - a scanline is 63.5 µs long, of which 53.5 µs are visible. This is about
736 visible 70 ns pixels per line.
- we have 525 scanlines, of which 485 are visible (interlaced); after
rounding this becomes 484.
@@ -802,7 +802,7 @@ static u_short ecs_palette[32];
static u_short do_vmode_full = 0; /* Change the Video Mode */
static u_short do_vmode_pan = 0; /* Update the Video Mode */
-static short do_blank = 0; /* (Un)Blank the Screen (1) */
+static short do_blank = 0; /* (Un)Blank the Screen (±1) */
static u_short do_cursor = 0; /* Move the Cursor */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index abe0c435a66..d775eb6590b 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -26,7 +26,7 @@
* Anthony Tong <atong@uiuc.edu>
*
* Generic LCD support written by Daniel Mantione, ported from 2.4.20 by Alex Kern
- * Many Thanks to Ville Syrjl for patches and fixing nasting 16 bit color bug.
+ * Many Thanks to Ville Syrjälä for patches and fixing nasting 16 bit color bug.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index a22ccf9485a..267422f6625 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -27,7 +27,7 @@ config VGACON_SOFT_SCROLLBACK
The scrollback buffer of the standard VGA console is located in
the VGA RAM. The size of this RAM is fixed and is quite small.
If you require a larger scrollback buffer, this can be placed in
- System RAM which is dynamically allocated during intialization.
+ System RAM which is dynamically allocated during initialization.
Placing the scrollback buffer in System RAM will slightly slow
down the console.
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 9bb2cbfe4a3..5fb8675e0d6 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -62,7 +62,7 @@ struct cfb_info {
struct display_switch *dispsw;
struct display *display;
struct pci_dev *dev;
- unsigned char __iomem *region;
+ unsigned char __iomem *region;
unsigned char __iomem *regs;
u_int id;
int func_use_count;
@@ -97,11 +97,11 @@ MODULE_PARM_DESC(default_font, "Default font name");
/*
* Our access methods.
*/
-#define cyber2000fb_writel(val,reg,cfb) writel(val, (cfb)->regs + (reg))
-#define cyber2000fb_writew(val,reg,cfb) writew(val, (cfb)->regs + (reg))
-#define cyber2000fb_writeb(val,reg,cfb) writeb(val, (cfb)->regs + (reg))
+#define cyber2000fb_writel(val, reg, cfb) writel(val, (cfb)->regs + (reg))
+#define cyber2000fb_writew(val, reg, cfb) writew(val, (cfb)->regs + (reg))
+#define cyber2000fb_writeb(val, reg, cfb) writeb(val, (cfb)->regs + (reg))
-#define cyber2000fb_readb(reg,cfb) readb((cfb)->regs + (reg))
+#define cyber2000fb_readb(reg, cfb) readb((cfb)->regs + (reg))
static inline void
cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb)
@@ -221,12 +221,8 @@ cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
static void
cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image)
{
-// struct cfb_info *cfb = (struct cfb_info *)info;
-
-// if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
- cfb_imageblit(info, image);
- return;
-// }
+ cfb_imageblit(info, image);
+ return;
}
static int cyber2000fb_sync(struct fb_info *info)
@@ -277,12 +273,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/*
* Pseudocolour:
- * 8 8
+ * 8 8
* pixel --/--+--/--> red lut --> red dac
- * | 8
- * +--/--> green lut --> green dac
- * | 8
- * +--/--> blue lut --> blue dac
+ * | 8
+ * +--/--> green lut --> green dac
+ * | 8
+ * +--/--> blue lut --> blue dac
*/
case FB_VISUAL_PSEUDOCOLOR:
if (regno >= NR_PALETTE)
@@ -292,9 +288,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
green >>= 8;
blue >>= 8;
- cfb->palette[regno].red = red;
+ cfb->palette[regno].red = red;
cfb->palette[regno].green = green;
- cfb->palette[regno].blue = blue;
+ cfb->palette[regno].blue = blue;
cyber2000fb_writeb(regno, 0x3c8, cfb);
cyber2000fb_writeb(red, 0x3c9, cfb);
@@ -304,12 +300,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/*
* Direct colour:
- * n rl
- * pixel --/--+--/--> red lut --> red dac
- * | gl
- * +--/--> green lut --> green dac
- * | bl
- * +--/--> blue lut --> blue dac
+ * n rl
+ * pixel --/--+--/--> red lut --> red dac
+ * | gl
+ * +--/--> green lut --> green dac
+ * | bl
+ * +--/--> blue lut --> blue dac
* n = bpp, rl = red length, gl = green length, bl = blue length
*/
case FB_VISUAL_DIRECTCOLOR:
@@ -325,9 +321,11 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* to the high 6 bits of the LUT.
*/
cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
- cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[regno >> 1].red,
+ 0x3c9, cfb);
cyber2000fb_writeb(green, 0x3c9, cfb);
- cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
+ cyber2000fb_writeb(cfb->palette[regno >> 1].blue,
+ 0x3c9, cfb);
green = cfb->palette[regno << 3].green;
@@ -335,9 +333,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
}
if (var->green.length >= 5 && regno < 32) {
- cfb->palette[regno << 3].red = red;
+ cfb->palette[regno << 3].red = red;
cfb->palette[regno << 3].green = green;
- cfb->palette[regno << 3].blue = blue;
+ cfb->palette[regno << 3].blue = blue;
/*
* The 5 bits of each colour component are
@@ -351,9 +349,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
}
if (var->green.length == 4 && regno < 16) {
- cfb->palette[regno << 4].red = red;
+ cfb->palette[regno << 4].red = red;
cfb->palette[regno << 4].green = green;
- cfb->palette[regno << 4].blue = blue;
+ cfb->palette[regno << 4].blue = blue;
/*
* The 5 bits of each colour component are
@@ -377,12 +375,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/*
* True colour:
- * n rl
- * pixel --/--+--/--> red dac
- * | gl
- * +--/--> green dac
- * | bl
- * +--/--> blue dac
+ * n rl
+ * pixel --/--+--/--> red dac
+ * | gl
+ * +--/--> green dac
+ * | bl
+ * +--/--> blue dac
* n = bpp, rl = red length, gl = green length, bl = blue length
*/
case FB_VISUAL_TRUECOLOR:
@@ -494,9 +492,9 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
/* PLL registers */
cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
- cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
+ cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
- cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
+ cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
cyber2000_grphw(0x90, 0x01, cfb);
cyber2000_grphw(0xb9, 0x80, cfb);
cyber2000_grphw(0xb9, 0x00, cfb);
@@ -515,8 +513,8 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
/*
* Set up accelerator registers
*/
- cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
- cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
+ cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
+ cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
}
@@ -549,15 +547,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
{
u_int Htotal, Hblankend, Hsyncend;
u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
-#define BIT(v,b1,m,b2) (((v >> b1) & m) << b2)
+#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2))
hw->crtc[13] = hw->pitch;
hw->crtc[17] = 0xe3;
hw->crtc[14] = 0;
hw->crtc[8] = 0;
- Htotal = var->xres + var->right_margin +
- var->hsync_len + var->left_margin;
+ Htotal = var->xres + var->right_margin +
+ var->hsync_len + var->left_margin;
if (Htotal > 2080)
return -EINVAL;
@@ -567,15 +565,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
hw->crtc[2] = var->xres >> 3;
hw->crtc[4] = (var->xres + var->right_margin) >> 3;
- Hblankend = (Htotal - 4*8) >> 3;
+ Hblankend = (Htotal - 4 * 8) >> 3;
- hw->crtc[3] = BIT(Hblankend, 0, 0x1f, 0) |
- BIT(1, 0, 0x01, 7);
+ hw->crtc[3] = ENCODE_BIT(Hblankend, 0, 0x1f, 0) |
+ ENCODE_BIT(1, 0, 0x01, 7);
Hsyncend = (var->xres + var->right_margin + var->hsync_len) >> 3;
- hw->crtc[5] = BIT(Hsyncend, 0, 0x1f, 0) |
- BIT(Hblankend, 5, 0x01, 7);
+ hw->crtc[5] = ENCODE_BIT(Hsyncend, 0, 0x1f, 0) |
+ ENCODE_BIT(Hblankend, 5, 0x01, 7);
Vdispend = var->yres - 1;
Vsyncstart = var->yres + var->lower_margin;
@@ -590,20 +588,20 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
Vblankend = Vtotal - 10;
hw->crtc[6] = Vtotal;
- hw->crtc[7] = BIT(Vtotal, 8, 0x01, 0) |
- BIT(Vdispend, 8, 0x01, 1) |
- BIT(Vsyncstart, 8, 0x01, 2) |
- BIT(Vblankstart,8, 0x01, 3) |
- BIT(1, 0, 0x01, 4) |
- BIT(Vtotal, 9, 0x01, 5) |
- BIT(Vdispend, 9, 0x01, 6) |
- BIT(Vsyncstart, 9, 0x01, 7);
- hw->crtc[9] = BIT(0, 0, 0x1f, 0) |
- BIT(Vblankstart,9, 0x01, 5) |
- BIT(1, 0, 0x01, 6);
+ hw->crtc[7] = ENCODE_BIT(Vtotal, 8, 0x01, 0) |
+ ENCODE_BIT(Vdispend, 8, 0x01, 1) |
+ ENCODE_BIT(Vsyncstart, 8, 0x01, 2) |
+ ENCODE_BIT(Vblankstart, 8, 0x01, 3) |
+ ENCODE_BIT(1, 0, 0x01, 4) |
+ ENCODE_BIT(Vtotal, 9, 0x01, 5) |
+ ENCODE_BIT(Vdispend, 9, 0x01, 6) |
+ ENCODE_BIT(Vsyncstart, 9, 0x01, 7);
+ hw->crtc[9] = ENCODE_BIT(0, 0, 0x1f, 0) |
+ ENCODE_BIT(Vblankstart, 9, 0x01, 5) |
+ ENCODE_BIT(1, 0, 0x01, 6);
hw->crtc[10] = Vsyncstart;
- hw->crtc[11] = BIT(Vsyncend, 0, 0x0f, 0) |
- BIT(1, 0, 0x01, 7);
+ hw->crtc[11] = ENCODE_BIT(Vsyncend, 0, 0x0f, 0) |
+ ENCODE_BIT(1, 0, 0x01, 7);
hw->crtc[12] = Vdispend;
hw->crtc[15] = Vblankstart;
hw->crtc[16] = Vblankend;
@@ -615,10 +613,10 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
* 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
*/
hw->crtc_ofl =
- BIT(Vtotal, 10, 0x01, 0) |
- BIT(Vdispend, 10, 0x01, 1) |
- BIT(Vsyncstart, 10, 0x01, 2) |
- BIT(Vblankstart,10, 0x01, 3) |
+ ENCODE_BIT(Vtotal, 10, 0x01, 0) |
+ ENCODE_BIT(Vdispend, 10, 0x01, 1) |
+ ENCODE_BIT(Vsyncstart, 10, 0x01, 2) |
+ ENCODE_BIT(Vblankstart, 10, 0x01, 3) |
EXT_CRT_VRTOFL_LINECOMP10;
/* woody: set the interlaced bit... */
@@ -750,11 +748,11 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->red.msb_right = 0;
var->green.msb_right = 0;
var->blue.msb_right = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
switch (var->bits_per_pixel) {
case 8: /* PSEUDOCOLOUR, 256 */
- var->transp.offset = 0;
- var->transp.length = 0;
var->red.offset = 0;
var->red.length = 8;
var->green.offset = 0;
@@ -766,8 +764,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
case 16:/* DIRECTCOLOUR, 64k or 32k */
switch (var->green.length) {
case 6: /* RGB565, 64k */
- var->transp.offset = 0;
- var->transp.length = 0;
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
@@ -778,8 +774,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
default:
case 5: /* RGB555, 32k */
- var->transp.offset = 0;
- var->transp.length = 0;
var->red.offset = 10;
var->red.length = 5;
var->green.offset = 5;
@@ -802,8 +796,6 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
break;
case 24:/* TRUECOLOUR, 16m */
- var->transp.offset = 0;
- var->transp.length = 0;
var->red.offset = 16;
var->red.length = 8;
var->green.offset = 8;
@@ -830,7 +822,7 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
if (mem > cfb->fb.fix.smem_len)
var->yres_virtual = cfb->fb.fix.smem_len * 8 /
- (var->bits_per_pixel * var->xres_virtual);
+ (var->bits_per_pixel * var->xres_virtual);
if (var->yres > var->yres_virtual)
var->yres = var->yres_virtual;
@@ -921,7 +913,7 @@ static int cyber2000fb_set_par(struct fb_info *info)
hw.fetch <<= 1;
hw.fetch += 1;
- cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
+ cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
/*
* Same here - if the size of the video mode exceeds the
@@ -952,7 +944,6 @@ static int cyber2000fb_set_par(struct fb_info *info)
return 0;
}
-
/*
* Pan or Wrap the Display
*/
@@ -1002,15 +993,15 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
switch (blank) {
case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */
sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
- break;
+ break;
case FB_BLANK_HSYNC_SUSPEND: /* hsync off */
sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
- break;
+ break;
case FB_BLANK_VSYNC_SUSPEND: /* vsync off */
sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
break;
- case FB_BLANK_NORMAL: /* soft blank */
- default: /* unblank */
+ case FB_BLANK_NORMAL: /* soft blank */
+ default: /* unblank */
break;
}
@@ -1018,7 +1009,8 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
if (blank <= 1) {
/* turn on ramdacs */
- cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
+ cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+ RAMDAC_RAMPWRDN);
cyber2000fb_write_ramdac_ctrl(cfb);
}
@@ -1043,7 +1035,8 @@ static int cyber2000fb_blank(int blank, struct fb_info *info)
if (blank >= 2) {
/* turn off ramdacs */
- cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN;
+ cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS |
+ RAMDAC_RAMPWRDN;
cyber2000fb_write_ramdac_ctrl(cfb);
}
@@ -1068,7 +1061,7 @@ static struct fb_ops cyber2000fb_ops = {
* of this driver. It is here solely at the moment to support the other
* CyberPro modules external to this driver.
*/
-static struct cfb_info *int_cfb_info;
+static struct cfb_info *int_cfb_info;
/*
* Enable access to the extended registers
@@ -1085,6 +1078,7 @@ void cyber2000fb_enable_extregs(struct cfb_info *cfb)
cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
}
}
+EXPORT_SYMBOL(cyber2000fb_enable_extregs);
/*
* Disable access to the extended registers
@@ -1104,11 +1098,13 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb)
else
cfb->func_use_count -= 1;
}
+EXPORT_SYMBOL(cyber2000fb_disable_extregs);
void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
{
memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
}
+EXPORT_SYMBOL(cyber2000fb_get_fb_var);
/*
* Attach a capture/tv driver to the core CyberX0X0 driver.
@@ -1122,13 +1118,15 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
info->fb_size = int_cfb_info->fb.fix.smem_len;
info->enable_extregs = cyber2000fb_enable_extregs;
info->disable_extregs = cyber2000fb_disable_extregs;
- info->info = int_cfb_info;
+ info->info = int_cfb_info;
- strlcpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
+ strlcpy(info->dev_name, int_cfb_info->fb.fix.id,
+ sizeof(info->dev_name));
}
return int_cfb_info != NULL;
}
+EXPORT_SYMBOL(cyber2000fb_attach);
/*
* Detach a capture/tv driver from the core CyberX0X0 driver.
@@ -1136,12 +1134,7 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
void cyber2000fb_detach(int idx)
{
}
-
-EXPORT_SYMBOL(cyber2000fb_attach);
EXPORT_SYMBOL(cyber2000fb_detach);
-EXPORT_SYMBOL(cyber2000fb_enable_extregs);
-EXPORT_SYMBOL(cyber2000fb_disable_extregs);
-EXPORT_SYMBOL(cyber2000fb_get_fb_var);
/*
* These parameters give
@@ -1205,7 +1198,7 @@ static void cyberpro_init_hw(struct cfb_info *cfb)
int i;
for (i = 0; i < sizeof(igs_regs); i += 2)
- cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
+ cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb);
if (cfb->id == ID_CYBERPRO_5000) {
unsigned char val;
@@ -1215,8 +1208,8 @@ static void cyberpro_init_hw(struct cfb_info *cfb)
}
}
-static struct cfb_info * __devinit
-cyberpro_alloc_fb_info(unsigned int id, char *name)
+static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id,
+ char *name)
{
struct cfb_info *cfb;
@@ -1228,9 +1221,9 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
cfb->id = id;
if (id == ID_CYBERPRO_5000)
- cfb->ref_ps = 40690; // 24.576 MHz
+ cfb->ref_ps = 40690; /* 24.576 MHz */
else
- cfb->ref_ps = 69842; // 14.31818 MHz (69841?)
+ cfb->ref_ps = 69842; /* 14.31818 MHz (69841?) */
cfb->divisors[0] = 1;
cfb->divisors[1] = 2;
@@ -1282,8 +1275,7 @@ cyberpro_alloc_fb_info(unsigned int id, char *name)
return cfb;
}
-static void
-cyberpro_free_fb_info(struct cfb_info *cfb)
+static void cyberpro_free_fb_info(struct cfb_info *cfb)
{
if (cfb) {
/*
@@ -1300,8 +1292,7 @@ cyberpro_free_fb_info(struct cfb_info *cfb)
* video=cyber2000:font:fontname
*/
#ifndef MODULE
-static int
-cyber2000fb_setup(char *options)
+static int cyber2000fb_setup(char *options)
{
char *opt;
@@ -1315,7 +1306,8 @@ cyber2000fb_setup(char *options)
if (strncmp(opt, "font:", 5) == 0) {
static char default_font_storage[40];
- strlcpy(default_font_storage, opt + 5, sizeof(default_font_storage));
+ strlcpy(default_font_storage, opt + 5,
+ sizeof(default_font_storage));
default_font = default_font_storage;
continue;
}
@@ -1354,10 +1346,18 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
* Determine the size of the memory.
*/
switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
- case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break;
- case MEM_CTL2_SIZE_2MB: smem_size = 0x00200000; break;
- case MEM_CTL2_SIZE_1MB: smem_size = 0x00100000; break;
- default: smem_size = 0x00100000; break;
+ case MEM_CTL2_SIZE_4MB:
+ smem_size = 0x00400000;
+ break;
+ case MEM_CTL2_SIZE_2MB:
+ smem_size = 0x00200000;
+ break;
+ case MEM_CTL2_SIZE_1MB:
+ smem_size = 0x00100000;
+ break;
+ default:
+ smem_size = 0x00100000;
+ break;
}
cfb->fb.fix.smem_len = smem_size;
@@ -1366,8 +1366,8 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
err = -EINVAL;
if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
- &cyber2000fb_default_mode, 8)) {
- printk("%s: no valid mode found\n", cfb->fb.fix.id);
+ &cyber2000fb_default_mode, 8)) {
+ printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id);
goto failed;
}
@@ -1377,7 +1377,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
cfb->fb.var.yres_virtual = cfb->fb.var.yres;
-// fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+/* fb_set_var(&cfb->fb.var, -1, &cfb->fb); */
/*
* Calculate the hsync and vsync frequencies. Note that
@@ -1425,20 +1425,20 @@ static void cyberpro_common_resume(struct cfb_info *cfb)
#include <asm/arch/hardware.h>
-static int __devinit
-cyberpro_vl_probe(void)
+static int __devinit cyberpro_vl_probe(void)
{
struct cfb_info *cfb;
int err = -ENOMEM;
- if (!request_mem_region(FB_START,FB_SIZE,"CyberPro2010")) return err;
+ if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010"))
+ return err;
cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
if (!cfb)
goto failed_release;
cfb->dev = NULL;
- cfb->region = ioremap(FB_START,FB_SIZE);
+ cfb->region = ioremap(FB_START, FB_SIZE);
if (!cfb->region)
goto failed_ioremap;
@@ -1475,7 +1475,7 @@ failed:
failed_ioremap:
cyberpro_free_fb_info(cfb);
failed_release:
- release_mem_region(FB_START,FB_SIZE);
+ release_mem_region(FB_START, FB_SIZE);
return err;
}
@@ -1538,7 +1538,8 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
* Allow the CyberPro to accept PCI burst accesses
*/
if (cfb->id == ID_CYBERPRO_2010) {
- printk(KERN_INFO "%s: NOT enabling PCI bursts\n", cfb->fb.fix.id);
+ printk(KERN_INFO "%s: NOT enabling PCI bursts\n",
+ cfb->fb.fix.id);
} else {
val = cyber2000_grphr(EXT_BUS_CTL, cfb);
if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
@@ -1688,9 +1689,10 @@ static int cyberpro_pci_resume(struct pci_dev *dev)
}
static struct pci_device_id cyberpro_pci_table[] = {
-// Not yet
-// { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
-// PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+/* Not yet
+ * { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
+ * PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
+ */
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
@@ -1700,7 +1702,7 @@ static struct pci_device_id cyberpro_pci_table[] = {
{ 0, }
};
-MODULE_DEVICE_TABLE(pci,cyberpro_pci_table);
+MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
static struct pci_driver cyberpro_driver = {
.name = "CyberPro",
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c
index 7f3f18d0671..febf09c6349 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/geode/video_gx.c
@@ -127,7 +127,7 @@ static void gx_set_dclk_frequency(struct fb_info *info)
int timeout = 1000;
/* Rev. 1 Geode GXs use a 14 MHz reference clock instead of 48 MHz. */
- if (cpu_data->x86_mask == 1) {
+ if (cpu_data(0).x86_mask == 1) {
pll_table = gx_pll_table_14MHz;
pll_table_len = ARRAY_SIZE(gx_pll_table_14MHz);
} else {
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index e8e38edb9b5..481d58f7535 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -4,7 +4,7 @@
* Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
* 945G/945GM integrated graphics chips.
*
- * Copyright 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
* 2004 Sylvain Meyer
* 2006 David Airlie
*
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 2a0e32074f7..5f6fb7d2c40 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -3,7 +3,7 @@
*
* Linux framebuffer driver for Intel(R) 865G integrated graphics chips.
*
- * Copyright 2002, 2003 David Dawes <dawes@xfree86.org>
+ * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
* 2004 Sylvain Meyer
*
* This driver consists of two parts. The first part (intelfbdrv.c) provides
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
index 7f4d25b8a18..f4fcf11b290 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/omap/Kconfig
@@ -8,7 +8,7 @@ config FB_OMAP
Frame buffer driver for OMAP based boards.
config FB_OMAP_BOOTLOADER_INIT
- bool "Check bootloader initializaion"
+ bool "Check bootloader initialization"
depends on FB_OMAP
help
Say Y here if you want to enable checking if the bootloader has
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
index e8c5dcdd881..189c3d64138 100644
--- a/drivers/video/pnx4008/sdum.h
+++ b/drivers/video/pnx4008/sdum.h
@@ -77,9 +77,6 @@
#define CONF_DIRTYDETECTION_OFF (0x600)
#define CONF_DIRTYDETECTION_ON (0x601)
-/* Set the corresponding bit. */
-#define BIT(n) (0x1U << (n))
-
struct dumchannel_uf {
int channelnr;
u32 *dirty;
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index ae08d458709..5857ccf5f6b 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -56,7 +56,7 @@
* - Add support for different devices
* - Backlight support
*
- * 2004-09-05: Herbert Ptzl <herbert@13thfloor.at>
+ * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
* - added clock (de-)allocation code
* - added fixem fbmem option
*
@@ -64,7 +64,7 @@
* - code cleanup
* - added a forgotten return in h1940fb_init
*
- * 2004-07-19: Herbert Ptzl <herbert@13thfloor.at>
+ * 2004-07-19: Herbert Pötzl <herbert@13thfloor.at>
* - code cleanup and extended debugging
*
* 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index ff9e805c43b..c31f549ebea 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -23,8 +23,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
- * Michel Dnzer <michel-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ * Michel Dänzer <michel-at-tungstengraphics-dot-com>
* Alan Hourihane <alanh-at-tungstengraphics-dot-com>
*/
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
index 1fc6695a49d..c4aba59d480 100644
--- a/drivers/video/vermilion/vermilion.h
+++ b/drivers/video/vermilion/vermilion.h
@@ -23,7 +23,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
- * Thomas Hellstrm <thomas-at-tungstengraphics-dot-com>
+ * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
*/
#ifndef _VERMILION_H_
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c
index 38bd3737259..a684b1e8737 100644
--- a/drivers/watchdog/at91rm9200_wdt.c
+++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -19,7 +20,6 @@
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/arch/at91_st.h>
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c
index c5982502c03..f236954d253 100644
--- a/drivers/watchdog/i6300esb.c
+++ b/drivers/watchdog/i6300esb.c
@@ -2,7 +2,7 @@
* i6300esb: Watchdog timer driver for Intel 6300ESB chipset
*
* (c) Copyright 2004 Google Inc.
- * (c) Copyright 2005 David Hrdeman <david@2gen.com>
+ * (c) Copyright 2005 David Härdeman <david@2gen.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,7 +19,7 @@
* Initial version 0.01
* 2004YYZZ Ross Biro
* Version 0.02
- * 20050210 David Hrdeman <david@2gen.com>
+ * 20050210 David Härdeman <david@2gen.com>
* Ported driver to kernel 2.6
*/
@@ -521,7 +521,7 @@ static void __exit watchdog_cleanup (void)
module_init(watchdog_init);
module_exit(watchdog_cleanup);
-MODULE_AUTHOR("Ross Biro and David Hrdeman");
+MODULE_AUTHOR("Ross Biro and David Härdeman");
MODULE_DESCRIPTION("Watchdog driver for Intel 6300ESB chipsets");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c
index 41508399009..cafc465f2ae 100644
--- a/drivers/watchdog/iTCO_vendor_support.c
+++ b/drivers/watchdog/iTCO_vendor_support.c
@@ -115,7 +115,7 @@ static void supermicro_old_pre_keepalive(unsigned long acpibase)
* For P4DPx:
* BIOS setup -> Advanced -> I/O Device Configuration -> Watch Dog
* This setting enables or disables Watchdog function. When enabled, the
- * default watchdog timer is set to be 5 minutes (about 4’35”). It is
+ * default watchdog timer is set to be 5 minutes (about 4m35s). It is
* enough to load and run the OS. The application (service or driver) has
* to take over the control once OS is running up and before watchdog
* expires.
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c
index 7150fb945ea..e3a29c30230 100644
--- a/drivers/watchdog/ks8695_wdt.c
+++ b/drivers/watchdog/ks8695_wdt.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/init.h>
@@ -18,7 +19,6 @@
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/watchdog.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/arch/regs-timer.h>
diff --git a/drivers/watchdog/mpc5200_wdt.c b/drivers/watchdog/mpc5200_wdt.c
index 9cfb9757662..11f6a111e75 100644
--- a/drivers/watchdog/mpc5200_wdt.c
+++ b/drivers/watchdog/mpc5200_wdt.c
@@ -176,6 +176,8 @@ static int mpc5200_wdt_probe(struct of_device *op, const struct of_device_id *ma
has_wdt = of_get_property(op->node, "has-wdt", NULL);
if (!has_wdt)
+ has_wdt = of_get_property(op->node, "fsl,has-wdt", NULL);
+ if (!has_wdt)
return -ENODEV;
wdt = kzalloc(sizeof(*wdt), GFP_KERNEL);
@@ -254,6 +256,7 @@ static int mpc5200_wdt_shutdown(struct of_device *op)
static struct of_device_id mpc5200_wdt_match[] = {
{ .compatible = "mpc5200-gpt", },
+ { .compatible = "fsl,mpc5200-gpt", },
{},
};
static struct of_platform_driver mpc5200_wdt_driver = {
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
index 719b066f73c..635ca454f56 100644
--- a/drivers/watchdog/omap_wdt.c
+++ b/drivers/watchdog/omap_wdt.c
@@ -39,11 +39,11 @@
#include <linux/platform_device.h>
#include <linux/moduleparam.h>
#include <linux/clk.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
-#include <asm/bitops.h>
#include <asm/arch/prcm.h>
diff --git a/drivers/watchdog/sa1100_wdt.c b/drivers/watchdog/sa1100_wdt.c
index 3475f47aaa4..34a2b3b8180 100644
--- a/drivers/watchdog/sa1100_wdt.c
+++ b/drivers/watchdog/sa1100_wdt.c
@@ -25,13 +25,13 @@
#include <linux/miscdevice.h>
#include <linux/watchdog.h>
#include <linux/init.h>
+#include <linux/bitops.h>
#ifdef CONFIG_ARCH_PXA
#include <asm/arch/pxa-regs.h>
#endif
#include <asm/hardware.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#define OSCR_FREQ CLOCK_TICK_RATE
diff --git a/drivers/watchdog/w83697hf_wdt.c b/drivers/watchdog/w83697hf_wdt.c
index d9e821d08de..51826c216d6 100644
--- a/drivers/watchdog/w83697hf_wdt.c
+++ b/drivers/watchdog/w83697hf_wdt.c
@@ -8,7 +8,7 @@
* which is based on wdt.c.
* Original copyright messages:
*
- * (c) Copyright 2003 Pdraig Brady <P@draigBrady.com>
+ * (c) Copyright 2003 Pádraig Brady <P@draigBrady.com>
*
* (c) Copyright 2000-2001 Marek Michalkiewicz <marekm@linux.org.pl>
*
diff --git a/drivers/zorro/zorro.ids b/drivers/zorro/zorro.ids
index 5bd4b05d4c4..560fef2a7b1 100644
--- a/drivers/zorro/zorro.ids
+++ b/drivers/zorro/zorro.ids
@@ -295,7 +295,7 @@
0100 RH 800C [HD Controller]
0200 RH 800C [RAM Expansion]
0861 Kato
-# The Rainbow II and III are actually made by Ingenieurbro Helfrich
+# The Rainbow II and III are actually made by Ingenieurbüro Helfrich
2000 Rainbow II [Graphics Card]
2100 Rainbow III [Graphics Card]
8000 Melody MPEG [Audio Card]
diff --git a/fs/Kconfig b/fs/Kconfig
index e31f3691b15..cc28a69246a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -220,7 +220,7 @@ config JBD
config JBD_DEBUG
bool "JBD (ext3) debugging support"
- depends on JBD
+ depends on JBD && DEBUG_FS
help
If you are using the ext3 journaled file system (or potentially any
other file system/device using JBD), this option allows you to
@@ -229,10 +229,10 @@ config JBD_DEBUG
debugging output will be turned off.
If you select Y here, then you will be able to turn on debugging
- with "echo N > /proc/sys/fs/jbd-debug", where N is a number between
- 1 and 5, the higher the number, the more debugging output is
- generated. To turn debugging off again, do
- "echo 0 > /proc/sys/fs/jbd-debug".
+ with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
+ number between 1 and 5, the higher the number, the more debugging
+ output is generated. To turn debugging off again, do
+ "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
config JBD2
tristate
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index e7204d71acc..45f5992a095 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -80,7 +80,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
*uid = current->uid;
*gid = current->gid;
- *pgrp = process_group(current);
+ *pgrp = task_pgrp_nr(current);
*minproto = *maxproto = AUTOFS_PROTO_VERSION;
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index c1489533277..5efff3c0d88 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -214,8 +214,8 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
oz_mode = autofs_oz_mode(sbi);
DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, "
- "oz_mode = %d\n", pid_nr(task_pid(current)),
- process_group(current), sbi->catatonic,
+ "oz_mode = %d\n", task_pid_nr(current),
+ task_pgrp_nr(current), sbi->catatonic,
oz_mode));
/*
@@ -536,7 +536,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp,
struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb);
void __user *argp = (void __user *)arg;
- DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current)));
+ DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current)));
if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
_IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index d85f42fa920..2d4ae40718d 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -131,7 +131,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry)
filesystem without "magic".) */
static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) {
- return sbi->catatonic || process_group(current) == sbi->oz_pgrp;
+ return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp;
}
/* Does a dentry have some pending activity? */
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index cd81f083667..7f05d6ccdb1 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -226,7 +226,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
*uid = current->uid;
*gid = current->gid;
- *pgrp = process_group(current);
+ *pgrp = task_pgrp_nr(current);
*minproto = AUTOFS_MIN_PROTO_VERSION;
*maxproto = AUTOFS_MAX_PROTO_VERSION;
@@ -323,7 +323,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
sbi->pipe = NULL;
sbi->catatonic = 1;
sbi->exp_timeout = 0;
- sbi->oz_pgrp = process_group(current);
+ sbi->oz_pgrp = task_pgrp_nr(current);
sbi->sb = s;
sbi->version = 0;
sbi->sub_version = 0;
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c
index 45ff3d63b75..2bbcc8151dc 100644
--- a/fs/autofs4/root.c
+++ b/fs/autofs4/root.c
@@ -582,7 +582,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
oz_mode = autofs4_oz_mode(sbi);
DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
- current->pid, process_group(current), sbi->catatonic, oz_mode);
+ current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name);
if (!unhashed) {
@@ -976,7 +976,7 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp,
void __user *p = (void __user *)arg;
DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u",
- cmd,arg,sbi,process_group(current));
+ cmd,arg,sbi,task_pgrp_nr(current));
if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) ||
_IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 6e2f3b8dde7..ba8de7ca260 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1383,10 +1383,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
prstatus->pr_sigpend = p->pending.signal.sig[0];
prstatus->pr_sighold = p->blocked.sig[0];
- prstatus->pr_pid = p->pid;
- prstatus->pr_ppid = p->parent->pid;
- prstatus->pr_pgrp = process_group(p);
- prstatus->pr_sid = process_session(p);
+ prstatus->pr_pid = task_pid_vnr(p);
+ prstatus->pr_ppid = task_pid_vnr(p->parent);
+ prstatus->pr_pgrp = task_pgrp_vnr(p);
+ prstatus->pr_sid = task_session_vnr(p);
if (thread_group_leader(p)) {
/*
* This is the record for the group leader. Add in the
@@ -1429,10 +1429,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
psinfo->pr_psargs[i] = ' ';
psinfo->pr_psargs[len] = 0;
- psinfo->pr_pid = p->pid;
- psinfo->pr_ppid = p->parent->pid;
- psinfo->pr_pgrp = process_group(p);
- psinfo->pr_sid = process_session(p);
+ psinfo->pr_pid = task_pid_vnr(p);
+ psinfo->pr_ppid = task_pid_vnr(p->parent);
+ psinfo->pr_pgrp = task_pgrp_vnr(p);
+ psinfo->pr_sid = task_session_vnr(p);
i = p->state ? ffz(~p->state) + 1 : 0;
psinfo->pr_state = i;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 033861c6b8f..32649f2a165 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1342,10 +1342,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
prstatus->pr_sigpend = p->pending.signal.sig[0];
prstatus->pr_sighold = p->blocked.sig[0];
- prstatus->pr_pid = p->pid;
- prstatus->pr_ppid = p->parent->pid;
- prstatus->pr_pgrp = process_group(p);
- prstatus->pr_sid = process_session(p);
+ prstatus->pr_pid = task_pid_vnr(p);
+ prstatus->pr_ppid = task_pid_vnr(p->parent);
+ prstatus->pr_pgrp = task_pgrp_vnr(p);
+ prstatus->pr_sid = task_session_vnr(p);
if (thread_group_leader(p)) {
/*
* This is the record for the group leader. Add in the
@@ -1391,10 +1391,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
psinfo->pr_psargs[i] = ' ';
psinfo->pr_psargs[len] = 0;
- psinfo->pr_pid = p->pid;
- psinfo->pr_ppid = p->parent->pid;
- psinfo->pr_pgrp = process_group(p);
- psinfo->pr_sid = process_session(p);
+ psinfo->pr_pid = task_pid_vnr(p);
+ psinfo->pr_ppid = task_pid_vnr(p->parent);
+ psinfo->pr_pgrp = task_pgrp_vnr(p);
+ psinfo->pr_sid = task_session_vnr(p);
i = p->state ? ffz(~p->state) + 1 : 0;
psinfo->pr_state = i;
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 576dd7de227..f95ae9789c9 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -2,7 +2,7 @@
* linux/fs/binfmt_em86.c
*
* Based on linux/fs/binfmt_script.c
- * Copyright (C) 1996 Martin von Lwis
+ * Copyright (C) 1996 Martin von Löwis
* original #!-checking implemented by tytso.
*
* em86 changes Copyright (C) 1997 Jim Paradis
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 42e94b3ab7b..b53c7e5f41b 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -1,7 +1,7 @@
/*
* binfmt_misc.c
*
- * Copyright (C) 1997 Richard Gnther
+ * Copyright (C) 1997 Richard Günther
*
* binfmt_misc detects binaries via a magic or filename extension and invokes
* a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 4d0e0f6d327..ab33939b12a 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -1,7 +1,7 @@
/*
* linux/fs/binfmt_script.c
*
- * Copyright (C) 1996 Martin von Lwis
+ * Copyright (C) 1996 Martin von Löwis
* original #!-checking implemented by tytso.
*/
diff --git a/fs/buffer.c b/fs/buffer.c
index 76403b1764c..7249e014819 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2563,7 +2563,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
struct page *page, void *fsdata)
{
struct inode *inode = page->mapping->host;
- struct buffer_head *head = NULL;
+ struct buffer_head *head = fsdata;
struct buffer_head *bh;
if (!PageMappedToDisk(page)) {
@@ -2584,7 +2584,6 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
unlock_page(page);
page_cache_release(page);
- head = fsdata;
while (head) {
bh = head;
head = head->b_this_page;
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index bed6215c079..3d419163c3d 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,19 @@
+Version 1.51
+------------
+Fix memory leak in statfs when mounted to very old servers (e.g.
+Windows 9x). Add new feature "POSIX open" which allows servers
+which support the current POSIX Extensions to provide better semantics
+(e.g. delete for open files opened with posix open). Take into
+account umask on posix mkdir not just older style mkdir. Add
+ability to mount to IPC$ share (which allows CIFS named pipes to be
+opened, read and written as if they were files). When 1st tree
+connect fails (e.g. due to signing negotiation failure) fix
+leak that causes cifsd not to stop and rmmod to fail to cleanup
+cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
+bigendian architectures. Fix possible memory corruption when
+EAGAIN returned on kern_recvmsg. Return better error if server
+requires packet signing but client has disabled it.
+
Version 1.50
------------
Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
@@ -6,7 +22,10 @@ done with "serverino" mount option). Add support for POSIX Unlink
Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
mount option to allow disabling the CIFS Unix Extensions for just
that mount. Fix hang on spinlock in find_writable_file (race when
-reopening file after session crash).
+reopening file after session crash). Byte range unlock request to
+windows server could unlock more bytes (on server copy of file)
+than intended if start of unlock request is well before start of
+a previous byte range lock that we issued.
Version 1.49
------------
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 6ecd9d6ba3f..ff6ba8d823f 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -3,4 +3,4 @@
#
obj-$(CONFIG_CIFS) += cifs.o
-cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o
+cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index f50a88d58f7..2a01f3ef96a 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -385,10 +385,9 @@ asn1_oid_decode(struct asn1_ctx *ctx,
unsigned long *optr;
size = eoc - ctx->pointer + 1;
- *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC);
- if (*oid == NULL) {
+ *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
+ if (*oid == NULL)
return 0;
- }
optr = *oid;
@@ -581,9 +580,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) {
- cFYI(1,
- ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end));
+ cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)",
+ cls, con, tag, end, *end));
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 1bf8cf522ad..73c4c419663 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -209,13 +209,16 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
i++;
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
- length =
- sprintf(buf,
- "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x "
- "Attributes: 0x%x\nPathComponentMax: %d Status: %d",
- i, tcon->treeName,
- atomic_read(&tcon->useCount),
- tcon->nativeFileSystem,
+ length = sprintf(buf, "\n%d) %s Uses: %d ", i,
+ tcon->treeName, atomic_read(&tcon->useCount));
+ buf += length;
+ if (tcon->nativeFileSystem) {
+ length = sprintf(buf, "Type: %s ",
+ tcon->nativeFileSystem);
+ buf += length;
+ }
+ length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x"
+ "\nPathComponentMax: %d Status: %d",
le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
le32_to_cpu(tcon->fsAttrInfo.Attributes),
le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
@@ -876,11 +879,16 @@ security_flags_write(struct file *file, const char __user *buffer,
if (count < 3) {
/* single char or single char followed by null */
c = flags_string[0];
- if (c == '0' || c == 'n' || c == 'N')
+ if (c == '0' || c == 'n' || c == 'N') {
extended_security = CIFSSEC_DEF; /* default */
- else if (c == '1' || c == 'y' || c == 'Y')
+ return count;
+ } else if (c == '1' || c == 'y' || c == 'Y') {
extended_security = CIFSSEC_MAX;
- return count;
+ return count;
+ } else if (!isdigit(c)) {
+ cERROR(1, ("invalid flag %c", c));
+ return -EINVAL;
+ }
}
/* else we have a number */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
new file mode 100644
index 00000000000..e8e56353f5a
--- /dev/null
+++ b/fs/cifs/cifsacl.c
@@ -0,0 +1,333 @@
+/*
+ * fs/cifs/cifsacl.c
+ *
+ * Copyright (C) International Business Machines Corp., 2007
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * Contains the routines for mapping CIFS/NTFS ACLs
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include "cifspdu.h"
+#include "cifsglob.h"
+#include "cifsacl.h"
+#include "cifsproto.h"
+#include "cifs_debug.h"
+
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
+ {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
+ {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
+ {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"},
+ {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"},
+ {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"},
+ {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"},
+ {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"}
+};
+
+
+/* security id for everyone */
+static const struct cifs_sid sid_everyone =
+ {1, 1, {0, 0, 0, 0, 0, 0}, {} };
+/* group users */
+static const struct cifs_sid sid_user =
+ {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
+
+
+int match_sid(struct cifs_sid *ctsid)
+{
+ int i, j;
+ int num_subauth, num_sat, num_saw;
+ struct cifs_sid *cwsid;
+
+ if (!ctsid)
+ return (-1);
+
+ for (i = 0; i < NUM_WK_SIDS; ++i) {
+ cwsid = &(wksidarr[i].cifssid);
+
+ /* compare the revision */
+ if (ctsid->revision != cwsid->revision)
+ continue;
+
+ /* compare all of the six auth values */
+ for (j = 0; j < 6; ++j) {
+ if (ctsid->authority[j] != cwsid->authority[j])
+ break;
+ }
+ if (j < 6)
+ continue; /* all of the auth values did not match */
+
+ /* compare all of the subauth values if any */
+ num_sat = ctsid->num_subauth;
+ num_saw = cwsid->num_subauth;
+ num_subauth = num_sat < num_saw ? num_sat : num_saw;
+ if (num_subauth) {
+ for (j = 0; j < num_subauth; ++j) {
+ if (ctsid->sub_auth[j] != cwsid->sub_auth[j])
+ break;
+ }
+ if (j < num_subauth)
+ continue; /* all sub_auth values do not match */
+ }
+
+ cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname));
+ return (0); /* sids compare/match */
+ }
+
+ cFYI(1, ("No matching sid"));
+ return (-1);
+}
+
+/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
+ the same returns 1, if they do not match returns 0 */
+int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid)
+{
+ int i;
+ int num_subauth, num_sat, num_saw;
+
+ if ((!ctsid) || (!cwsid))
+ return (0);
+
+ /* compare the revision */
+ if (ctsid->revision != cwsid->revision)
+ return (0);
+
+ /* compare all of the six auth values */
+ for (i = 0; i < 6; ++i) {
+ if (ctsid->authority[i] != cwsid->authority[i])
+ return (0);
+ }
+
+ /* compare all of the subauth values if any */
+ num_sat = ctsid->num_subauth;
+ num_saw = cwsid->num_subauth;
+ num_subauth = num_sat < num_saw ? num_sat : num_saw;
+ if (num_subauth) {
+ for (i = 0; i < num_subauth; ++i) {
+ if (ctsid->sub_auth[i] != cwsid->sub_auth[i])
+ return (0);
+ }
+ }
+
+ return (1); /* sids compare/match */
+}
+
+
+static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
+{
+ int num_subauth;
+
+ /* validate that we do not go past end of acl */
+
+ /* XXX this if statement can be removed
+ if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) {
+ cERROR(1, ("ACL too small to parse ACE"));
+ return;
+ } */
+
+ num_subauth = pace->num_subauth;
+ if (num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+ int i;
+ cFYI(1, ("ACE revision %d num_subauth %d",
+ pace->revision, pace->num_subauth));
+ for (i = 0; i < num_subauth; ++i) {
+ cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
+ le32_to_cpu(pace->sub_auth[i])));
+ }
+
+ /* BB add length check to make sure that we do not have huge
+ num auths and therefore go off the end */
+
+ cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1])));
+#endif
+ }
+
+ return;
+}
+
+static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl)
+{
+ /* validate that we do not go past end of acl */
+ if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) {
+ cERROR(1, ("ACL too small to parse NT ACE"));
+ return;
+ }
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x",
+ pntace->type, pntace->flags, pntace->size,
+ pntace->access_req));
+#endif
+ return;
+}
+
+
+
+static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
+ struct cifs_sid *pownersid, struct cifs_sid *pgrpsid)
+{
+ int i;
+ int num_aces = 0;
+ int acl_size;
+ char *acl_base;
+ struct cifs_ntace **ppntace;
+ struct cifs_ace **ppace;
+
+ /* BB need to add parm so we can store the SID BB */
+
+ /* validate that we do not go past end of acl */
+ if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
+ cERROR(1, ("ACL too small to parse DACL"));
+ return;
+ }
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("DACL revision %d size %d num aces %d",
+ le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
+ le32_to_cpu(pdacl->num_aces)));
+#endif
+
+ acl_base = (char *)pdacl;
+ acl_size = sizeof(struct cifs_acl);
+
+ num_aces = le32_to_cpu(pdacl->num_aces);
+ if (num_aces > 0) {
+ ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
+ GFP_KERNEL);
+ ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
+ GFP_KERNEL);
+
+/* cifscred->cecount = pdacl->num_aces;
+ cifscred->ntaces = kmalloc(num_aces *
+ sizeof(struct cifs_ntace *), GFP_KERNEL);
+ cifscred->aces = kmalloc(num_aces *
+ sizeof(struct cifs_ace *), GFP_KERNEL);*/
+
+ for (i = 0; i < num_aces; ++i) {
+ ppntace[i] = (struct cifs_ntace *)
+ (acl_base + acl_size);
+ ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] +
+ sizeof(struct cifs_ntace));
+
+ parse_ntace(ppntace[i], end_of_acl);
+ if (end_of_acl < ((char *)ppace[i] +
+ (le16_to_cpu(ppntace[i]->size) -
+ sizeof(struct cifs_ntace)))) {
+ cERROR(1, ("ACL too small to parse ACE"));
+ break;
+ } else
+ parse_ace(ppace[i], end_of_acl);
+
+/* memcpy((void *)(&(cifscred->ntaces[i])),
+ (void *)ppntace[i],
+ sizeof(struct cifs_ntace));
+ memcpy((void *)(&(cifscred->aces[i])),
+ (void *)ppace[i],
+ sizeof(struct cifs_ace)); */
+
+ acl_base = (char *)ppntace[i];
+ acl_size = le16_to_cpu(ppntace[i]->size);
+ }
+
+ kfree(ppace);
+ kfree(ppntace);
+ }
+
+ return;
+}
+
+
+static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
+{
+
+ /* BB need to add parm so we can store the SID BB */
+
+ /* validate that we do not go past end of acl */
+ if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
+ cERROR(1, ("ACL too small to parse SID"));
+ return -EINVAL;
+ }
+
+ if (psid->num_subauth) {
+#ifdef CONFIG_CIFS_DEBUG2
+ int i;
+ cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x",
+ psid->revision, psid->num_subauth, psid->sub_auth[0]));
+
+ for (i = 0; i < psid->num_subauth; i++) {
+ cFYI(1, ("SID sub_auth[%d]: 0x%x ", i,
+ le32_to_cpu(psid->sub_auth[i])));
+ }
+
+ /* BB add length check to make sure that we do not have huge
+ num auths and therefore go off the end */
+ cFYI(1, ("RID 0x%x",
+ le32_to_cpu(psid->sub_auth[psid->num_subauth-1])));
+#endif
+ }
+
+ return 0;
+}
+
+
+/* Convert CIFS ACL to POSIX form */
+int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
+{
+ int rc;
+ struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+ struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
+ char *end_of_acl = ((char *)pntsd) + acl_len;
+
+ owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->osidoffset));
+ group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->gsidoffset));
+ dacl_ptr = (struct cifs_acl *)((char *)pntsd +
+ le32_to_cpu(pntsd->dacloffset));
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
+ "sacloffset 0x%x dacloffset 0x%x",
+ pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
+ le32_to_cpu(pntsd->gsidoffset),
+ le32_to_cpu(pntsd->sacloffset),
+ le32_to_cpu(pntsd->dacloffset)));
+#endif
+ rc = parse_sid(owner_sid_ptr, end_of_acl);
+ if (rc)
+ return rc;
+
+ rc = parse_sid(group_sid_ptr, end_of_acl);
+ if (rc)
+ return rc;
+
+ parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr);
+
+/* cifscred->uid = owner_sid_ptr->rid;
+ cifscred->gid = group_sid_ptr->rid;
+ memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
+ sizeof (struct cifs_sid));
+ memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
+ sizeof (struct cifs_sid)); */
+
+
+ return (0);
+}
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index 5eff35d6e56..420f8781364 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsacl.h
*
- * Copyright (c) International Business Machines Corp., 2005
+ * Copyright (c) International Business Machines Corp., 2007
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -22,17 +22,65 @@
#ifndef _CIFSACL_H
#define _CIFSACL_H
+
+#define NUM_AUTHS 6 /* number of authority fields */
+#define NUM_SUBAUTHS 5 /* number of sub authority fields */
+#define NUM_WK_SIDS 7 /* number of well known sids */
+#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
+
+#define READ_BIT 0x4
+#define WRITE_BIT 0x2
+#define EXEC_BIT 0x1
+
+#define UBITSHIFT 6
+#define GBITSHIFT 3
+
+struct cifs_ntsd {
+ __le16 revision; /* revision level */
+ __le16 type;
+ __le32 osidoffset;
+ __le32 gsidoffset;
+ __le32 sacloffset;
+ __le32 dacloffset;
+} __attribute__((packed));
+
struct cifs_sid {
__u8 revision; /* revision level */
- __u8 num_subauths;
+ __u8 num_subauth;
+ __u8 authority[6];
+ __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */
+} __attribute__((packed));
+
+struct cifs_acl {
+ __le16 revision; /* revision level */
+ __le16 size;
+ __le32 num_aces;
+} __attribute__((packed));
+
+struct cifs_ntace { /* first part of ACE which contains perms */
+ __u8 type;
+ __u8 flags;
+ __le16 size;
+ __le32 access_req;
+} __attribute__((packed));
+
+struct cifs_ace { /* last part of ACE which includes user info */
+ __u8 revision; /* revision level */
+ __u8 num_subauth;
__u8 authority[6];
- __u32 sub_auth[4];
- /* next sub_auth if any ... */
+ __le32 sub_auth[5];
} __attribute__((packed));
-/* everyone */
-/* extern const struct cifs_sid sid_everyone;*/
-/* group users */
-/* extern const struct cifs_sid sid_user;*/
+struct cifs_wksid {
+ struct cifs_sid cifssid;
+ char sidname[SIDNAMELENGTH];
+} __attribute__((packed));
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+
+extern int match_sid(struct cifs_sid *);
+extern int compare_sids(struct cifs_sid *, struct cifs_sid *);
+
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
#endif /* _CIFSACL_H */
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 36272293027..632070b4275 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -345,7 +345,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
user = kmalloc(2 + (len * 2), GFP_KERNEL);
if (user == NULL)
goto calc_exit_2;
- len = cifs_strtoUCS(user, ses->userName, len, nls_cp);
+ len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
UniStrupr(user);
hmac_md5_update((char *)user, 2*len, pctxt);
@@ -356,7 +356,8 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses,
domain = kmalloc(2 + (len * 2), GFP_KERNEL);
if (domain == NULL)
goto calc_exit_1;
- len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp);
+ len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len,
+ nls_cp);
/* the following line was removed since it didn't work well
with lower cased domain name that passed as an option.
Maybe converting the domain name earlier makes sense */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index ba8f7868cb2..a6fbea57c4b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -49,10 +49,6 @@
static struct quotactl_ops cifs_quotactl_ops;
#endif /* QUOTA */
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-extern struct export_operations cifs_export_ops;
-#endif /* EXPERIMENTAL */
-
int cifsFYI = 0;
int cifsERROR = 1;
int traceSMB = 0;
@@ -240,9 +236,9 @@ static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
cifs_sb = CIFS_SB(inode->i_sb);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
return 0;
- } else /* file mode might have been restricted at mount time
+ else /* file mode might have been restricted at mount time
on the client (above and beyond ACL on servers) for
servers which do not support setting and viewing mode bits,
so allowing client to check permissions is useful */
@@ -312,15 +308,15 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",domain=%s",
cifs_sb->tcon->ses->domainName);
}
+ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
+ !(cifs_sb->tcon->unix_ext))
+ seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
+ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
+ !(cifs_sb->tcon->unix_ext))
+ seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
}
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths");
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
- !(cifs_sb->tcon->unix_ext))
- seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
- !(cifs_sb->tcon->unix_ext))
- seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
seq_printf(s, ",rsize=%d", cifs_sb->rsize);
seq_printf(s, ",wsize=%d", cifs_sb->wsize);
}
@@ -346,7 +342,7 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
if (pTcon) {
cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
} else {
- return -EIO;
+ rc = -EIO;
}
FreeXid(xid);
@@ -716,7 +712,7 @@ static int
cifs_init_inodecache(void)
{
cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
- sizeof (struct cifsInodeInfo),
+ sizeof(struct cifsInodeInfo),
0, (SLAB_RECLAIM_ACCOUNT|
SLAB_MEM_SPREAD),
cifs_init_once);
@@ -816,8 +812,8 @@ static int
cifs_init_mids(void)
{
cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
- sizeof (struct mid_q_entry), 0,
- SLAB_HWCACHE_ALIGN, NULL);
+ sizeof(struct mid_q_entry), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
if (cifs_mid_cachep == NULL)
return -ENOMEM;
@@ -829,8 +825,8 @@ cifs_init_mids(void)
}
cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
- sizeof (struct oplock_q_entry), 0,
- SLAB_HWCACHE_ALIGN, NULL);
+ sizeof(struct oplock_q_entry), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
if (cifs_oplock_cachep == NULL) {
mempool_destroy(cifs_mid_poolp);
kmem_cache_destroy(cifs_mid_cachep);
@@ -882,7 +878,8 @@ static int cifs_oplock_thread(void *dummyarg)
the call */
/* mutex_lock(&inode->i_mutex);*/
if (S_ISREG(inode->i_mode)) {
- rc = filemap_fdatawrite(inode->i_mapping);
+ rc =
+ filemap_fdatawrite(inode->i_mapping);
if (CIFS_I(inode)->clientCanCacheRead
== 0) {
filemap_fdatawait(inode->i_mapping);
@@ -907,8 +904,7 @@ static int cifs_oplock_thread(void *dummyarg)
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
- cFYI(1,
- ("Oplock release rc = %d ", rc));
+ cFYI(1, ("Oplock release rc = %d", rc));
}
} else
spin_unlock(&GlobalMid_Lock);
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a20de77a385..5574ba3ab1f 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsfs.h
*
- * Copyright (c) International Business Machines Corp., 2002, 2005
+ * Copyright (c) International Business Machines Corp., 2002, 2007
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -99,7 +99,12 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *,
size_t, int);
extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-extern int cifs_ioctl (struct inode *inode, struct file *filep,
+extern int cifs_ioctl(struct inode *inode, struct file *filep,
unsigned int command, unsigned long arg);
-#define CIFS_VERSION "1.50"
+
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+extern const struct export_operations cifs_export_ops;
+#endif /* EXPERIMENTAL */
+
+#define CIFS_VERSION "1.51"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index b98742fc3b5..87f51f23276 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -19,6 +19,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include "cifs_fs_sb.h"
+#include "cifsacl.h"
/*
* The sizes of various internal tables and strings
*/
@@ -89,7 +90,8 @@ enum statusEnum {
};
enum securityEnum {
- LANMAN = 0, /* Legacy LANMAN auth */
+ PLAINTXT = 0, /* Legacy with Plaintext passwords */
+ LANMAN, /* Legacy LANMAN auth */
NTLM, /* Legacy NTLM012 auth with NTLM hash */
NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
RawNTLMSSP, /* NTLMSSP without SPNEGO */
@@ -115,6 +117,17 @@ struct mac_key {
} data;
};
+struct cifs_cred {
+ int uid;
+ int gid;
+ int mode;
+ int cecount;
+ struct cifs_sid osid;
+ struct cifs_sid gsid;
+ struct cifs_ntace *ntaces;
+ struct cifs_ace *aces;
+};
+
/*
*****************************************************************
* Except the CIFS PDUs themselves all the
@@ -279,6 +292,7 @@ struct cifsTconInfo {
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
+ unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
unsigned retry:1;
unsigned nocase:1;
unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol
@@ -329,6 +343,7 @@ struct cifsFileInfo {
struct list_head llist; /* list of byte range locks we have. */
unsigned closePend:1; /* file is marked to close */
unsigned invalidHandle:1; /* file closed via session abend */
+ unsigned messageMode:1; /* for pipes: message vs byte mode */
atomic_t wrtPending; /* handle in use - defer close */
struct semaphore fh_sem; /* prevents reopen race after dead ses*/
char *search_resume_name; /* BB removeme BB */
@@ -464,6 +479,9 @@ struct dir_notify_req {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MAY_LANMAN 0x00010
#define CIFSSEC_MAY_PLNTXT 0x00020
+#else
+#define CIFSSEC_MAY_LANMAN 0
+#define CIFSSEC_MAY_PLNTXT 0
#endif /* weak passwords */
#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
@@ -477,14 +495,23 @@ require use of the stronger protocol */
#ifdef CONFIG_CIFS_WEAK_PW_HASH
#define CIFSSEC_MUST_LANMAN 0x10010
#define CIFSSEC_MUST_PLNTXT 0x20020
+#ifdef CONFIG_CIFS_UPCALL
+#define CIFSSEC_MASK 0x3F03F /* allows weak security but also krb5 */
+#else
#define CIFSSEC_MASK 0x37037 /* current flags supported if weak */
+#endif /* UPCALL */
+#else /* do not allow weak pw hash */
+#ifdef CONFIG_CIFS_UPCALL
+#define CIFSSEC_MASK 0x0F00F /* flags supported if no weak allowed */
#else
-#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */
+#define CIFSSEC_MASK 0x07007 /* flags supported if no weak allowed */
+#endif /* UPCALL */
#endif /* WEAK_PW_HASH */
#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
#define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2
#define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2
+#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5)
/*
*****************************************************************
* All constants go here
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 6a2056e58ce..c41ff74e912 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -215,6 +215,12 @@
/* file_execute, file_read_attributes*/
/* write_dac, and delete. */
+#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
+#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+ | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
+
+
/*
* Invalid readdir handle
*/
@@ -360,10 +366,10 @@ struct smb_hdr {
__u8 WordCount;
} __attribute__((packed));
/* given a pointer to an smb_hdr retrieve the value of byte count */
-#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
-#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
+#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
+#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount)))
/* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
+#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2)
/*
* Computer Name Length (since Netbios name was length 16 with last byte 0x20)
@@ -716,6 +722,14 @@ typedef struct smb_com_findclose_req {
#define REQ_OPENDIRONLY 0x00000008
#define REQ_EXTENDED_INFO 0x00000010
+/* File type */
+#define DISK_TYPE 0x0000
+#define BYTE_PIPE_TYPE 0x0001
+#define MESSAGE_PIPE_TYPE 0x0002
+#define PRINTER_TYPE 0x0003
+#define COMM_DEV_TYPE 0x0004
+#define UNKNOWN_TYPE 0xFFFF
+
typedef struct smb_com_open_req { /* also handles create */
struct smb_hdr hdr; /* wct = 24 */
__u8 AndXCommand;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 04a69dafedb..1a883663b22 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -50,7 +50,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
int * /* bytes returned */ , const int long_op);
extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
struct kvec *, int /* nvec to send */,
- int * /* type of buf returned */ , const int long_op);
+ int * /* type of buf returned */ , const int long_op,
+ const int logError /* whether to log status code*/ );
extern int SendReceiveBlockingLock(const unsigned int /* xid */ ,
struct cifsTconInfo *,
struct smb_hdr * /* input */ ,
@@ -65,7 +66,7 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
enum securityEnum *secType);
extern int cifs_inet_pton(int, char *source, void *dst);
-extern int map_smb_to_linux_error(struct smb_hdr *smb);
+extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifsTconInfo *, int /* length of
fixed section (word count) in two byte units */);
@@ -304,12 +305,13 @@ extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn,
const char *pass);
extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *,
const struct nls_table *);
-extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * );
+extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
const struct nls_table *);
#ifdef CONFIG_CIFS_WEAK_PW_HASH
extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
#endif /* CIFS_WEAK_PW_HASH */
+extern int parse_sec_desc(struct cifs_ntsd *, int);
extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *source_tcon,
const char *fromName,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 8eb102f940d..f0d9a485d09 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -34,10 +34,10 @@
#include <asm/uaccess.h>
#include "cifspdu.h"
#include "cifsglob.h"
+#include "cifsacl.h"
#include "cifsproto.h"
#include "cifs_unicode.h"
#include "cifs_debug.h"
-#include "cifsacl.h"
#ifdef CONFIG_CIFS_POSIX
static struct {
@@ -94,9 +94,8 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
write_lock(&GlobalSMBSeslock);
list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
open_file = list_entry(tmp, struct cifsFileInfo, tlist);
- if (open_file) {
+ if (open_file)
open_file->invalidHandle = TRUE;
- }
}
write_unlock(&GlobalSMBSeslock);
/* BB Add call to invalidate_inodes(sb) for all superblocks mounted
@@ -439,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
pSMB->hdr.Mid = GetNextMid(server);
pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
+
if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
+ cFYI(1, ("Kerberos only mechanism, enable extended security"));
+ pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
+ }
count = 0;
for (i = 0; i < CIFS_NUM_PROT; i++) {
@@ -513,7 +517,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
(int)ts.tv_sec, (int)utc.tv_sec,
(int)(utc.tv_sec - ts.tv_sec)));
val = (int)(utc.tv_sec - ts.tv_sec);
- seconds = val < 0 ? -val : val;
+ seconds = abs(val);
result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
remain = seconds % MIN_TZ_ADJ;
if (remain >= (MIN_TZ_ADJ / 2))
@@ -574,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->secType = NTLM;
else if (secFlags & CIFSSEC_MAY_NTLMV2)
server->secType = NTLMv2;
- /* else krb5 ... any others ... */
+ else if (secFlags & CIFSSEC_MAY_KRB5)
+ server->secType = Kerberos;
+ else if (secFlags & CIFSSEC_MAY_LANMAN)
+ server->secType = LANMAN;
+/* #ifdef CONFIG_CIFS_EXPERIMENTAL
+ else if (secFlags & CIFSSEC_MAY_PLNTXT)
+ server->secType = ??
+#endif */
+ else {
+ rc = -EOPNOTSUPP;
+ cERROR(1, ("Invalid security type"));
+ goto neg_err_exit;
+ }
+ /* else ... any others ...? */
/* one byte, so no need to convert this or EncryptionKeyLen from
little endian */
@@ -604,22 +621,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
(server->capabilities & CAP_EXTENDED_SECURITY)) {
count = pSMBr->ByteCount;
- if (count < 16)
+ if (count < 16) {
rc = -EIO;
- else if (count == 16) {
- server->secType = RawNTLMSSP;
- if (server->socketUseCount.counter > 1) {
- if (memcmp(server->server_GUID,
- pSMBr->u.extended_response.
- GUID, 16) != 0) {
- cFYI(1, ("server UID changed"));
- memcpy(server->server_GUID,
- pSMBr->u.extended_response.GUID,
- 16);
- }
- } else
+ goto neg_err_exit;
+ }
+
+ if (server->socketUseCount.counter > 1) {
+ if (memcmp(server->server_GUID,
+ pSMBr->u.extended_response.
+ GUID, 16) != 0) {
+ cFYI(1, ("server UID changed"));
memcpy(server->server_GUID,
- pSMBr->u.extended_response.GUID, 16);
+ pSMBr->u.extended_response.GUID,
+ 16);
+ }
+ } else
+ memcpy(server->server_GUID,
+ pSMBr->u.extended_response.GUID, 16);
+
+ if (count == 16) {
+ server->secType = RawNTLMSSP;
} else {
rc = decode_negTokenInit(pSMBr->u.extended_response.
SecurityBlob,
@@ -642,10 +663,12 @@ signing_check:
/* MUST_SIGN already includes the MAY_SIGN FLAG
so if this is zero it means that signing is disabled */
cFYI(1, ("Signing disabled"));
- if (server->secMode & SECMODE_SIGN_REQUIRED)
+ if (server->secMode & SECMODE_SIGN_REQUIRED) {
cERROR(1, ("Server requires "
- "/proc/fs/cifs/PacketSigningEnabled "
- "to be on"));
+ "packet signing to be enabled in "
+ "/proc/fs/cifs/SecurityFlags."));
+ rc = -EOPNOTSUPP;
+ }
server->secMode &=
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
@@ -1052,7 +1075,7 @@ PsxCreat:
InformationLevel) - 4;
offset = param_offset + params;
pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
- pdata->Level = SMB_QUERY_FILE_UNIX_BASIC;
+ pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
pdata->Permissions = cpu_to_le64(mode);
pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
pdata->OpenFlags = cpu_to_le32(*pOplock);
@@ -1098,8 +1121,8 @@ PsxCreat:
if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
*pOplock |= CIFS_CREATE_ACTION;
/* check to make sure response data is there */
- if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) {
- pRetData->Type = -1; /* unknown */
+ if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
+ pRetData->Type = cpu_to_le32(-1); /* unknown */
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("unknown type"));
#endif
@@ -1107,12 +1130,12 @@ PsxCreat:
if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP)
+ sizeof(FILE_UNIX_BASIC_INFO)) {
cERROR(1, ("Open response data too small"));
- pRetData->Type = -1;
+ pRetData->Type = cpu_to_le32(-1);
goto psx_create_err;
}
memcpy((char *) pRetData,
(char *)psx_rsp + sizeof(OPEN_PSX_RSP),
- sizeof (FILE_UNIX_BASIC_INFO));
+ sizeof(FILE_UNIX_BASIC_INFO));
}
psx_create_err:
@@ -1193,9 +1216,9 @@ OldOpenRetry:
}
if (*pOplock & REQ_OPLOCK)
pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
- else if (*pOplock & REQ_BATCHOPLOCK) {
+ else if (*pOplock & REQ_BATCHOPLOCK)
pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
- }
+
pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
/* BB fixme add conversion for access_flags to bits 0 - 2 of mode */
/* 0 = read
@@ -1310,9 +1333,8 @@ openRetry:
}
if (*pOplock & REQ_OPLOCK)
pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
- else if (*pOplock & REQ_BATCHOPLOCK) {
+ else if (*pOplock & REQ_BATCHOPLOCK)
pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
- }
pSMB->DesiredAccess = cpu_to_le32(access_flags);
pSMB->AllocationSize = 0;
/* set file as system file if special file such
@@ -1424,9 +1446,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
iov[0].iov_base = (char *)pSMB;
iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
- rc = SendReceive2(xid, tcon->ses, iov,
- 1 /* num iovecs */,
- &resp_buf_type, 0);
+ rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
+ &resp_buf_type, 0 /* not long op */, 1 /* log err */ );
cifs_stats_inc(&tcon->num_reads);
pSMBr = (READ_RSP *)iov[0].iov_base;
if (rc) {
@@ -1446,11 +1467,11 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
*nbytes = 0;
} else {
pReadData = (char *) (&pSMBr->hdr.Protocol) +
- le16_to_cpu(pSMBr->DataOffset);
-/* if (rc = copy_to_user(buf, pReadData, data_length)) {
+ le16_to_cpu(pSMBr->DataOffset);
+/* if (rc = copy_to_user(buf, pReadData, data_length)) {
cERROR(1,("Faulting on read rc = %d",rc));
rc = -EFAULT;
- }*/ /* can not use copy_to_user when using page cache*/
+ }*/ /* can not use copy_to_user when using page cache*/
if (*buf)
memcpy(*buf, pReadData, data_length);
}
@@ -1645,7 +1666,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
- long_op);
+ long_op, 0 /* do not log STATUS code */ );
cifs_stats_inc(&tcon->num_writes);
if (rc) {
cFYI(1, ("Send error Write2 = %d", rc));
@@ -2538,7 +2559,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
cFYI(1, ("data starts after end of smb"));
return -EINVAL;
} else if (data_count + *ppdata > end_of_smb) {
- cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p",
+ cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p",
*ppdata, data_count, (data_count + *ppdata),
end_of_smb, pSMBr));
return -EINVAL;
@@ -2615,7 +2636,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
reparse_buf->TargetNameOffset +
reparse_buf->TargetNameLen) >
end_of_smb) {
- cFYI(1,("reparse buf goes beyond SMB"));
+ cFYI(1, ("reparse buf beyond SMB"));
rc = -EIO;
goto qreparse_out;
}
@@ -3042,25 +3063,12 @@ GetExtAttrOut:
#endif /* CONFIG_POSIX */
-
-/* security id for everyone */
-static const struct cifs_sid sid_everyone =
- {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
-/* group users */
-static const struct cifs_sid sid_user =
- {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
-
-/* Convert CIFS ACL to POSIX form */
-static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
-{
- return 0;
-}
-
+#ifdef CONFIG_CIFS_EXPERIMENTAL
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
/* BB fix up return info */ char *acl_inf, const int buflen,
- const int acl_type /* ACCESS/DEFAULT not sure implication */)
+ const int acl_type)
{
int rc = 0;
int buf_type = 0;
@@ -3085,12 +3093,13 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
iov[0].iov_base = (char *)pSMB;
iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
- rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0);
+ rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
+ 0 /* not long op */, 0 /* do not log STATUS codes */ );
cifs_stats_inc(&tcon->num_acl_get);
if (rc) {
cFYI(1, ("Send error in QuerySecDesc = %d", rc));
} else { /* decode response */
- struct cifs_sid *psec_desc;
+ struct cifs_ntsd *psec_desc;
__le32 * parm;
int parm_len;
int data_len;
@@ -3105,8 +3114,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
goto qsec_out;
pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
- cERROR(1, ("smb %p parm %p data %p",
- pSMBr, parm, psec_desc)); /* BB removeme BB */
+ cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc));
if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
rc = -EIO; /* bad smb */
@@ -3115,7 +3123,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
/* BB check that data area is minimum length and as big as acl_len */
- acl_len = le32_to_cpu(*(__le32 *)parm);
+ acl_len = le32_to_cpu(*parm);
/* BB check if (acl_len > bufsize) */
parse_sec_desc(psec_desc, acl_len);
@@ -3128,6 +3136,7 @@ qsec_out:
/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
return rc;
}
+#endif /* CONFIG_CIFS_EXPERIMENTAL */
/* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */
@@ -3363,6 +3372,9 @@ UnixQPathInfoRetry:
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) {
+ cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n"
+ "Unix Extensions can be disabled on mount "
+ "by specifying the nosfu mount option."));
rc = -EIO; /* bad smb */
} else {
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3883,12 +3895,10 @@ getDFSRetry:
pSMB->hdr.Mid = GetNextMid(ses->server);
pSMB->hdr.Tid = ses->ipc_tid;
pSMB->hdr.Uid = ses->Suid;
- if (ses->capabilities & CAP_STATUS32) {
+ if (ses->capabilities & CAP_STATUS32)
pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
- }
- if (ses->capabilities & CAP_DFS) {
+ if (ses->capabilities & CAP_DFS)
pSMB->hdr.Flags2 |= SMBFLG2_DFS;
- }
if (ses->capabilities & CAP_UNICODE) {
pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
@@ -4060,10 +4070,6 @@ oldQFSInfoRetry:
(void **) &pSMBr);
if (rc)
return rc;
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
params = 2; /* level */
pSMB->TotalDataCount = 0;
@@ -4265,7 +4271,7 @@ QFSAttributeRetry:
*) (((char *) &pSMBr->hdr.Protocol) +
data_offset);
memcpy(&tcon->fsAttrInfo, response_data,
- sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
+ sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
}
}
cifs_buf_release(pSMB);
@@ -4334,7 +4340,7 @@ QFSDeviceRetry:
(((char *) &pSMBr->hdr.Protocol) +
data_offset);
memcpy(&tcon->fsDevInfo, response_data,
- sizeof (FILE_SYSTEM_DEVICE_INFO));
+ sizeof(FILE_SYSTEM_DEVICE_INFO));
}
}
cifs_buf_release(pSMB);
@@ -4402,7 +4408,7 @@ QFSUnixRetry:
*) (((char *) &pSMBr->hdr.Protocol) +
data_offset);
memcpy(&tcon->fsUnixInfo, response_data,
- sizeof (FILE_SYSTEM_UNIX_INFO));
+ sizeof(FILE_SYSTEM_UNIX_INFO));
}
}
cifs_buf_release(pSMB);
@@ -4612,7 +4618,7 @@ SetEOFRetry:
strncpy(pSMB->FileName, fileName, name_len);
}
params = 6 + name_len;
- data_count = sizeof (struct file_end_of_file_info);
+ data_count = sizeof(struct file_end_of_file_info);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(4100);
pSMB->MaxSetupCount = 0;
@@ -4800,7 +4806,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon,
data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
- count = sizeof (FILE_BASIC_INFO);
+ count = sizeof(FILE_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
pSMB->SetupCount = 1;
@@ -4871,7 +4877,7 @@ SetTimesRetry:
}
params = 6 + name_len;
- count = sizeof (FILE_BASIC_INFO);
+ count = sizeof(FILE_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
pSMB->MaxSetupCount = 0;
@@ -4900,7 +4906,7 @@ SetTimesRetry:
pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += byte_count;
- memcpy(data_offset, data, sizeof (FILE_BASIC_INFO));
+ memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
@@ -5003,7 +5009,7 @@ setPermsRetry:
}
params = 6 + name_len;
- count = sizeof (FILE_UNIX_BASIC_INFO);
+ count = sizeof(FILE_UNIX_BASIC_INFO);
pSMB->MaxParameterCount = cpu_to_le16(2);
pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
pSMB->MaxSetupCount = 0;
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4af3588c1a9..19ee11f7f35 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -124,7 +124,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
struct mid_q_entry *mid_entry;
spin_lock(&GlobalMid_Lock);
- if ( kthread_should_stop() ) {
+ if (kthread_should_stop()) {
/* the demux thread will exit normally
next time through the loop */
spin_unlock(&GlobalMid_Lock);
@@ -151,9 +151,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
}
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
- if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
+ if ((tcon) && (tcon->ses) && (tcon->ses->server == server))
tcon->tidStatus = CifsNeedReconnect;
- }
}
read_unlock(&GlobalSMBSeslock);
/* do not want to be sending data on a socket we are freeing */
@@ -187,7 +186,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
spin_unlock(&GlobalMid_Lock);
up(&server->tcpSem);
- while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
+ while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
try_to_freeze();
if (server->protocolType == IPV6) {
rc = ipv6_connect(&server->addr.sockAddr6,
@@ -204,7 +203,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
atomic_inc(&tcpSesReconnectCount);
spin_lock(&GlobalMid_Lock);
- if ( !kthread_should_stop() )
+ if (!kthread_should_stop())
server->tcpStatus = CifsGood;
server->sequence_number = 0;
spin_unlock(&GlobalMid_Lock);
@@ -352,17 +351,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
current->flags |= PF_MEMALLOC;
server->tsk = current; /* save process info to wake at shutdown */
- cFYI(1, ("Demultiplex PID: %d", current->pid));
+ cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
write_lock(&GlobalSMBSeslock);
atomic_inc(&tcpSesAllocCount);
length = tcpSesAllocCount.counter;
write_unlock(&GlobalSMBSeslock);
complete(&cifsd_complete);
- if (length > 1) {
- mempool_resize(cifs_req_poolp,
- length + cifs_min_rcv,
- GFP_KERNEL);
- }
+ if (length > 1)
+ mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+ GFP_KERNEL);
set_freezable();
while (!kthread_should_stop()) {
@@ -378,7 +375,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
} else if (isLargeBuf) {
/* we are reusing a dirty large buf, clear its start */
- memset(bigbuf, 0, sizeof (struct smb_hdr));
+ memset(bigbuf, 0, sizeof(struct smb_hdr));
}
if (smallbuf == NULL) {
@@ -391,7 +388,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
}
/* beginning of smb buffer is cleared in our buf_get */
} else /* if existing small buf clear beginning */
- memset(smallbuf, 0, sizeof (struct smb_hdr));
+ memset(smallbuf, 0, sizeof(struct smb_hdr));
isLargeBuf = FALSE;
isMultiRsp = FALSE;
@@ -400,11 +397,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
iov.iov_len = 4;
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
+ pdu_length = 4; /* enough to get RFC1001 header */
+incomplete_rcv:
length =
kernel_recvmsg(csocket, &smb_msg,
- &iov, 1, 4, 0 /* BB see socket.h flags */);
+ &iov, 1, pdu_length, 0 /* BB other flags? */);
- if ( kthread_should_stop() ) {
+ if (kthread_should_stop()) {
break;
} else if (server->tcpStatus == CifsNeedReconnect) {
cFYI(1, ("Reconnect after server stopped responding"));
@@ -416,7 +415,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
msleep(1); /* minimum sleep to prevent looping
allowing socket to clear and app threads to set
tcpStatus CifsNeedReconnect if server hung */
- continue;
+ if (pdu_length < 4)
+ goto incomplete_rcv;
+ else
+ continue;
} else if (length <= 0) {
if (server->tcpStatus == CifsNew) {
cFYI(1, ("tcp session abend after SMBnegprot"));
@@ -437,13 +439,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
wake_up(&server->response_q);
continue;
} else if (length < 4) {
- cFYI(1,
- ("Frame under four bytes received (%d bytes long)",
+ cFYI(1, ("less than four bytes received (%d bytes)",
length));
- cifs_reconnect(server);
- csocket = server->ssocket;
- wake_up(&server->response_q);
- continue;
+ pdu_length -= length;
+ msleep(1);
+ goto incomplete_rcv;
}
/* The right amount was read from socket - 4 bytes */
@@ -504,7 +504,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
/* else we have an SMB response */
if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
- (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
+ (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
cERROR(1, ("Invalid size SMB length %d pdu_length %d",
length, pdu_length+4));
cifs_reconnect(server);
@@ -528,7 +528,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
total_read += length) {
length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
pdu_length - total_read, 0);
- if ( kthread_should_stop() ||
+ if (kthread_should_stop() ||
(length == -EINTR)) {
/* then will exit */
reconnect = 2;
@@ -546,6 +546,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
allowing socket to clear and app
threads to set tcpStatus
CifsNeedReconnect if server hung*/
+ length = 0;
continue;
} else if (length <= 0) {
cERROR(1, ("Received no data, expecting %d",
@@ -631,9 +632,9 @@ multi_t2_fnd:
/* Was previous buf put in mpx struct for multi-rsp? */
if (!isMultiRsp) {
/* smb buffer will be freed by user thread */
- if (isLargeBuf) {
+ if (isLargeBuf)
bigbuf = NULL;
- } else
+ else
smallbuf = NULL;
}
wake_up_process(task_to_wake);
@@ -676,9 +677,8 @@ multi_t2_fnd:
server->ssocket = NULL;
}
/* buffer usuallly freed in free_mid - need to free it here on exit */
- if (bigbuf != NULL)
- cifs_buf_release(bigbuf);
- if (smallbuf != NULL)
+ cifs_buf_release(bigbuf);
+ if (smallbuf) /* no sense logging a debug message if NULL */
cifs_small_buf_release(smallbuf);
read_lock(&GlobalSMBSeslock);
@@ -702,9 +702,8 @@ multi_t2_fnd:
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList);
- if (ses->server == server) {
+ if (ses->server == server)
ses->status = CifsExiting;
- }
}
spin_lock(&GlobalMid_Lock);
@@ -714,9 +713,8 @@ multi_t2_fnd:
cFYI(1, ("Clearing Mid 0x%x - waking up ",
mid_entry->mid));
task_to_wake = mid_entry->tsk;
- if (task_to_wake) {
+ if (task_to_wake)
wake_up_process(task_to_wake);
- }
}
}
spin_unlock(&GlobalMid_Lock);
@@ -749,18 +747,15 @@ multi_t2_fnd:
list_for_each(tmp, &GlobalSMBSessionList) {
ses = list_entry(tmp, struct cifsSesInfo,
cifsSessionList);
- if (ses->server == server) {
+ if (ses->server == server)
ses->server = NULL;
- }
}
write_unlock(&GlobalSMBSeslock);
kfree(server);
- if (length > 0) {
- mempool_resize(cifs_req_poolp,
- length + cifs_min_rcv,
- GFP_KERNEL);
- }
+ if (length > 0)
+ mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
+ GFP_KERNEL);
return 0;
}
@@ -1477,7 +1472,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
if (psin_server->sin_port) { /* user overrode default port */
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1493,7 +1488,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1502,7 +1497,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
psin_server->sin_port = htons(RFC1001_PORT);
rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
psin_server,
- sizeof (struct sockaddr_in), 0);
+ sizeof(struct sockaddr_in), 0);
if (rc >= 0)
connected = 1;
}
@@ -1610,7 +1605,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
if (psin_server->sin6_port) { /* user overrode default port */
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in6), 0);
+ sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1626,7 +1621,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server,
- sizeof (struct sockaddr_in6), 0);
+ sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1634,7 +1629,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
if (!connected) {
psin_server->sin6_port = htons(RFC1001_PORT);
rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
- psin_server, sizeof (struct sockaddr_in6), 0);
+ psin_server, sizeof(struct sockaddr_in6), 0);
if (rc >= 0)
connected = 1;
}
@@ -1750,7 +1745,16 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
cFYI(1, ("very large write cap"));
#endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
- cFYI(1, ("setting capabilities failed"));
+ if (vol_info == NULL) {
+ cFYI(1, ("resetting capabilities failed"));
+ } else
+ cERROR(1, ("Negotiating Unix capabilities "
+ "with the server failed. Consider "
+ "mounting with the Unix Extensions\n"
+ "disabled, if problems are found, "
+ "by specifying the nounix mount "
+ "option."));
+
}
}
}
@@ -1909,8 +1913,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
return rc;
}
- srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
- if (srvTcp == NULL) {
+ srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
+ if (!srvTcp) {
rc = -ENOMEM;
sock_release(csocket);
kfree(volume_info.UNC);
@@ -1919,9 +1923,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
FreeXid(xid);
return rc;
} else {
- memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
memcpy(&srvTcp->addr.sockAddr, &sin_server,
- sizeof (struct sockaddr_in));
+ sizeof(struct sockaddr_in));
atomic_set(&srvTcp->inFlight, 0);
/* BB Add code for ipv6 case too */
srvTcp->ssocket = csocket;
@@ -2173,8 +2176,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (tsk)
kthread_stop(tsk);
}
- } else
+ } else {
cFYI(1, ("No session or bad tcon"));
+ if ((pSesInfo->server) &&
+ (pSesInfo->server->tsk)) {
+ struct task_struct *tsk;
+ force_sig(SIGKILL,
+ pSesInfo->server->tsk);
+ tsk = pSesInfo->server->tsk;
+ if (tsk)
+ kthread_stop(tsk);
+ }
+ }
sesInfoFree(pSesInfo);
/* pSesInfo = NULL; */
}
@@ -2185,8 +2198,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
tcon->ses = pSesInfo;
/* do not care if following two calls succeed - informational */
- CIFSSMBQFSDeviceInfo(xid, tcon);
- CIFSSMBQFSAttributeInfo(xid, tcon);
+ if (!tcon->ipc) {
+ CIFSSMBQFSDeviceInfo(xid, tcon);
+ CIFSSMBQFSAttributeInfo(xid, tcon);
+ }
/* tell server which Unix caps we support */
if (tcon->ses->capabilities & CAP_UNIX)
@@ -2526,8 +2541,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
sesssetup_nomem: /* do not return an error on nomem for the info strings,
since that could make reconnection harder, and
reconnection might be needed to free memory */
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
@@ -2547,7 +2561,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
int remaining_words = 0;
int bytes_returned = 0;
int len;
- int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
+ int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
PNEGOTIATE_MESSAGE SecurityBlob;
PCHALLENGE_MESSAGE SecurityBlob2;
__u32 negotiate_flags, capabilities;
@@ -2865,15 +2879,14 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
rc = -EIO;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
static int
CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
- char *ntlm_session_key, int ntlmv2_flag,
- const struct nls_table *nls_codepage)
+ char *ntlm_session_key, int ntlmv2_flag,
+ const struct nls_table *nls_codepage)
{
struct smb_hdr *smb_buffer;
struct smb_hdr *smb_buffer_response;
@@ -2886,7 +2899,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
int remaining_words = 0;
int bytes_returned = 0;
int len;
- int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
+ int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
PAUTHENTICATE_MESSAGE SecurityBlob;
__u32 negotiate_flags, capabilities;
__u16 count;
@@ -2901,8 +2914,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
return -ENOMEM;
}
smb_buffer_response = smb_buffer;
- pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
- pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
+ pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
+ pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
/* send SMBsessionSetup here */
header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
@@ -2921,7 +2934,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_EXTENDED_SECURITY;
+ CAP_EXTENDED_SECURITY;
if (ses->capabilities & CAP_UNICODE) {
smb_buffer->Flags2 |= SMBFLG2_UNICODE;
capabilities |= CAP_UNICODE;
@@ -2936,15 +2949,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
}
pSMB->req.Capabilities = cpu_to_le32(capabilities);
- bcc_ptr = (char *) &pSMB->req.SecurityBlob;
- SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
+ bcc_ptr = (char *)&pSMB->req.SecurityBlob;
+ SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
SecurityBlob->MessageType = NtLmAuthenticate;
bcc_ptr += SecurityBlobLength;
- negotiate_flags =
- NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
- 0x80000000 | NTLMSSP_NEGOTIATE_128;
+ negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
+ 0x80000000 | NTLMSSP_NEGOTIATE_128;
if (sign_CIFS_PDUs)
negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
if (ntlmv2_flag)
@@ -2979,36 +2991,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- __u16 len =
- cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
+ __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
nls_codepage);
- len *= 2;
+ ln *= 2;
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->DomainName.Length =
- cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->DomainName.Length = cpu_to_le16(ln);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
- __u16 len =
- cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
+ __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
nls_codepage);
- len *= 2;
+ ln *= 2;
SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->UserName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->UserName.Length =
- cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->UserName.Length = cpu_to_le16(ln);
}
/* SecurityBlob->WorkstationName.Length =
@@ -3052,33 +3060,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->DomainName.Length = 0;
SecurityBlob->DomainName.MaximumLength = 0;
} else {
- __u16 len;
+ __u16 ln;
negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
strncpy(bcc_ptr, domain, 63);
- len = strnlen(domain, 64);
+ ln = strnlen(domain, 64);
SecurityBlob->DomainName.MaximumLength =
- cpu_to_le16(len);
+ cpu_to_le16(ln);
SecurityBlob->DomainName.Buffer =
cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->DomainName.Length = cpu_to_le16(len);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->DomainName.Length = cpu_to_le16(ln);
}
if (user == NULL) {
SecurityBlob->UserName.Buffer = 0;
SecurityBlob->UserName.Length = 0;
SecurityBlob->UserName.MaximumLength = 0;
} else {
- __u16 len;
+ __u16 ln;
strncpy(bcc_ptr, user, 63);
- len = strnlen(user, 64);
- SecurityBlob->UserName.MaximumLength =
- cpu_to_le16(len);
+ ln = strnlen(user, 64);
+ SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
SecurityBlob->UserName.Buffer =
- cpu_to_le32(SecurityBlobLength);
- bcc_ptr += len;
- SecurityBlobLength += len;
- SecurityBlob->UserName.Length = cpu_to_le16(len);
+ cpu_to_le32(SecurityBlobLength);
+ bcc_ptr += ln;
+ SecurityBlobLength += ln;
+ SecurityBlob->UserName.Length = cpu_to_le16(ln);
}
/* BB fill in our workstation name if known BB */
@@ -3100,12 +3107,11 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
&bytes_returned, 1);
if (rc) {
-/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
- } else if ((smb_buffer_response->WordCount == 3)
- || (smb_buffer_response->WordCount == 4)) {
+/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
+ } else if ((smb_buffer_response->WordCount == 3) ||
+ (smb_buffer_response->WordCount == 4)) {
__u16 action = le16_to_cpu(pSMBr->resp.Action);
- __u16 blob_len =
- le16_to_cpu(pSMBr->resp.SecurityBlobLength);
+ __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
if (action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* BB Should we set anything
in SesInfo struct ? */
@@ -3145,8 +3151,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
} else {
remaining_words = BCC(smb_buffer_response) / 2;
}
- len =
- UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
+ len = UniStrnlen((wchar_t *) bcc_ptr,
+ remaining_words - 1);
/* We look for obvious messed up bcc or strings in response so we do not go off
the end since (at least) WIN2K and Windows XP have a major bug in not null
terminating last Unicode string in response */
@@ -3230,7 +3236,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
<= BCC(smb_buffer_response)) {
if (ses->serverOS)
kfree(ses->serverOS);
- ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
+ ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
strncpy(ses->serverOS,bcc_ptr, len);
bcc_ptr += len;
@@ -3259,28 +3265,24 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr[0] = 0;
bcc_ptr++;
} else
- cFYI(1,
- ("field of length %d "
+ cFYI(1, ("field of length %d "
"extends beyond end of smb ",
len));
}
} else {
- cERROR(1,
- (" Security Blob extends beyond end "
+ cERROR(1, ("Security Blob extends beyond end "
"of SMB"));
}
} else {
cERROR(1, ("No session structure passed in."));
}
} else {
- cERROR(1,
- (" Invalid Word count %d: ",
+ cERROR(1, ("Invalid Word count %d: ",
smb_buffer_response->WordCount));
rc = -EIO;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
@@ -3389,6 +3391,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr = pByteArea(smb_buffer_response);
length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
/* skip service field (NB: this field is always ASCII) */
+ if (length == 3) {
+ if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
+ (bcc_ptr[2] == 'C')) {
+ cFYI(1, ("IPC connection"));
+ tcon->ipc = 1;
+ }
+ } else if (length == 2) {
+ if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
+ /* the most common case */
+ cFYI(1, ("disk share connection"));
+ }
+ }
bcc_ptr += length + 1;
strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
@@ -3399,9 +3413,11 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 2, GFP_KERNEL);
- cifs_strfromUCS_le(tcon->nativeFileSystem,
- (__le16 *) bcc_ptr,
- length, nls_codepage);
+ if (tcon->nativeFileSystem)
+ cifs_strfromUCS_le(
+ tcon->nativeFileSystem,
+ (__le16 *) bcc_ptr,
+ length, nls_codepage);
bcc_ptr += 2 * length;
bcc_ptr[0] = 0; /* null terminate the string */
bcc_ptr[1] = 0;
@@ -3416,8 +3432,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
kfree(tcon->nativeFileSystem);
tcon->nativeFileSystem =
kzalloc(length + 1, GFP_KERNEL);
- strncpy(tcon->nativeFileSystem, bcc_ptr,
- length);
+ if (tcon->nativeFileSystem)
+ strncpy(tcon->nativeFileSystem, bcc_ptr,
+ length);
}
/* else do not bother copying these information fields*/
}
@@ -3433,8 +3450,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
ses->ipc_tid = smb_buffer_response->Tid;
}
- if (smb_buffer)
- cifs_buf_release(smb_buffer);
+ cifs_buf_release(smb_buffer);
return rc;
}
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4830acc86d7..793404b1092 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -3,7 +3,7 @@
*
* vfs operations that deal with dentries
*
- * Copyright (C) International Business Machines Corp., 2002,2005
+ * Copyright (C) International Business Machines Corp., 2002,2007
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -269,7 +269,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
CIFSSMBClose(xid, pTcon, fileHandle);
} else if (newinode) {
pCifsFile =
- kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
+ kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
if (pCifsFile == NULL)
goto cifs_create_out;
@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
/* BB Do not bother to decode buf since no
local inode yet to put timestamps in,
but we can reuse it safely */
- int bytes_written;
+ unsigned int bytes_written;
struct win_dev *pdev;
pdev = (struct win_dev *)buf;
if (S_ISCHR(mode)) {
@@ -450,8 +450,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
xid = GetXid();
- cFYI(1,
- (" parent inode = 0x%p name is: %s and dentry = 0x%p",
+ cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p",
parent_dir_inode, direntry->d_name.name, direntry));
/* check whether path exists */
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 893fd0aebff..75949d6a5f1 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -43,6 +43,7 @@
#include <linux/exportfs.h>
#include "cifsglob.h"
#include "cifs_debug.h"
+#include "cifsfs.h"
#ifdef CONFIG_CIFS_EXPERIMENTAL
static struct dentry *cifs_get_parent(struct dentry *dentry)
@@ -52,7 +53,7 @@ static struct dentry *cifs_get_parent(struct dentry *dentry)
return ERR_PTR(-EACCES);
}
-struct export_operations cifs_export_ops = {
+const struct export_operations cifs_export_ops = {
.get_parent = cifs_get_parent,
/* Following five export operations are unneeded so far and can default:
.get_dentry =
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 894b1f7b299..1e7e4c06d9e 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -467,7 +467,7 @@ reopen_error_exit:
int cifs_close(struct inode *inode, struct file *file)
{
int rc = 0;
- int xid;
+ int xid, timeout;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifsFileInfo *pSMBFile =
@@ -485,9 +485,9 @@ int cifs_close(struct inode *inode, struct file *file)
/* no sense reconnecting to close a file that is
already closed */
if (pTcon->tidStatus != CifsNeedReconnect) {
- int timeout = 2;
+ timeout = 2;
while ((atomic_read(&pSMBFile->wrtPending) != 0)
- && (timeout < 1000) ) {
+ && (timeout <= 2048)) {
/* Give write a better chance to get to
server ahead of the close. We do not
want to add a wait_q here as it would
@@ -522,12 +522,30 @@ int cifs_close(struct inode *inode, struct file *file)
list_del(&pSMBFile->flist);
list_del(&pSMBFile->tlist);
write_unlock(&GlobalSMBSeslock);
+ timeout = 10;
+ /* We waited above to give the SMBWrite a chance to issue
+ on the wire (so we do not get SMBWrite returning EBADF
+ if writepages is racing with close. Note that writepages
+ does not specify a file handle, so it is possible for a file
+ to be opened twice, and the application close the "wrong"
+ file handle - in these cases we delay long enough to allow
+ the SMBWrite to get on the wire before the SMB Close.
+ We allow total wait here over 45 seconds, more than
+ oplock break time, and more than enough to allow any write
+ to complete on the server, or to time out on the client */
+ while ((atomic_read(&pSMBFile->wrtPending) != 0)
+ && (timeout <= 50000)) {
+ cERROR(1, ("writes pending, delay free of handle"));
+ msleep(timeout);
+ timeout *= 8;
+ }
kfree(pSMBFile->search_resume_name);
kfree(file->private_data);
file->private_data = NULL;
} else
rc = -EBADF;
+ read_lock(&GlobalSMBSeslock);
if (list_empty(&(CIFS_I(inode)->openFileList))) {
cFYI(1, ("closing last open instance for inode %p", inode));
/* if the file is not open we do not know if we can cache info
@@ -535,6 +553,7 @@ int cifs_close(struct inode *inode, struct file *file)
CIFS_I(inode)->clientCanCacheRead = FALSE;
CIFS_I(inode)->clientCanCacheAll = FALSE;
}
+ read_unlock(&GlobalSMBSeslock);
if ((rc == 0) && CIFS_I(inode)->write_behind_rc)
rc = CIFS_I(inode)->write_behind_rc;
FreeXid(xid);
@@ -767,7 +786,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
mutex_lock(&fid->lock_mutex);
list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
if (pfLock->fl_start <= li->offset &&
- length >= li->length) {
+ (pfLock->fl_start + length) >=
+ (li->offset + li->length)) {
stored_rc = CIFSSMBLock(xid, pTcon,
netfid,
li->length, li->offset,
@@ -1022,6 +1042,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
}
read_lock(&GlobalSMBSeslock);
+refind_writable:
list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
if (open_file->closePend)
continue;
@@ -1029,24 +1050,49 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
((open_file->pfile->f_flags & O_RDWR) ||
(open_file->pfile->f_flags & O_WRONLY))) {
atomic_inc(&open_file->wrtPending);
+
+ if (!open_file->invalidHandle) {
+ /* found a good writable file */
+ read_unlock(&GlobalSMBSeslock);
+ return open_file;
+ }
+
read_unlock(&GlobalSMBSeslock);
- if ((open_file->invalidHandle) &&
- (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) {
- rc = cifs_reopen_file(open_file->pfile, FALSE);
- /* if it fails, try another handle - might be */
- /* dangerous to hold up writepages with retry */
- if (rc) {
- cFYI(1,
- ("failed on reopen file in wp"));
+ /* Had to unlock since following call can block */
+ rc = cifs_reopen_file(open_file->pfile, FALSE);
+ if (!rc) {
+ if (!open_file->closePend)
+ return open_file;
+ else { /* start over in case this was deleted */
+ /* since the list could be modified */
read_lock(&GlobalSMBSeslock);
- /* can not use this handle, no write
- pending on this one after all */
- atomic_dec
- (&open_file->wrtPending);
- continue;
+ atomic_dec(&open_file->wrtPending);
+ goto refind_writable;
}
}
- return open_file;
+
+ /* if it fails, try another handle if possible -
+ (we can not do this if closePending since
+ loop could be modified - in which case we
+ have to start at the beginning of the list
+ again. Note that it would be bad
+ to hold up writepages here (rather than
+ in caller) with continuous retries */
+ cFYI(1, ("wp failed on reopen file"));
+ read_lock(&GlobalSMBSeslock);
+ /* can not use this handle, no write
+ pending on this one after all */
+ atomic_dec(&open_file->wrtPending);
+
+ if (open_file->closePend) /* list could have changed */
+ goto refind_writable;
+ /* else we simply continue to the next entry. Thus
+ we do not loop on reopen errors. If we
+ can not reopen the file, for example if we
+ reconnected to a server with another client
+ racing to delete or lock the file we would not
+ make progress if we restarted before the beginning
+ of the loop here. */
}
}
read_unlock(&GlobalSMBSeslock);
@@ -1709,7 +1755,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct page *page;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
- int bytes_read = 0;
+ unsigned int bytes_read = 0;
unsigned int read_size, i;
char *smb_read_data = NULL;
struct smb_com_read_rsp *pSMBr;
@@ -1803,7 +1849,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
i += bytes_read >> PAGE_CACHE_SHIFT;
cifs_stats_bytes_read(pTcon, bytes_read);
- if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
+ if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) {
i++; /* account for partial page */
/* server copy of file can have smaller size
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 279f3c5e0ce..5e8b388be3b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
inode->i_mode = le64_to_cpu(findData.Permissions);
/* since we set the inode type below we need to mask off
to avoid strange results if bits set above */
- inode->i_mode &= ~S_IFMT;
+ inode->i_mode &= ~S_IFMT;
if (type == UNIX_FILE) {
inode->i_mode |= S_IFREG;
} else if (type == UNIX_SYMLINK) {
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode,
return rc;
}
+static const struct inode_operations cifs_ipc_inode_ops = {
+ .lookup = cifs_lookup,
+};
+
/* gets root inode */
void cifs_read_inode(struct inode *inode)
{
- int xid;
+ int xid, rc;
struct cifs_sb_info *cifs_sb;
cifs_sb = CIFS_SB(inode->i_sb);
xid = GetXid();
if (cifs_sb->tcon->unix_ext)
- cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
+ rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
else
- cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+ rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid);
+ if (rc && cifs_sb->tcon->ipc) {
+ cFYI(1, ("ipc connection - fake read inode"));
+ inode->i_mode |= S_IFDIR;
+ inode->i_nlink = 2;
+ inode->i_op = &cifs_ipc_inode_ops;
+ inode->i_fop = &simple_dir_operations;
+ inode->i_uid = cifs_sb->mnt_uid;
+ inode->i_gid = cifs_sb->mnt_gid;
+ }
+
/* can not call macro FreeXid here since in a void func */
_FreeXid(xid);
}
@@ -919,18 +933,25 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
goto mkdir_out;
}
+ mode &= ~current->fs->umask;
rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
mode, NULL /* netfid */, pInfo, &oplock,
full_path, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc) {
+ if (rc == -EOPNOTSUPP) {
+ kfree(pInfo);
+ goto mkdir_retry_old;
+ } else if (rc) {
cFYI(1, ("posix mkdir returned 0x%x", rc));
d_drop(direntry);
} else {
int obj_type;
- if (pInfo->Type == -1) /* no return info - go query */
+ if (pInfo->Type == cpu_to_le32(-1)) {
+ /* no return info, go query for it */
+ kfree(pInfo);
goto mkdir_get_info;
+ }
/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
to set uid/gid */
inc_nlink(inode);
@@ -940,8 +961,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
direntry->d_op = &cifs_dentry_ops;
newinode = new_inode(inode->i_sb);
- if (newinode == NULL)
+ if (newinode == NULL) {
+ kfree(pInfo);
goto mkdir_get_info;
+ }
/* Is an i_ino of zero legal? */
/* Are there sanity checks we can use to ensure that
the server is really filling in that field? */
@@ -972,7 +995,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
kfree(pInfo);
goto mkdir_out;
}
-
+mkdir_retry_old:
/* BB add setting the equivalent of mode via CreateX w/ACLs */
rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
@@ -1377,8 +1400,17 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset)
}
i_size_write(inode, offset);
spin_unlock(&inode->i_lock);
+ /*
+ * unmap_mapping_range is called twice, first simply for efficiency
+ * so that truncate_inode_pages does fewer single-page unmaps. However
+ * after this first call, and before truncate_inode_pages finishes,
+ * it is possible for private pages to be COWed, which remain after
+ * truncate_inode_pages finishes, hence the second unmap_mapping_range
+ * call must be made for correctness.
+ */
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
+ unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
goto out_truncate;
do_expand:
@@ -1469,7 +1501,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
atomic_dec(&open_file->wrtPending);
cFYI(1, ("SetFSize for attrs rc = %d", rc));
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
- int bytes_written;
+ unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon,
nfid, 0, attrs->ia_size,
&bytes_written, NULL, NULL,
@@ -1502,7 +1534,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
- int bytes_written;
+ unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon,
netfid, 0,
attrs->ia_size,
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 6a85ef7b879..11f265726db 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -237,7 +237,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
char *tmp_path = NULL;
char *tmpbuffer;
unsigned char *referrals = NULL;
- int num_referrals = 0;
+ unsigned int num_referrals = 0;
int len;
__u16 fid;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 0bcec0844be..51ec681fe74 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -169,7 +169,6 @@ cifs_buf_get(void)
void
cifs_buf_release(void *buf_to_free)
{
-
if (buf_to_free == NULL) {
/* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/
return;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 2bfed3f45d0..f06359cb22e 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -114,10 +114,16 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
{ERRusempx, -EIO},
{ERRusestd, -EIO},
{ERR_NOTIFY_ENUM_DIR, -ENOBUFS},
- {ERRaccountexpired, -EACCES},
+ {ERRnoSuchUser, -EACCES},
+/* {ERRaccountexpired, -EACCES},
{ERRbadclient, -EACCES},
{ERRbadLogonTime, -EACCES},
- {ERRpasswordExpired, -EACCES},
+ {ERRpasswordExpired, -EACCES},*/
+ {ERRaccountexpired, -EKEYEXPIRED},
+ {ERRbadclient, -EACCES},
+ {ERRbadLogonTime, -EACCES},
+ {ERRpasswordExpired, -EKEYEXPIRED},
+
{ERRnosupport, -EINVAL},
{0, 0}
};
@@ -270,7 +276,7 @@ static const struct {
from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
during the session setup } */
{
- ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
+ ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */
ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {
ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {
ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {
@@ -285,10 +291,10 @@ static const struct {
ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {
ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {
ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
- ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
- ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
+ ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {
+ ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {
ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
- ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {
+ ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {
ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {
@@ -585,7 +591,7 @@ static const struct {
ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
- ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {
+ ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {
ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {
@@ -754,7 +760,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
}
int
-map_smb_to_linux_error(struct smb_hdr *smb)
+map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
{
unsigned int i;
int rc = -EIO; /* if transport error smb error may not be set */
@@ -771,7 +777,9 @@ map_smb_to_linux_error(struct smb_hdr *smb)
/* translate the newer STATUS codes to old style SMB errors
* and then to POSIX errors */
__u32 err = le32_to_cpu(smb->Status.CifsError);
- if (cifsFYI & CIFS_RC)
+ if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))
+ cifs_print_status(err);
+ else if (cifsFYI & CIFS_RC)
cifs_print_status(err);
ntstatus_to_dos(err, &smberrclass, &smberrcode);
} else {
@@ -813,7 +821,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
}
/* else ERRHRD class errors or junk - return EIO */
- cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
+ cFYI(1, ("Mapping smb error code %d to POSIX err %d",
smberrcode, rc));
/* generic corrective action e.g. reconnect SMB session on
@@ -899,8 +907,11 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
cERROR(1, ("illegal hours %d", st->Hours));
days = sd->Day;
month = sd->Month;
- if ((days > 31) || (month > 12))
+ if ((days > 31) || (month > 12)) {
cERROR(1, ("illegal date, month %d day: %d", month, days));
+ if (month > 12)
+ month = 12;
+ }
month -= 1;
days += total_days_of_prev_months[month];
days += 3652; /* account for difference in days between 1980 and 1970 */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 916df943133..3746580e970 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode)
static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
- char *buf, int *pobject_type, int isNewInode)
+ char *buf, unsigned int *pobject_type, int isNewInode)
{
loff_t local_size;
struct timespec local_mtime;
@@ -294,7 +294,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type,
}
static void unix_fill_in_inode(struct inode *tmp_inode,
- FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode)
+ FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode)
{
loff_t local_size;
struct timespec local_mtime;
@@ -826,7 +826,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
int rc = 0;
struct qstr qstring;
struct cifsFileInfo *pCifsF;
- unsigned obj_type;
+ unsigned int obj_type;
ino_t inum;
struct cifs_sb_info *cifs_sb;
struct inode *tmp_inode;
@@ -1067,7 +1067,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
if (current_entry == NULL) {
/* evaluate whether this case is an error */
- cERROR(1,("past end of SMB num to fill %d i %d",
+ cERROR(1, ("past SMB end, num to fill %d i %d",
num_to_fill, i));
break;
}
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 892be9b4d1f..899dc6078d9 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -67,14 +67,59 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
capabilities |= CAP_DFS;
}
- if (ses->capabilities & CAP_UNIX) {
+ if (ses->capabilities & CAP_UNIX)
capabilities |= CAP_UNIX;
- }
/* BB check whether to init vcnum BB */
return capabilities;
}
+static void
+unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
+{
+ char *bcc_ptr = *pbcc_area;
+ int bytes_ret = 0;
+
+ /* Copy OS version */
+ bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
+ nls_cp);
+ bcc_ptr += 2 * bytes_ret;
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
+ 32, nls_cp);
+ bcc_ptr += 2 * bytes_ret;
+ bcc_ptr += 2; /* trailing null */
+
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
+ 32, nls_cp);
+ bcc_ptr += 2 * bytes_ret;
+ bcc_ptr += 2; /* trailing null */
+
+ *pbcc_area = bcc_ptr;
+}
+
+static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
+ const struct nls_table *nls_cp)
+{
+ char *bcc_ptr = *pbcc_area;
+ int bytes_ret = 0;
+
+ /* copy domain */
+ if (ses->domainName == NULL) {
+ /* Sending null domain better than using a bogus domain name (as
+ we did briefly in 2.6.18) since server will use its default */
+ *bcc_ptr = 0;
+ *(bcc_ptr+1) = 0;
+ bytes_ret = 0;
+ } else
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
+ 256, nls_cp);
+ bcc_ptr += 2 * bytes_ret;
+ bcc_ptr += 2; /* account for null terminator */
+
+ *pbcc_area = bcc_ptr;
+}
+
+
static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
const struct nls_table *nls_cp)
{
@@ -100,32 +145,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
}
bcc_ptr += 2 * bytes_ret;
bcc_ptr += 2; /* account for null termination */
- /* copy domain */
- if (ses->domainName == NULL) {
- /* Sending null domain better than using a bogus domain name (as
- we did briefly in 2.6.18) since server will use its default */
- *bcc_ptr = 0;
- *(bcc_ptr+1) = 0;
- bytes_ret = 0;
- } else
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
- 256, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* account for null terminator */
-
- /* Copy OS version */
- bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
- nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
- 32, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* trailing null */
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 32, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* trailing null */
+ unicode_domain_string(&bcc_ptr, ses, nls_cp);
+ unicode_oslm_strings(&bcc_ptr, nls_cp);
*pbcc_area = bcc_ptr;
}
@@ -203,14 +225,11 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
if (len >= words_left)
return rc;
- if (ses->serverOS)
- kfree(ses->serverOS);
+ kfree(ses->serverOS);
/* UTF-8 string will not grow more than four times as big as UCS-16 */
ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
- if (ses->serverOS != NULL) {
- cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
- nls_cp);
- }
+ if (ses->serverOS != NULL)
+ cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
data += 2 * (len + 1);
words_left -= len + 1;
@@ -220,8 +239,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
if (len >= words_left)
return rc;
- if (ses->serverNOS)
- kfree(ses->serverNOS);
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
if (ses->serverNOS != NULL) {
cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
@@ -240,8 +258,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft,
if (len > words_left)
return rc;
- if (ses->serverDomain)
- kfree(ses->serverDomain);
+ kfree(ses->serverDomain);
ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
if (ses->serverDomain != NULL) {
cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
@@ -271,8 +288,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
if (len >= bleft)
return rc;
- if (ses->serverOS)
- kfree(ses->serverOS);
+ kfree(ses->serverOS);
ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
if (ses->serverOS)
@@ -289,8 +305,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft,
if (len >= bleft)
return rc;
- if (ses->serverNOS)
- kfree(ses->serverNOS);
+ kfree(ses->serverNOS);
ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
if (ses->serverNOS)
@@ -479,7 +494,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
if (ses->capabilities & CAP_UNICODE) {
if (iov[0].iov_len % 2) {
*bcc_ptr = 0;
- } bcc_ptr++;
+ bcc_ptr++;
+ }
unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
} else
ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
@@ -497,7 +513,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
iov[1].iov_base = str_area;
iov[1].iov_len = count;
- rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
+ rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
+ 0 /* not long op */, 1 /* log NT STATUS if any */ );
/* SMB request buf freed in SendReceive2 */
cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index 2ef0be28882..7f50e8577c1 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -173,9 +173,10 @@
#define ERRusestd 251 /* temporarily unable to use either raw
or mpx */
#define ERR_NOTIFY_ENUM_DIR 1024
+#define ERRnoSuchUser 2238 /* user account does not exist */
#define ERRaccountexpired 2239
-#define ERRbadclient 2240
-#define ERRbadLogonTime 2241
+#define ERRbadclient 2240 /* can not logon from this client */
+#define ERRbadLogonTime 2241 /* logon hours do not allow this */
#define ERRpasswordExpired 2242
#define ERRnetlogonNotStarted 2455
#define ERRnosupport 0xFFFF
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 746bc9405db..7ed32b3cb78 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -55,7 +55,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
if (temp == NULL)
return temp;
else {
- memset(temp, 0, sizeof (struct mid_q_entry));
+ memset(temp, 0, sizeof(struct mid_q_entry));
temp->mid = smb_buffer->Mid; /* always LE */
temp->pid = current->pid;
temp->command = smb_buffer->Command;
@@ -158,7 +158,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
iov.iov_len = len;
smb_msg.msg_name = sin;
- smb_msg.msg_namelen = sizeof (struct sockaddr);
+ smb_msg.msg_namelen = sizeof(struct sockaddr);
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -228,7 +228,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec,
return -ENOTSOCK; /* BB eventually add reconnect code here */
smb_msg.msg_name = sin;
- smb_msg.msg_namelen = sizeof (struct sockaddr);
+ smb_msg.msg_namelen = sizeof(struct sockaddr);
smb_msg.msg_control = NULL;
smb_msg.msg_controllen = 0;
smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
@@ -363,9 +363,8 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
} /* else ok - we are setting up session */
}
*ppmidQ = AllocMidQEntry(in_buf, ses);
- if (*ppmidQ == NULL) {
+ if (*ppmidQ == NULL)
return -ENOMEM;
- }
return 0;
}
@@ -419,7 +418,7 @@ static int wait_for_response(struct cifsSesInfo *ses,
int
SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
- const int long_op)
+ const int long_op, const int logError)
{
int rc = 0;
unsigned int receive_len;
@@ -465,7 +464,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
wake_up(&ses->server->request_q);
return rc;
}
-
rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
midQ->midState = MID_REQUEST_SUBMITTED;
@@ -568,13 +566,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
}
/* BB special case reconnect tid and uid here? */
- /* BB special case Errbadpassword and pwdexpired here */
- rc = map_smb_to_linux_error(midQ->resp_buf);
+ rc = map_smb_to_linux_error(midQ->resp_buf, logError);
/* convert ByteCount if necessary */
- if (receive_len >=
- sizeof (struct smb_hdr) -
- 4 /* do not count RFC1001 header */ +
+ if (receive_len >= sizeof(struct smb_hdr) - 4
+ /* do not count RFC1001 header */ +
(2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
BCC(midQ->resp_buf) =
le16_to_cpu(BCC_LE(midQ->resp_buf));
@@ -749,12 +745,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
*pbytes_returned = out_buf->smb_buf_length;
/* BB special case reconnect tid and uid here? */
- rc = map_smb_to_linux_error(out_buf);
+ rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
/* convert ByteCount if necessary */
- if (receive_len >=
- sizeof (struct smb_hdr) -
- 4 /* do not count RFC1001 header */ +
+ if (receive_len >= sizeof(struct smb_hdr) - 4
+ /* do not count RFC1001 header */ +
(2 * out_buf->WordCount) + 2 /* bcc */ )
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
} else {
@@ -993,12 +988,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
*pbytes_returned = out_buf->smb_buf_length;
/* BB special case reconnect tid and uid here? */
- rc = map_smb_to_linux_error(out_buf);
+ rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
/* convert ByteCount if necessary */
- if (receive_len >=
- sizeof (struct smb_hdr) -
- 4 /* do not count RFC1001 header */ +
+ if (receive_len >= sizeof(struct smb_hdr) - 4
+ /* do not count RFC1001 header */ +
(2 * out_buf->WordCount) + 2 /* bcc */ )
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
} else {
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index f61e433d281..369e838bebd 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -261,21 +261,26 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
-/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
+#ifdef CONFIG_CIFS_EXPERIMENTAL
+ else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
__u16 fid;
int oplock = FALSE;
- rc = CIFSSMBOpen(xid, pTcon, full_path,
- FILE_OPEN, GENERIC_READ, 0, &fid,
- &oplock, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (experimEnabled)
+ rc = CIFSSMBOpen(xid, pTcon, full_path,
+ FILE_OPEN, GENERIC_READ, 0, &fid,
+ &oplock, NULL, cifs_sb->local_nls,
+ cifs_sb->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ /* else rc is EOPNOTSUPP from above */
+
if(rc == 0) {
rc = CIFSSMBGetCIFSACL(xid, pTcon, fid,
ea_value, buf_size,
ACL_TYPE_ACCESS);
CIFSSMBClose(xid, pTcon, fid);
}
- } */ /* BB enable after fixing up return data */
+ }
+#endif /* EXPERIMENTAL */
#else
cFYI(1, ("query POSIX ACL not supported yet"));
#endif /* CONFIG_CIFS_POSIX */
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index cdb4c07a787..359e531094d 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -51,7 +51,7 @@ static void *alloc_upcall(int opcode, int size)
inp->ih.opcode = opcode;
inp->ih.pid = current->pid;
- inp->ih.pgid = process_group(current);
+ inp->ih.pgid = task_pgrp_nr(current);
#ifdef CONFIG_CODA_FS_OLD_API
memset(&inp->ih.cred, 0, sizeof(struct coda_cred));
inp->ih.cred.cr_fsuid = current->fsuid;
diff --git a/fs/dcache.c b/fs/dcache.c
index 5489b2d98a0..d9ca1e5ceb9 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
__cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
-static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
+__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
EXPORT_SYMBOL(dcache_lock);
@@ -1479,6 +1479,8 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
* dentry:internal, target:external. Steal target's
* storage and make target internal.
*/
+ memcpy(target->d_iname, dentry->d_name.name,
+ dentry->d_name.len + 1);
dentry->d_name.name = target->d_name.name;
target->d_name.name = target->d_iname;
}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 11be8a325e2..6a713b33992 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
d_move(old_dentry, dentry);
fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
- NULL, old_dentry->d_inode);
+ NULL, old_dentry);
fsnotify_oldname_free(old_name);
unlock_rename(new_dir, old_dir);
dput(dentry);
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 6438941ab1f..4f741546f4b 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -456,7 +456,7 @@ static int check_version(struct dlm_write_request *req)
printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
"user (%d.%d.%d) kernel (%d.%d.%d)\n",
current->comm,
- current->pid,
+ task_pid_nr(current),
req->version[0],
req->version[1],
req->version[2],
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef2c74..0a9882edf56 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
pg = virt_to_page(addr);
offset = offset_in_page(addr);
if (sg) {
- sg[i].page = pg;
+ sg_set_page(&sg[i], pg);
sg[i].offset = offset;
}
remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
{
struct scatterlist src_sg, dst_sg;
- src_sg.page = src_page;
+ sg_init_table(&src_sg, 1);
+ sg_init_table(&dst_sg, 1);
+
+ sg_set_page(&src_sg, src_page);
src_sg.offset = src_offset;
src_sg.length = size;
- dst_sg.page = dst_page;
+ sg_set_page(&dst_sg, dst_page);
dst_sg.offset = dst_offset;
dst_sg.length = size;
return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
{
struct scatterlist src_sg, dst_sg;
- src_sg.page = src_page;
+ sg_init_table(&src_sg, 1);
+ sg_init_table(&dst_sg, 1);
+
+ sg_set_page(&src_sg, src_page);
src_sg.offset = src_offset;
src_sg.length = size;
- dst_sg.page = dst_page;
+ sg_set_page(&dst_sg, dst_page);
dst_sg.offset = dst_offset;
dst_sg.length = size;
return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710dd63..263fed88c0c 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
};
int rc = 0;
+ sg_init_table(&dst_sg, 1);
+ sg_init_table(&src_sg, 1);
+
if (unlikely(ecryptfs_verbosity > 0)) {
ecryptfs_printk(
KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index 5276b19423c..f7f407075be 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -10,6 +10,8 @@
#include <linux/string.h>
#include <linux/efs_fs.h>
#include <linux/smp_lock.h>
+#include <linux/exportfs.h>
+
static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
struct buffer_head *bh;
@@ -75,13 +77,10 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct namei
return NULL;
}
-struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
+ u32 generation)
{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
struct inode *inode;
- struct dentry *result;
if (ino == 0)
return ERR_PTR(-ESTALE);
@@ -91,20 +90,25 @@ struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
if (is_bad_inode(inode) ||
(generation && inode->i_generation != generation)) {
- result = ERR_PTR(-ESTALE);
- goto out_iput;
+ iput(inode);
+ return ERR_PTR(-ESTALE);
}
- result = d_alloc_anon(inode);
- if (!result) {
- result = ERR_PTR(-ENOMEM);
- goto out_iput;
- }
- return result;
+ return inode;
+}
- out_iput:
- iput(inode);
- return result;
+struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ efs_nfs_get_inode);
+}
+
+struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ efs_nfs_get_inode);
}
struct dentry *efs_get_parent(struct dentry *child)
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 25d0326c5f1..c79bc627f10 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -113,8 +113,9 @@ static const struct super_operations efs_superblock_operations = {
.remount_fs = efs_remount,
};
-static struct export_operations efs_export_ops = {
- .get_dentry = efs_get_dentry,
+static const struct export_operations efs_export_ops = {
+ .fh_to_dentry = efs_fh_to_dentry,
+ .fh_to_parent = efs_fh_to_parent,
.get_parent = efs_get_parent,
};
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index de618929195..34f68f3a069 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -325,15 +325,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
int wake_nests = 0;
unsigned long flags;
struct task_struct *this_task = current;
- struct list_head *lsthead = &psw->wake_task_list, *lnk;
+ struct list_head *lsthead = &psw->wake_task_list;
struct wake_task_node *tncur;
struct wake_task_node tnode;
spin_lock_irqsave(&psw->lock, flags);
/* Try to see if the current task is already inside this wakeup call */
- list_for_each(lnk, lsthead) {
- tncur = list_entry(lnk, struct wake_task_node, llink);
+ list_for_each_entry(tncur, lsthead, llink) {
if (tncur->wq == wq ||
(tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) {
diff --git a/fs/exec.c b/fs/exec.c
index 070ddf13cb7..2c942e2d14e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -234,7 +234,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
vma->vm_start = vma->vm_end - PAGE_SIZE;
vma->vm_flags = VM_STACK_FLAGS;
- vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
err = insert_vm_struct(mm, vma);
if (err) {
up_write(&mm->mmap_sem);
@@ -775,8 +775,8 @@ static int de_thread(struct task_struct *tsk)
* Reparenting needs write_lock on tasklist_lock,
* so it is safe to do it under read_lock.
*/
- if (unlikely(tsk->group_leader == child_reaper(tsk)))
- tsk->nsproxy->pid_ns->child_reaper = tsk;
+ if (unlikely(tsk->group_leader == task_child_reaper(tsk)))
+ task_active_pid_ns(tsk)->child_reaper = tsk;
zap_other_threads(tsk);
read_unlock(&tasklist_lock);
@@ -841,8 +841,8 @@ static int de_thread(struct task_struct *tsk)
*/
tsk->start_time = leader->start_time;
- BUG_ON(leader->tgid != tsk->tgid);
- BUG_ON(tsk->pid == tsk->tgid);
+ BUG_ON(!same_thread_group(leader, tsk));
+ BUG_ON(has_group_leader_pid(tsk));
/*
* An exec() starts a new thread group with the
* TGID of the previous thread group. Rehash the
@@ -857,7 +857,7 @@ static int de_thread(struct task_struct *tsk)
*/
detach_pid(tsk, PIDTYPE_PID);
tsk->pid = leader->pid;
- attach_pid(tsk, PIDTYPE_PID, find_pid(tsk->pid));
+ attach_pid(tsk, PIDTYPE_PID, task_pid(leader));
transfer_pid(leader, tsk, PIDTYPE_PGID);
transfer_pid(leader, tsk, PIDTYPE_SID);
list_replace_rcu(&leader->tasks, &tsk->tasks);
@@ -1433,7 +1433,7 @@ static int format_corename(char *corename, const char *pattern, long signr)
case 'p':
pid_in_pattern = 1;
rc = snprintf(out_ptr, out_end - out_ptr,
- "%d", current->tgid);
+ "%d", task_tgid_vnr(current));
if (rc > out_end - out_ptr)
goto out;
out_ptr += rc;
@@ -1513,7 +1513,7 @@ static int format_corename(char *corename, const char *pattern, long signr)
if (!ispipe && !pid_in_pattern
&& (core_uses_pid || atomic_read(&current->mm->mm_users) != 1)) {
rc = snprintf(out_ptr, out_end - out_ptr,
- ".%d", current->tgid);
+ ".%d", task_tgid_vnr(current));
if (rc > out_end - out_ptr)
goto out;
out_ptr += rc;
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 8adb32a9387..109ab5e44ec 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -1,4 +1,13 @@
-
+/*
+ * Copyright (C) Neil Brown 2002
+ * Copyright (C) Christoph Hellwig 2007
+ *
+ * This file contains the code mapping from inodes to NFS file handles,
+ * and for mapping back from file handles to dentries.
+ *
+ * For details on why we do all the strange and hairy things in here
+ * take a look at Documentation/filesystems/Exporting.
+ */
#include <linux/exportfs.h>
#include <linux/fs.h>
#include <linux/file.h>
@@ -9,32 +18,19 @@
#define dprintk(fmt, args...) do{}while(0)
-static int get_name(struct dentry *dentry, char *name,
+static int get_name(struct vfsmount *mnt, struct dentry *dentry, char *name,
struct dentry *child);
-static struct dentry *exportfs_get_dentry(struct super_block *sb, void *obj)
+static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
+ char *name, struct dentry *child)
{
- struct dentry *result = ERR_PTR(-ESTALE);
-
- if (sb->s_export_op->get_dentry) {
- result = sb->s_export_op->get_dentry(sb, obj);
- if (!result)
- result = ERR_PTR(-ESTALE);
- }
-
- return result;
-}
-
-static int exportfs_get_name(struct dentry *dir, char *name,
- struct dentry *child)
-{
- struct export_operations *nop = dir->d_sb->s_export_op;
+ const struct export_operations *nop = dir->d_sb->s_export_op;
if (nop->get_name)
return nop->get_name(dir, name, child);
else
- return get_name(dir, name, child);
+ return get_name(mnt, dir, name, child);
}
/*
@@ -98,7 +94,7 @@ find_disconnected_root(struct dentry *dentry)
* It may already be, as the flag isn't always updated when connection happens.
*/
static int
-reconnect_path(struct super_block *sb, struct dentry *target_dir)
+reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
{
char nbuf[NAME_MAX+1];
int noprogress = 0;
@@ -121,7 +117,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
pd->d_flags &= ~DCACHE_DISCONNECTED;
spin_unlock(&pd->d_lock);
noprogress = 0;
- } else if (pd == sb->s_root) {
+ } else if (pd == mnt->mnt_sb->s_root) {
printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
spin_lock(&pd->d_lock);
pd->d_flags &= ~DCACHE_DISCONNECTED;
@@ -147,8 +143,8 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
struct dentry *npd;
mutex_lock(&pd->d_inode->i_mutex);
- if (sb->s_export_op->get_parent)
- ppd = sb->s_export_op->get_parent(pd);
+ if (mnt->mnt_sb->s_export_op->get_parent)
+ ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
mutex_unlock(&pd->d_inode->i_mutex);
if (IS_ERR(ppd)) {
@@ -161,7 +157,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
pd->d_inode->i_ino, ppd->d_inode->i_ino);
- err = exportfs_get_name(ppd, nbuf, pd);
+ err = exportfs_get_name(mnt, ppd, nbuf, pd);
if (err) {
dput(ppd);
dput(pd);
@@ -214,125 +210,6 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
return 0;
}
-/**
- * find_exported_dentry - helper routine to implement export_operations->decode_fh
- * @sb: The &super_block identifying the filesystem
- * @obj: An opaque identifier of the object to be found - passed to
- * get_inode
- * @parent: An optional opqaue identifier of the parent of the object.
- * @acceptable: A function used to test possible &dentries to see if they are
- * acceptable
- * @context: A parameter to @acceptable so that it knows on what basis to
- * judge.
- *
- * find_exported_dentry is the central helper routine to enable file systems
- * to provide the decode_fh() export_operation. It's main task is to take
- * an &inode, find or create an appropriate &dentry structure, and possibly
- * splice this into the dcache in the correct place.
- *
- * The decode_fh() operation provided by the filesystem should call
- * find_exported_dentry() with the same parameters that it received except
- * that instead of the file handle fragment, pointers to opaque identifiers
- * for the object and optionally its parent are passed. The default decode_fh
- * routine passes one pointer to the start of the filehandle fragment, and
- * one 8 bytes into the fragment. It is expected that most filesystems will
- * take this approach, though the offset to the parent identifier may well be
- * different.
- *
- * find_exported_dentry() will call get_dentry to get an dentry pointer from
- * the file system. If any &dentry in the d_alias list is acceptable, it will
- * be returned. Otherwise find_exported_dentry() will attempt to splice a new
- * &dentry into the dcache using get_name() and get_parent() to find the
- * appropriate place.
- */
-
-struct dentry *
-find_exported_dentry(struct super_block *sb, void *obj, void *parent,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
-{
- struct dentry *result, *alias;
- int err = -ESTALE;
-
- /*
- * Attempt to find the inode.
- */
- result = exportfs_get_dentry(sb, obj);
- if (IS_ERR(result))
- return result;
-
- if (S_ISDIR(result->d_inode->i_mode)) {
- if (!(result->d_flags & DCACHE_DISCONNECTED)) {
- if (acceptable(context, result))
- return result;
- err = -EACCES;
- goto err_result;
- }
-
- err = reconnect_path(sb, result);
- if (err)
- goto err_result;
- } else {
- struct dentry *target_dir, *nresult;
- char nbuf[NAME_MAX+1];
-
- alias = find_acceptable_alias(result, acceptable, context);
- if (alias)
- return alias;
-
- if (parent == NULL)
- goto err_result;
-
- target_dir = exportfs_get_dentry(sb,parent);
- if (IS_ERR(target_dir)) {
- err = PTR_ERR(target_dir);
- goto err_result;
- }
-
- err = reconnect_path(sb, target_dir);
- if (err) {
- dput(target_dir);
- goto err_result;
- }
-
- /*
- * As we weren't after a directory, have one more step to go.
- */
- err = exportfs_get_name(target_dir, nbuf, result);
- if (!err) {
- mutex_lock(&target_dir->d_inode->i_mutex);
- nresult = lookup_one_len(nbuf, target_dir,
- strlen(nbuf));
- mutex_unlock(&target_dir->d_inode->i_mutex);
- if (!IS_ERR(nresult)) {
- if (nresult->d_inode) {
- dput(result);
- result = nresult;
- } else
- dput(nresult);
- }
- }
- dput(target_dir);
- }
-
- alias = find_acceptable_alias(result, acceptable, context);
- if (alias)
- return alias;
-
- /* drat - I just cannot find anything acceptable */
- dput(result);
- /* It might be justifiable to return ESTALE here,
- * but the filehandle at-least looks reasonable good
- * and it may just be a permission problem, so returning
- * -EACCESS is safer
- */
- return ERR_PTR(-EACCES);
-
- err_result:
- dput(result);
- return ERR_PTR(err);
-}
-
struct getdents_callback {
char *name; /* name that was found. It already points to a
buffer NAME_MAX+1 is size */
@@ -370,8 +247,8 @@ static int filldir_one(void * __buf, const char * name, int len,
* calls readdir on the parent until it finds an entry with
* the same inode number as the child, and returns that.
*/
-static int get_name(struct dentry *dentry, char *name,
- struct dentry *child)
+static int get_name(struct vfsmount *mnt, struct dentry *dentry,
+ char *name, struct dentry *child)
{
struct inode *dir = dentry->d_inode;
int error;
@@ -387,7 +264,7 @@ static int get_name(struct dentry *dentry, char *name,
/*
* Open the directory ...
*/
- file = dentry_open(dget(dentry), NULL, O_RDONLY);
+ file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
error = PTR_ERR(file);
if (IS_ERR(file))
goto out;
@@ -434,100 +311,177 @@ out:
* can be used to check that it is still valid. It places them in the
* filehandle fragment where export_decode_fh expects to find them.
*/
-static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
- int connectable)
+static int export_encode_fh(struct dentry *dentry, struct fid *fid,
+ int *max_len, int connectable)
{
struct inode * inode = dentry->d_inode;
int len = *max_len;
- int type = 1;
+ int type = FILEID_INO32_GEN;
if (len < 2 || (connectable && len < 4))
return 255;
len = 2;
- fh[0] = inode->i_ino;
- fh[1] = inode->i_generation;
+ fid->i32.ino = inode->i_ino;
+ fid->i32.gen = inode->i_generation;
if (connectable && !S_ISDIR(inode->i_mode)) {
struct inode *parent;
spin_lock(&dentry->d_lock);
parent = dentry->d_parent->d_inode;
- fh[2] = parent->i_ino;
- fh[3] = parent->i_generation;
+ fid->i32.parent_ino = parent->i_ino;
+ fid->i32.parent_gen = parent->i_generation;
spin_unlock(&dentry->d_lock);
len = 4;
- type = 2;
+ type = FILEID_INO32_GEN_PARENT;
}
*max_len = len;
return type;
}
-
-/**
- * export_decode_fh - default export_operations->decode_fh function
- * @sb: The superblock
- * @fh: pointer to the file handle fragment
- * @fh_len: length of file handle fragment
- * @acceptable: function for testing acceptability of dentrys
- * @context: context for @acceptable
- *
- * This is the default decode_fh() function.
- * a fileid_type of 1 indicates that the filehandlefragment
- * just contains an object identifier understood by get_dentry.
- * a fileid_type of 2 says that there is also a directory
- * identifier 8 bytes in to the filehandlefragement.
- */
-static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
- int fileid_type,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
-{
- __u32 parent[2];
- parent[0] = parent[1] = 0;
- if (fh_len < 2 || fileid_type > 2)
- return NULL;
- if (fileid_type == 2) {
- if (fh_len > 2) parent[0] = fh[2];
- if (fh_len > 3) parent[1] = fh[3];
- }
- return find_exported_dentry(sb, fh, parent,
- acceptable, context);
-}
-
-int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
+int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
int connectable)
{
- struct export_operations *nop = dentry->d_sb->s_export_op;
+ const struct export_operations *nop = dentry->d_sb->s_export_op;
int error;
if (nop->encode_fh)
- error = nop->encode_fh(dentry, fh, max_len, connectable);
+ error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
else
- error = export_encode_fh(dentry, fh, max_len, connectable);
+ error = export_encode_fh(dentry, fid, max_len, connectable);
return error;
}
EXPORT_SYMBOL_GPL(exportfs_encode_fh);
-struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len,
- int fileid_type, int (*acceptable)(void *, struct dentry *),
- void *context)
+struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
+ int fh_len, int fileid_type,
+ int (*acceptable)(void *, struct dentry *), void *context)
{
- struct export_operations *nop = mnt->mnt_sb->s_export_op;
- struct dentry *result;
+ const struct export_operations *nop = mnt->mnt_sb->s_export_op;
+ struct dentry *result, *alias;
+ int err;
- if (nop->decode_fh) {
- result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
- acceptable, context);
+ /*
+ * Try to get any dentry for the given file handle from the filesystem.
+ */
+ result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
+ if (!result)
+ result = ERR_PTR(-ESTALE);
+ if (IS_ERR(result))
+ return result;
+
+ if (S_ISDIR(result->d_inode->i_mode)) {
+ /*
+ * This request is for a directory.
+ *
+ * On the positive side there is only one dentry for each
+ * directory inode. On the negative side this implies that we
+ * to ensure our dentry is connected all the way up to the
+ * filesystem root.
+ */
+ if (result->d_flags & DCACHE_DISCONNECTED) {
+ err = reconnect_path(mnt, result);
+ if (err)
+ goto err_result;
+ }
+
+ if (!acceptable(context, result)) {
+ err = -EACCES;
+ goto err_result;
+ }
+
+ return result;
} else {
- result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type,
- acceptable, context);
+ /*
+ * It's not a directory. Life is a little more complicated.
+ */
+ struct dentry *target_dir, *nresult;
+ char nbuf[NAME_MAX+1];
+
+ /*
+ * See if either the dentry we just got from the filesystem
+ * or any alias for it is acceptable. This is always true
+ * if this filesystem is exported without the subtreecheck
+ * option. If the filesystem is exported with the subtree
+ * check option there's a fair chance we need to look at
+ * the parent directory in the file handle and make sure
+ * it's connected to the filesystem root.
+ */
+ alias = find_acceptable_alias(result, acceptable, context);
+ if (alias)
+ return alias;
+
+ /*
+ * Try to extract a dentry for the parent directory from the
+ * file handle. If this fails we'll have to give up.
+ */
+ err = -ESTALE;
+ if (!nop->fh_to_parent)
+ goto err_result;
+
+ target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
+ fh_len, fileid_type);
+ if (!target_dir)
+ goto err_result;
+ err = PTR_ERR(target_dir);
+ if (IS_ERR(target_dir))
+ goto err_result;
+
+ /*
+ * And as usual we need to make sure the parent directory is
+ * connected to the filesystem root. The VFS really doesn't
+ * like disconnected directories..
+ */
+ err = reconnect_path(mnt, target_dir);
+ if (err) {
+ dput(target_dir);
+ goto err_result;
+ }
+
+ /*
+ * Now that we've got both a well-connected parent and a
+ * dentry for the inode we're after, make sure that our
+ * inode is actually connected to the parent.
+ */
+ err = exportfs_get_name(mnt, target_dir, nbuf, result);
+ if (!err) {
+ mutex_lock(&target_dir->d_inode->i_mutex);
+ nresult = lookup_one_len(nbuf, target_dir,
+ strlen(nbuf));
+ mutex_unlock(&target_dir->d_inode->i_mutex);
+ if (!IS_ERR(nresult)) {
+ if (nresult->d_inode) {
+ dput(result);
+ result = nresult;
+ } else
+ dput(nresult);
+ }
+ }
+
+ /*
+ * At this point we are done with the parent, but it's pinned
+ * by the child dentry anyway.
+ */
+ dput(target_dir);
+
+ /*
+ * And finally make sure the dentry is actually acceptable
+ * to NFSD.
+ */
+ alias = find_acceptable_alias(result, acceptable, context);
+ if (!alias) {
+ err = -EACCES;
+ goto err_result;
+ }
+
+ return alias;
}
- return result;
+ err_result:
+ dput(result);
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(exportfs_decode_fh);
-EXPORT_SYMBOL(find_exported_dentry);
-
MODULE_LICENSE("GPL");
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 05d9342bb64..d868e26c15e 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -28,6 +28,24 @@
typedef struct ext2_dir_entry_2 ext2_dirent;
+static inline unsigned ext2_rec_len_from_disk(__le16 dlen)
+{
+ unsigned len = le16_to_cpu(dlen);
+
+ if (len == EXT2_MAX_REC_LEN)
+ return 1 << 16;
+ return len;
+}
+
+static inline __le16 ext2_rec_len_to_disk(unsigned len)
+{
+ if (len == (1 << 16))
+ return cpu_to_le16(EXT2_MAX_REC_LEN);
+ else if (len > (1 << 16))
+ BUG();
+ return cpu_to_le16(len);
+}
+
/*
* ext2 uses block-sized chunks. Arguably, sector-sized ones would be
* more robust, but we have what we have
@@ -106,7 +124,7 @@ static void ext2_check_page(struct page *page)
}
for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
p = (ext2_dirent *)(kaddr + offs);
- rec_len = le16_to_cpu(p->rec_len);
+ rec_len = ext2_rec_len_from_disk(p->rec_len);
if (rec_len < EXT2_DIR_REC_LEN(1))
goto Eshort;
@@ -204,7 +222,8 @@ static inline int ext2_match (int len, const char * const name,
*/
static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
{
- return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len));
+ return (ext2_dirent *)((char *)p +
+ ext2_rec_len_from_disk(p->rec_len));
}
static inline unsigned
@@ -316,7 +335,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
return 0;
}
}
- filp->f_pos += le16_to_cpu(de->rec_len);
+ filp->f_pos += ext2_rec_len_from_disk(de->rec_len);
}
ext2_put_page(page);
}
@@ -425,7 +444,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
{
loff_t pos = page_offset(page) +
(char *) de - (char *) page_address(page);
- unsigned len = le16_to_cpu(de->rec_len);
+ unsigned len = ext2_rec_len_from_disk(de->rec_len);
int err;
lock_page(page);
@@ -482,7 +501,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
/* We hit i_size */
name_len = 0;
rec_len = chunk_size;
- de->rec_len = cpu_to_le16(chunk_size);
+ de->rec_len = ext2_rec_len_to_disk(chunk_size);
de->inode = 0;
goto got_it;
}
@@ -496,7 +515,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
if (ext2_match (namelen, name, de))
goto out_unlock;
name_len = EXT2_DIR_REC_LEN(de->name_len);
- rec_len = le16_to_cpu(de->rec_len);
+ rec_len = ext2_rec_len_from_disk(de->rec_len);
if (!de->inode && rec_len >= reclen)
goto got_it;
if (rec_len >= name_len + reclen)
@@ -518,8 +537,8 @@ got_it:
goto out_unlock;
if (de->inode) {
ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
- de1->rec_len = cpu_to_le16(rec_len - name_len);
- de->rec_len = cpu_to_le16(name_len);
+ de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
+ de->rec_len = ext2_rec_len_to_disk(name_len);
de = de1;
}
de->name_len = namelen;
@@ -550,7 +569,8 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
struct inode *inode = mapping->host;
char *kaddr = page_address(page);
unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
- unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
+ unsigned to = ((char *)dir - kaddr) +
+ ext2_rec_len_from_disk(dir->rec_len);
loff_t pos;
ext2_dirent * pde = NULL;
ext2_dirent * de = (ext2_dirent *) (kaddr + from);
@@ -574,7 +594,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
&page, NULL);
BUG_ON(err);
if (pde)
- pde->rec_len = cpu_to_le16(to - from);
+ pde->rec_len = ext2_rec_len_to_disk(to - from);
dir->inode = 0;
err = ext2_commit_chunk(page, pos, to - from);
inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
@@ -610,14 +630,14 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
memset(kaddr, 0, chunk_size);
de = (struct ext2_dir_entry_2 *)kaddr;
de->name_len = 1;
- de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));
+ de->rec_len = ext2_rec_len_to_disk(EXT2_DIR_REC_LEN(1));
memcpy (de->name, ".\0\0", 4);
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type (de, inode);
de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
de->name_len = 2;
- de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));
+ de->rec_len = ext2_rec_len_to_disk(chunk_size - EXT2_DIR_REC_LEN(1));
de->inode = cpu_to_le32(parent->i_ino);
memcpy (de->name, "..\0", 4);
ext2_set_de_type (de, inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 77bd5f9262f..154e25f13d7 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -311,13 +311,10 @@ static const struct super_operations ext2_sops = {
#endif
};
-static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext2_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
struct inode *inode;
- struct dentry *result;
if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
return ERR_PTR(-ESTALE);
@@ -338,15 +335,21 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
iput(inode);
return ERR_PTR(-ESTALE);
}
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+ return inode;
+}
+
+static struct dentry *ext2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ ext2_nfs_get_inode);
+}
+
+static struct dentry *ext2_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ ext2_nfs_get_inode);
}
/* Yes, most of these are left as NULL!!
@@ -354,9 +357,10 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
* systems, but can be improved upon.
* Currently only get_parent is required.
*/
-static struct export_operations ext2_export_ops = {
+static const struct export_operations ext2_export_ops = {
+ .fh_to_dentry = ext2_fh_to_dentry,
+ .fh_to_parent = ext2_fh_to_parent,
.get_parent = ext2_get_parent,
- .get_dentry = ext2_get_dentry,
};
static unsigned long get_sb_block(void **data)
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 3dec003b773..9b162cd6c16 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2954,7 +2954,7 @@ int ext3_write_inode(struct inode *inode, int wait)
return 0;
if (ext3_journal_current_handle()) {
- jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n");
+ jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n");
dump_stack();
return -EIO;
}
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 81868c0bc40..de55da9e28b 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -631,13 +631,10 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
}
-static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext3_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
struct inode *inode;
- struct dentry *result;
if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
return ERR_PTR(-ESTALE);
@@ -660,15 +657,22 @@ static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
iput(inode);
return ERR_PTR(-ESTALE);
}
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+
+ return inode;
+}
+
+static struct dentry *ext3_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ ext3_nfs_get_inode);
+}
+
+static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ ext3_nfs_get_inode);
}
#ifdef CONFIG_QUOTA
@@ -737,9 +741,10 @@ static const struct super_operations ext3_sops = {
#endif
};
-static struct export_operations ext3_export_ops = {
+static const struct export_operations ext3_export_ops = {
+ .fh_to_dentry = ext3_fh_to_dentry,
+ .fh_to_parent = ext3_fh_to_parent,
.get_parent = ext3_get_parent,
- .get_dentry = ext3_get_dentry,
};
enum {
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c
index f58cbb26323..408373819e3 100644
--- a/fs/ext3/xattr.c
+++ b/fs/ext3/xattr.c
@@ -741,12 +741,11 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode,
}
} else {
/* Allocate a buffer where we construct the new block. */
- s->base = kmalloc(sb->s_blocksize, GFP_KERNEL);
+ s->base = kzalloc(sb->s_blocksize, GFP_KERNEL);
/* assert(header == s->base) */
error = -ENOMEM;
if (s->base == NULL)
goto cleanup;
- memset(s->base, 0, sb->s_blocksize);
header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC);
header(s->base)->h_blocks = cpu_to_le32(1);
header(s->base)->h_refcount = cpu_to_le32(1);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b11e9e2bcd0..8031dc0e24e 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -686,13 +686,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
}
-static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *ext4_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
struct inode *inode;
- struct dentry *result;
if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
return ERR_PTR(-ESTALE);
@@ -715,15 +712,22 @@ static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
iput(inode);
return ERR_PTR(-ESTALE);
}
- /* now to find a dentry.
- * If possible, get a well-connected one
- */
- result = d_alloc_anon(inode);
- if (!result) {
- iput(inode);
- return ERR_PTR(-ENOMEM);
- }
- return result;
+
+ return inode;
+}
+
+static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ ext4_nfs_get_inode);
+}
+
+static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ ext4_nfs_get_inode);
}
#ifdef CONFIG_QUOTA
@@ -792,9 +796,10 @@ static const struct super_operations ext4_sops = {
#endif
};
-static struct export_operations ext4_export_ops = {
+static const struct export_operations ext4_export_ops = {
+ .fh_to_dentry = ext4_fh_to_dentry,
+ .fh_to_parent = ext4_fh_to_parent,
.get_parent = ext4_get_parent,
- .get_dentry = ext4_get_dentry,
};
enum {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index c0c5e9c55b5..920a576e1c2 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -653,24 +653,15 @@ static const struct super_operations fat_sops = {
* of i_logstart is used to store the directory entry offset.
*/
-static struct dentry *
-fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
-{
- if (fhtype != 3)
- return ERR_PTR(-ESTALE);
- if (len < 5)
- return ERR_PTR(-ESTALE);
-
- return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
-}
-
-static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
+static struct dentry *fat_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
{
struct inode *inode = NULL;
struct dentry *result;
- __u32 *fh = inump;
+ u32 *fh = fid->raw;
+
+ if (fh_len < 5 || fh_type != 3)
+ return NULL;
inode = iget(sb, fh[0]);
if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
@@ -783,10 +774,9 @@ out:
return parent;
}
-static struct export_operations fat_export_ops = {
- .decode_fh = fat_decode_fh,
+static const struct export_operations fat_export_ops = {
.encode_fh = fat_encode_fh,
- .get_dentry = fat_get_dentry,
+ .fh_to_dentry = fat_fh_to_dentry,
.get_parent = fat_get_parent,
};
diff --git a/fs/fcntl.c b/fs/fcntl.c
index c9db73fc5e3..8685263ccc4 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -18,6 +18,7 @@
#include <linux/ptrace.h>
#include <linux/signal.h>
#include <linux/rcupdate.h>
+#include <linux/pid_namespace.h>
#include <asm/poll.h>
#include <asm/siginfo.h>
@@ -292,7 +293,7 @@ int f_setown(struct file *filp, unsigned long arg, int force)
who = -who;
}
rcu_read_lock();
- pid = find_pid(who);
+ pid = find_vpid(who);
result = __f_setown(filp, pid, type, force);
rcu_read_unlock();
return result;
@@ -308,7 +309,7 @@ pid_t f_getown(struct file *filp)
{
pid_t pid;
read_lock(&filp->f_owner.lock);
- pid = pid_nr(filp->f_owner.pid);
+ pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns);
if (filp->f_owner.pid_type == PIDTYPE_PGID)
pid = -pid;
read_unlock(&filp->f_owner.lock);
diff --git a/fs/file_table.c b/fs/file_table.c
index 3176fefc92e..664e3f2309b 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -323,12 +323,11 @@ void file_kill(struct file *file)
int fs_may_remount_ro(struct super_block *sb)
{
- struct list_head *p;
+ struct file *file;
/* Check that no files are currently opened for writing. */
file_list_lock();
- list_for_each(p, &sb->s_files) {
- struct file *file = list_entry(p, struct file, f_u.fu_list);
+ list_for_each_entry(file, &sb->s_files, f_u.fu_list) {
struct inode *inode = file->f_path.dentry->d_inode;
/* File with pending delete? */
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 686734ff973..0fca82021d7 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -89,7 +89,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev"))
printk(KERN_DEBUG
"%s(%d): dirtied inode %lu (%s) on %s\n",
- current->comm, current->pid, inode->i_ino,
+ current->comm, task_pid_nr(current), inode->i_ino,
name, inode->i_sb->s_id);
}
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index e2d1347796a..b9da62348a8 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -31,40 +31,6 @@
#define GFS2_LARGE_FH_SIZE 8
#define GFS2_OLD_FH_SIZE 10
-static struct dentry *gfs2_decode_fh(struct super_block *sb,
- __u32 *p,
- int fh_len,
- int fh_type,
- int (*acceptable)(void *context,
- struct dentry *dentry),
- void *context)
-{
- __be32 *fh = (__force __be32 *)p;
- struct gfs2_inum_host inum, parent;
-
- memset(&parent, 0, sizeof(struct gfs2_inum));
-
- switch (fh_len) {
- case GFS2_LARGE_FH_SIZE:
- case GFS2_OLD_FH_SIZE:
- parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
- parent.no_formal_ino |= be32_to_cpu(fh[5]);
- parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
- parent.no_addr |= be32_to_cpu(fh[7]);
- case GFS2_SMALL_FH_SIZE:
- inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
- inum.no_formal_ino |= be32_to_cpu(fh[1]);
- inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
- inum.no_addr |= be32_to_cpu(fh[3]);
- break;
- default:
- return NULL;
- }
-
- return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
- acceptable, context);
-}
-
static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
int connectable)
{
@@ -189,10 +155,10 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
return dentry;
}
-static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj)
+static struct dentry *gfs2_get_dentry(struct super_block *sb,
+ struct gfs2_inum_host *inum)
{
struct gfs2_sbd *sdp = sb->s_fs_info;
- struct gfs2_inum_host *inum = inum_obj;
struct gfs2_holder i_gh, ri_gh, rgd_gh;
struct gfs2_rgrpd *rgd;
struct inode *inode;
@@ -289,11 +255,50 @@ fail:
return ERR_PTR(error);
}
-struct export_operations gfs2_export_ops = {
- .decode_fh = gfs2_decode_fh,
+static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct gfs2_inum_host this;
+ __be32 *fh = (__force __be32 *)fid->raw;
+
+ switch (fh_type) {
+ case GFS2_SMALL_FH_SIZE:
+ case GFS2_LARGE_FH_SIZE:
+ case GFS2_OLD_FH_SIZE:
+ this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
+ this.no_formal_ino |= be32_to_cpu(fh[1]);
+ this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
+ this.no_addr |= be32_to_cpu(fh[3]);
+ return gfs2_get_dentry(sb, &this);
+ default:
+ return NULL;
+ }
+}
+
+static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ struct gfs2_inum_host parent;
+ __be32 *fh = (__force __be32 *)fid->raw;
+
+ switch (fh_type) {
+ case GFS2_LARGE_FH_SIZE:
+ case GFS2_OLD_FH_SIZE:
+ parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
+ parent.no_formal_ino |= be32_to_cpu(fh[5]);
+ parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
+ parent.no_addr |= be32_to_cpu(fh[7]);
+ return gfs2_get_dentry(sb, &parent);
+ default:
+ return NULL;
+ }
+}
+
+const struct export_operations gfs2_export_ops = {
.encode_fh = gfs2_encode_fh,
+ .fh_to_dentry = gfs2_fh_to_dentry,
+ .fh_to_parent = gfs2_fh_to_parent,
.get_name = gfs2_get_name,
.get_parent = gfs2_get_parent,
- .get_dentry = gfs2_get_dentry,
};
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h
index 407029b3b2b..da849051183 100644
--- a/fs/gfs2/ops_fstype.h
+++ b/fs/gfs2/ops_fstype.h
@@ -14,6 +14,6 @@
extern struct file_system_type gfs2_fs_type;
extern struct file_system_type gfs2meta_fs_type;
-extern struct export_operations gfs2_export_ops;
+extern const struct export_operations gfs2_export_ops;
#endif /* __OPS_FSTYPE_DOT_H__ */
diff --git a/fs/inotify.c b/fs/inotify.c
index 7457501b956..2c5b9215287 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -667,6 +667,49 @@ out:
EXPORT_SYMBOL_GPL(inotify_add_watch);
/**
+ * inotify_clone_watch - put the watch next to existing one
+ * @old: already installed watch
+ * @new: new watch
+ *
+ * Caller must hold the inotify_mutex of inode we are dealing with;
+ * it is expected to remove the old watch before unlocking the inode.
+ */
+s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
+{
+ struct inotify_handle *ih = old->ih;
+ int ret = 0;
+
+ new->mask = old->mask;
+ new->ih = ih;
+
+ mutex_lock(&ih->mutex);
+
+ /* Initialize a new watch */
+ ret = inotify_handle_get_wd(ih, new);
+ if (unlikely(ret))
+ goto out;
+ ret = new->wd;
+
+ get_inotify_handle(ih);
+
+ new->inode = igrab(old->inode);
+
+ list_add(&new->h_list, &ih->watches);
+ list_add(&new->i_list, &old->inode->inotify_watches);
+out:
+ mutex_unlock(&ih->mutex);
+ return ret;
+}
+
+void inotify_evict_watch(struct inotify_watch *watch)
+{
+ get_inotify_watch(watch);
+ mutex_lock(&watch->ih->mutex);
+ inotify_remove_watch_locked(watch->ih, watch);
+ mutex_unlock(&watch->ih->mutex);
+}
+
+/**
* inotify_rm_wd - remove a watch from an inotify instance
* @ih: inotify handle
* @wd: watch descriptor to remove
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 10d2c211d18..d6ff77e8e7e 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -25,6 +25,7 @@
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/security.h>
+#include <linux/pid_namespace.h>
static int set_task_ioprio(struct task_struct *task, int ioprio)
{
@@ -93,7 +94,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
if (!who)
p = current;
else
- p = find_task_by_pid(who);
+ p = find_task_by_vpid(who);
if (p)
ret = set_task_ioprio(p, ioprio);
break;
@@ -101,7 +102,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
if (!who)
pgrp = task_pgrp(current);
else
- pgrp = find_pid(who);
+ pgrp = find_vpid(who);
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
ret = set_task_ioprio(p, ioprio);
if (ret)
@@ -180,7 +181,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
if (!who)
p = current;
else
- p = find_task_by_pid(who);
+ p = find_task_by_vpid(who);
if (p)
ret = get_task_ioprio(p);
break;
@@ -188,7 +189,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
if (!who)
pgrp = task_pgrp(current);
else
- pgrp = find_pid(who);
+ pgrp = find_vpid(who);
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
tmpio = get_task_ioprio(p);
if (tmpio < 0)
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index 4af856a7fda..29f9753ae5e 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -42,16 +42,6 @@ isofs_export_iget(struct super_block *sb,
return result;
}
-static struct dentry *
-isofs_export_get_dentry(struct super_block *sb, void *vobjp)
-{
- __u32 *objp = vobjp;
- unsigned long block = objp[0];
- unsigned long offset = objp[1];
- __u32 generation = objp[2];
- return isofs_export_iget(sb, block, offset, generation);
-}
-
/* This function is surprisingly simple. The trick is understanding
* that "child" is always a directory. So, to find its parent, you
* simply need to find its ".." entry, normalize its block and offset,
@@ -182,43 +172,44 @@ isofs_export_encode_fh(struct dentry *dentry,
return type;
}
+struct isofs_fid {
+ u32 block;
+ u16 offset;
+ u16 parent_offset;
+ u32 generation;
+ u32 parent_block;
+ u32 parent_generation;
+};
-static struct dentry *
-isofs_export_decode_fh(struct super_block *sb,
- __u32 *fh32,
- int fh_len,
- int fileid_type,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
+static struct dentry *isofs_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
{
- __u16 *fh16 = (__u16*)fh32;
- __u32 child[3]; /* The child is what triggered all this. */
- __u32 parent[3]; /* The parent is just along for the ride. */
+ struct isofs_fid *ifid = (struct isofs_fid *)fid;
- if (fh_len < 3 || fileid_type > 2)
+ if (fh_len < 3 || fh_type > 2)
return NULL;
- child[0] = fh32[0];
- child[1] = fh16[2]; /* fh16 [sic] */
- child[2] = fh32[2];
-
- parent[0] = 0;
- parent[1] = 0;
- parent[2] = 0;
- if (fileid_type == 2) {
- if (fh_len > 2) parent[0] = fh32[3];
- parent[1] = fh16[3]; /* fh16 [sic] */
- if (fh_len > 4) parent[2] = fh32[4];
- }
-
- return sb->s_export_op->find_exported_dentry(sb, child, parent,
- acceptable, context);
+ return isofs_export_iget(sb, ifid->block, ifid->offset,
+ ifid->generation);
}
+static struct dentry *isofs_fh_to_parent(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ struct isofs_fid *ifid = (struct isofs_fid *)fid;
+
+ if (fh_type != 2)
+ return NULL;
+
+ return isofs_export_iget(sb,
+ fh_len > 2 ? ifid->parent_block : 0,
+ ifid->parent_offset,
+ fh_len > 4 ? ifid->parent_generation : 0);
+}
-struct export_operations isofs_export_ops = {
- .decode_fh = isofs_export_decode_fh,
+const struct export_operations isofs_export_ops = {
.encode_fh = isofs_export_encode_fh,
- .get_dentry = isofs_export_get_dentry,
+ .fh_to_dentry = isofs_fh_to_dentry,
+ .fh_to_parent = isofs_fh_to_parent,
.get_parent = isofs_export_get_parent,
};
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index aa359a2e4ce..09e3d306e96 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -3,7 +3,7 @@
*
* (C) 1991 Linus Torvalds - minix filesystem
* 1992, 1993, 1994 Eric Youngdale Modified for ISO 9660 filesystem.
- * 1994 Eberhard Moenkeberg - multi session handling.
+ * 1994 Eberhard Mönkeberg - multi session handling.
* 1995 Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
* 1997 Gordon Chaffee - Joliet CDs
* 1998 Eric Lammerts - ISO 9660 Level 3
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index a07e67b1ea7..f3213f9f89a 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -178,4 +178,4 @@ isofs_normalize_block_and_offset(struct iso_directory_record* de,
extern const struct inode_operations isofs_dir_inode_operations;
extern const struct file_operations isofs_dir_operations;
extern const struct address_space_operations isofs_symlink_aops;
-extern struct export_operations isofs_export_ops;
+extern const struct export_operations isofs_export_ops;
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index a263d82761d..8f1f2aa5fb3 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -466,7 +466,7 @@ void journal_commit_transaction(journal_t *journal)
spin_unlock(&journal->j_list_lock);
if (err)
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
journal_write_revoke_records(journal, commit_transaction);
@@ -524,7 +524,7 @@ void journal_commit_transaction(journal_t *journal)
descriptor = journal_get_descriptor_buffer(journal);
if (!descriptor) {
- __journal_abort_hard(journal);
+ journal_abort(journal, -EIO);
continue;
}
@@ -557,7 +557,7 @@ void journal_commit_transaction(journal_t *journal)
and repeat this loop: we'll fall into the
refile-on-abort condition above. */
if (err) {
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
continue;
}
@@ -748,7 +748,7 @@ wait_for_iobuf:
err = -EIO;
if (err)
- __journal_abort_hard(journal);
+ journal_abort(journal, err);
/* End of a transaction! Finally, we can do checkpoint
processing: any buffers committed as a result of this
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 5d9fec0b7eb..5d14243499d 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -35,6 +35,7 @@
#include <linux/kthread.h>
#include <linux/poison.h>
#include <linux/proc_fs.h>
+#include <linux/debugfs.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -654,10 +655,9 @@ static journal_t * journal_init_common (void)
journal_t *journal;
int err;
- journal = kmalloc(sizeof(*journal), GFP_KERNEL);
+ journal = kzalloc(sizeof(*journal), GFP_KERNEL);
if (!journal)
goto fail;
- memset(journal, 0, sizeof(*journal));
init_waitqueue_head(&journal->j_wait_transaction_locked);
init_waitqueue_head(&journal->j_wait_logspace);
@@ -1852,64 +1852,41 @@ void journal_put_journal_head(struct journal_head *jh)
}
/*
- * /proc tunables
+ * debugfs tunables
*/
-#if defined(CONFIG_JBD_DEBUG)
-int journal_enable_debug;
-EXPORT_SYMBOL(journal_enable_debug);
-#endif
+#ifdef CONFIG_JBD_DEBUG
-#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS)
+u8 journal_enable_debug __read_mostly;
+EXPORT_SYMBOL(journal_enable_debug);
-static struct proc_dir_entry *proc_jbd_debug;
+static struct dentry *jbd_debugfs_dir;
+static struct dentry *jbd_debug;
-static int read_jbd_debug(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static void __init jbd_create_debugfs_entry(void)
{
- int ret;
-
- ret = sprintf(page + off, "%d\n", journal_enable_debug);
- *eof = 1;
- return ret;
+ jbd_debugfs_dir = debugfs_create_dir("jbd", NULL);
+ if (jbd_debugfs_dir)
+ jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO,
+ jbd_debugfs_dir,
+ &journal_enable_debug);
}
-static int write_jbd_debug(struct file *file, const char __user *buffer,
- unsigned long count, void *data)
+static void __exit jbd_remove_debugfs_entry(void)
{
- char buf[32];
-
- if (count > ARRAY_SIZE(buf) - 1)
- count = ARRAY_SIZE(buf) - 1;
- if (copy_from_user(buf, buffer, count))
- return -EFAULT;
- buf[ARRAY_SIZE(buf) - 1] = '\0';
- journal_enable_debug = simple_strtoul(buf, NULL, 10);
- return count;
+ debugfs_remove(jbd_debug);
+ debugfs_remove(jbd_debugfs_dir);
}
-#define JBD_PROC_NAME "sys/fs/jbd-debug"
+#else
-static void __init create_jbd_proc_entry(void)
+static inline void jbd_create_debugfs_entry(void)
{
- proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL);
- if (proc_jbd_debug) {
- /* Why is this so hard? */
- proc_jbd_debug->read_proc = read_jbd_debug;
- proc_jbd_debug->write_proc = write_jbd_debug;
- }
}
-static void __exit remove_jbd_proc_entry(void)
+static inline void jbd_remove_debugfs_entry(void)
{
- if (proc_jbd_debug)
- remove_proc_entry(JBD_PROC_NAME, NULL);
}
-#else
-
-#define create_jbd_proc_entry() do {} while (0)
-#define remove_jbd_proc_entry() do {} while (0)
-
#endif
struct kmem_cache *jbd_handle_cache;
@@ -1966,7 +1943,7 @@ static int __init journal_init(void)
ret = journal_init_caches();
if (ret != 0)
journal_destroy_caches();
- create_jbd_proc_entry();
+ jbd_create_debugfs_entry();
return ret;
}
@@ -1977,7 +1954,7 @@ static void __exit journal_exit(void)
if (n)
printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n);
#endif
- remove_jbd_proc_entry();
+ jbd_remove_debugfs_entry();
journal_destroy_caches();
}
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 2a5f4b833e3..c5d9694b6a2 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -250,10 +250,10 @@ int journal_recover(journal_t *journal)
if (!err)
err = do_one_pass(journal, &info, PASS_REPLAY);
- jbd_debug(0, "JBD: recovery, exit status %d, "
+ jbd_debug(1, "JBD: recovery, exit status %d, "
"recovered transactions %u to %u\n",
err, info.start_transaction, info.end_transaction);
- jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
+ jbd_debug(1, "JBD: Replayed %d and revoked %d/%d blocks\n",
info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
/* Restart the log at the next transaction ID, thus invalidating
@@ -297,7 +297,7 @@ int journal_skip_recovery(journal_t *journal)
#ifdef CONFIG_JBD_DEBUG
int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
#endif
- jbd_debug(0,
+ jbd_debug(1,
"JBD: ignoring %d transaction%s from the journal.\n",
dropped, (dropped == 1) ? "" : "s");
journal->j_transaction_sequence = ++info.end_transaction;
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 9841b1e5af0..08ff6c7028c 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -96,13 +96,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle)
alloc_transaction:
if (!journal->j_running_transaction) {
- new_transaction = kmalloc(sizeof(*new_transaction),
+ new_transaction = kzalloc(sizeof(*new_transaction),
GFP_NOFS|__GFP_NOFAIL);
if (!new_transaction) {
ret = -ENOMEM;
goto out;
}
- memset(new_transaction, 0, sizeof(*new_transaction));
}
jbd_debug(3, "New handle %p going live.\n", handle);
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 2a49f2c51a9..4130adabd76 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -80,28 +80,28 @@
#define JFFS2_ERROR(fmt, ...) \
do { \
printk(JFFS2_ERR_MSG_PREFIX \
- " (%d) %s: " fmt, current->pid, \
+ " (%d) %s: " fmt, task_pid_nr(current), \
__FUNCTION__ , ##__VA_ARGS__); \
} while(0)
#define JFFS2_WARNING(fmt, ...) \
do { \
printk(JFFS2_WARN_MSG_PREFIX \
- " (%d) %s: " fmt, current->pid, \
+ " (%d) %s: " fmt, task_pid_nr(current), \
__FUNCTION__ , ##__VA_ARGS__); \
} while(0)
#define JFFS2_NOTICE(fmt, ...) \
do { \
printk(JFFS2_NOTICE_MSG_PREFIX \
- " (%d) %s: " fmt, current->pid, \
+ " (%d) %s: " fmt, task_pid_nr(current), \
__FUNCTION__ , ##__VA_ARGS__); \
} while(0)
#define JFFS2_DEBUG(fmt, ...) \
do { \
printk(JFFS2_DBG_MSG_PREFIX \
- " (%d) %s: " fmt, current->pid, \
+ " (%d) %s: " fmt, task_pid_nr(current), \
__FUNCTION__ , ##__VA_ARGS__); \
} while(0)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index df0b8535de8..df25ecc418a 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -773,7 +773,7 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
getChild:
/* update max. number of pages to split */
if (BT_STACK_FULL(btstack)) {
- /* Something's corrupted, mark filesytem dirty so
+ /* Something's corrupted, mark filesystem dirty so
* chkdsk will fix it.
*/
jfs_error(sb, "stack overrun in dtSearch!");
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index f0ec72b263f..8e2cf2cde18 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -18,6 +18,8 @@
#ifndef _H_JFS_INODE
#define _H_JFS_INODE
+struct fid;
+
extern struct inode *ialloc(struct inode *, umode_t);
extern int jfs_fsync(struct file *, struct dentry *, int);
extern int jfs_ioctl(struct inode *, struct file *,
@@ -32,7 +34,10 @@ extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry);
extern void jfs_get_inode_flags(struct jfs_inode_info *);
-extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
extern void jfs_set_inode_flags(struct inode *);
extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 932797ba433..4e0a8493cef 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -20,6 +20,7 @@
#include <linux/fs.h>
#include <linux/ctype.h>
#include <linux/quotaops.h>
+#include <linux/exportfs.h>
#include "jfs_incore.h"
#include "jfs_superblock.h"
#include "jfs_inode.h"
@@ -1477,13 +1478,10 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
return dentry;
}
-struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct inode *jfs_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
{
- __u32 *objp = vobjp;
- unsigned long ino = objp[0];
- __u32 generation = objp[1];
struct inode *inode;
- struct dentry *result;
if (ino == 0)
return ERR_PTR(-ESTALE);
@@ -1493,20 +1491,25 @@ struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
if (is_bad_inode(inode) ||
(generation && inode->i_generation != generation)) {
- result = ERR_PTR(-ESTALE);
- goto out_iput;
+ iput(inode);
+ return ERR_PTR(-ESTALE);
}
- result = d_alloc_anon(inode);
- if (!result) {
- result = ERR_PTR(-ENOMEM);
- goto out_iput;
- }
- return result;
+ return inode;
+}
- out_iput:
- iput(inode);
- return result;
+struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ jfs_nfs_get_inode);
+}
+
+struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ jfs_nfs_get_inode);
}
struct dentry *jfs_get_parent(struct dentry *dentry)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index cff60c17194..314bb4ff1ba 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -48,7 +48,7 @@ MODULE_LICENSE("GPL");
static struct kmem_cache * jfs_inode_cachep;
static const struct super_operations jfs_super_operations;
-static struct export_operations jfs_export_operations;
+static const struct export_operations jfs_export_operations;
static struct file_system_type jfs_fs_type;
#define MAX_COMMIT_THREADS 64
@@ -737,8 +737,9 @@ static const struct super_operations jfs_super_operations = {
#endif
};
-static struct export_operations jfs_export_operations = {
- .get_dentry = jfs_get_dentry,
+static const struct export_operations jfs_export_operations = {
+ .fh_to_dentry = jfs_fh_to_dentry,
+ .fh_to_parent = jfs_fh_to_parent,
.get_parent = jfs_get_parent,
};
diff --git a/fs/libfs.c b/fs/libfs.c
index ae51481e45e..6e68b700958 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -8,6 +8,7 @@
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/mutex.h>
+#include <linux/exportfs.h>
#include <asm/uaccess.h>
@@ -678,6 +679,93 @@ out:
return ret;
}
+/*
+ * This is what d_alloc_anon should have been. Once the exportfs
+ * argument transition has been finished I will update d_alloc_anon
+ * to this prototype and this wrapper will go away. --hch
+ */
+static struct dentry *exportfs_d_alloc(struct inode *inode)
+{
+ struct dentry *dentry;
+
+ if (!inode)
+ return NULL;
+ if (IS_ERR(inode))
+ return ERR_PTR(PTR_ERR(inode));
+
+ dentry = d_alloc_anon(inode);
+ if (!dentry) {
+ iput(inode);
+ dentry = ERR_PTR(-ENOMEM);
+ }
+ return dentry;
+}
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
+ * @sb: filesystem to do the file handle conversion on
+ * @fid: file handle to convert
+ * @fh_len: length of the file handle in bytes
+ * @fh_type: type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the object specified in the file handle.
+ */
+struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type, struct inode *(*get_inode)
+ (struct super_block *sb, u64 ino, u32 gen))
+{
+ struct inode *inode = NULL;
+
+ if (fh_len < 2)
+ return NULL;
+
+ switch (fh_type) {
+ case FILEID_INO32_GEN:
+ case FILEID_INO32_GEN_PARENT:
+ inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
+ break;
+ }
+
+ return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
+
+/**
+ * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
+ * @sb: filesystem to do the file handle conversion on
+ * @fid: file handle to convert
+ * @fh_len: length of the file handle in bytes
+ * @fh_type: type of file handle
+ * @get_inode: filesystem callback to retrieve inode
+ *
+ * This function decodes @fid as long as it has one of the well-known
+ * Linux filehandle types and calls @get_inode on it to retrieve the
+ * inode for the _parent_ object specified in the file handle if it
+ * is specified in the file handle, or NULL otherwise.
+ */
+struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type, struct inode *(*get_inode)
+ (struct super_block *sb, u64 ino, u32 gen))
+{
+ struct inode *inode = NULL;
+
+ if (fh_len <= 2)
+ return NULL;
+
+ switch (fh_type) {
+ case FILEID_INO32_GEN_PARENT:
+ inode = get_inode(sb, fid->i32.parent_ino,
+ (fh_len > 3 ? fid->i32.parent_gen : 0));
+ break;
+ }
+
+ return exportfs_d_alloc(inode);
+}
+EXPORT_SYMBOL_GPL(generic_fh_to_parent);
+
EXPORT_SYMBOL(dcache_dir_close);
EXPORT_SYMBOL(dcache_dir_lseek);
EXPORT_SYMBOL(dcache_dir_open);
diff --git a/fs/namei.c b/fs/namei.c
index 1e5c7166916..3b993db26ce 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
out:
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
nd->dentry->d_inode))
- audit_inode(name, nd->dentry->d_inode);
+ audit_inode(name, nd->dentry);
out_fail:
return retval;
@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
retval = path_walk(name, nd);
if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
nd->dentry->d_inode))
- audit_inode(name, nd->dentry->d_inode);
+ audit_inode(name, nd->dentry);
return retval;
@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
return -ENOENT;
BUG_ON(victim->d_parent->d_inode != dir);
- audit_inode_child(victim->d_name.name, victim->d_inode, dir);
+ audit_inode_child(victim->d_name.name, victim, dir);
error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
if (error)
@@ -1783,7 +1783,7 @@ do_last:
* It already exists.
*/
mutex_unlock(&dir->d_inode->i_mutex);
- audit_inode(pathname, path.dentry->d_inode);
+ audit_inode(pathname, path.dentry);
error = -EEXIST;
if (flag & O_EXCL)
@@ -2562,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (!error) {
const char *new_name = old_dentry->d_name.name;
fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
- new_dentry->d_inode, old_dentry->d_inode);
+ new_dentry->d_inode, old_dentry);
}
fsnotify_oldname_free(old_name);
diff --git a/fs/namespace.c b/fs/namespace.c
index 07daa797259..06083885b21 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
list_add(&mnt->mnt_slave, &old->mnt_slave_list);
mnt->mnt_master = old;
CLEAR_MNT_SHARED(mnt);
- } else {
+ } else if (!(flag & CL_PRIVATE)) {
if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
list_add(&mnt->mnt_share, &old->mnt_share);
if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
return NULL;
}
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+ struct vfsmount *tree;
+ down_read(&namespace_sem);
+ tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+ up_read(&namespace_sem);
+ return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+ LIST_HEAD(umount_list);
+ down_read(&namespace_sem);
+ spin_lock(&vfsmount_lock);
+ umount_tree(mnt, 0, &umount_list);
+ spin_unlock(&vfsmount_lock);
+ up_read(&namespace_sem);
+ release_mounts(&umount_list);
+}
+
/*
* @source_mnt : mount tree to be attached
* @nd : place the mount tree @source_mnt is attached
@@ -1411,7 +1431,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
mnt_flags |= MNT_RELATIME;
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
- MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
+ MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
/* ... and get the mountpoint */
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index af8b235d405..11833f4caea 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -168,7 +168,8 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
spin_unlock(&inode->i_lock);
spin_unlock(&clp->cl_lock);
- kfree(delegation);
+ if (delegation != NULL)
+ nfs_free_delegation(delegation);
return status;
}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 8ec7fbd8240..35334539d94 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -562,6 +562,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
nfs_fattr_init(&fattr);
desc->entry = &my_entry;
+ nfs_block_sillyrename(dentry);
while(!desc->entry->eof) {
res = readdir_search_pagecache(desc);
@@ -592,6 +593,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
break;
}
}
+ nfs_unblock_sillyrename(dentry);
unlock_kernel();
if (res > 0)
res = 0;
@@ -866,6 +868,7 @@ struct dentry_operations nfs_dentry_operations = {
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{
struct dentry *res;
+ struct dentry *parent;
struct inode *inode = NULL;
int error;
struct nfs_fh fhandle;
@@ -894,26 +897,31 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
goto out_unlock;
}
+ parent = dentry->d_parent;
+ /* Protect against concurrent sillydeletes */
+ nfs_block_sillyrename(parent);
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (error == -ENOENT)
goto no_entry;
if (error < 0) {
res = ERR_PTR(error);
- goto out_unlock;
+ goto out_unblock_sillyrename;
}
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
res = (struct dentry *)inode;
if (IS_ERR(res))
- goto out_unlock;
+ goto out_unblock_sillyrename;
no_entry:
res = d_materialise_unique(dentry, inode);
if (res != NULL) {
if (IS_ERR(res))
- goto out_unlock;
+ goto out_unblock_sillyrename;
dentry = res;
}
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+out_unblock_sillyrename:
+ nfs_unblock_sillyrename(parent);
out_unlock:
unlock_kernel();
out:
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index d29f90d00aa..b3bb89f7d5d 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -131,7 +131,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
{
/* Ensure that dirty pages are flushed out with the right creds */
if (filp->f_mode & FMODE_WRITE)
- filemap_fdatawrite(filp->f_mapping);
+ nfs_wb_all(filp->f_path.dentry->d_inode);
nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
return NFS_PROTO(inode)->file_release(inode, filp);
}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 6d2f2a3eccf..db5d96dc610 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -514,7 +514,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
return ctx;
}
-void put_nfs_open_context(struct nfs_open_context *ctx)
+static void __put_nfs_open_context(struct nfs_open_context *ctx, int wait)
{
struct inode *inode = ctx->path.dentry->d_inode;
@@ -522,8 +522,12 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
return;
list_del(&ctx->list);
spin_unlock(&inode->i_lock);
- if (ctx->state != NULL)
- nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+ if (ctx->state != NULL) {
+ if (wait)
+ nfs4_close_sync(&ctx->path, ctx->state, ctx->mode);
+ else
+ nfs4_close_state(&ctx->path, ctx->state, ctx->mode);
+ }
if (ctx->cred != NULL)
put_rpccred(ctx->cred);
dput(ctx->path.dentry);
@@ -531,6 +535,16 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
kfree(ctx);
}
+void put_nfs_open_context(struct nfs_open_context *ctx)
+{
+ __put_nfs_open_context(ctx, 0);
+}
+
+static void put_nfs_open_context_sync(struct nfs_open_context *ctx)
+{
+ __put_nfs_open_context(ctx, 1);
+}
+
/*
* Ensure that mmap has a recent RPC credential for use when writing out
* shared pages
@@ -577,7 +591,7 @@ static void nfs_file_clear_open_context(struct file *filp)
spin_lock(&inode->i_lock);
list_move_tail(&ctx->list, &NFS_I(inode)->open_files);
spin_unlock(&inode->i_lock);
- put_nfs_open_context(ctx);
+ put_nfs_open_context_sync(ctx);
}
}
@@ -1169,6 +1183,9 @@ static void init_once(struct kmem_cache * cachep, void *foo)
INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);
nfsi->ncommit = 0;
nfsi->npages = 0;
+ atomic_set(&nfsi->silly_count, 1);
+ INIT_HLIST_HEAD(&nfsi->silly_list);
+ init_waitqueue_head(&nfsi->waitqueue);
nfs4_init_once(nfsi);
}
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index d2802b1ca3b..b35069a2aa9 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -178,7 +178,7 @@ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struc
extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_async_renew(struct nfs_client *, struct rpc_cred *);
extern int nfs4_proc_renew(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_do_close(struct path *path, struct nfs4_state *state);
+extern int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait);
extern struct dentry *nfs4_atomic_open(struct inode *, struct dentry *, struct nameidata *);
extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nameidata *);
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
@@ -209,6 +209,7 @@ extern void nfs4_drop_state_owner(struct nfs4_state_owner *);
extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
extern void nfs4_put_open_state(struct nfs4_state *);
extern void nfs4_close_state(struct path *, struct nfs4_state *, mode_t);
+extern void nfs4_close_sync(struct path *, struct nfs4_state *, mode_t);
extern void nfs4_state_set_mode_locked(struct nfs4_state *, mode_t);
extern void nfs4_schedule_state_recovery(struct nfs_client *);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
@@ -235,6 +236,7 @@ extern struct svc_version nfs4_callback_version1;
#else
#define nfs4_close_state(a, b, c) do { } while (0)
+#define nfs4_close_sync(a, b, c) do { } while (0)
#endif /* CONFIG_NFS_V4 */
#endif /* __LINUX_FS_NFS_NFS4_FS.H */
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index cb99fd90a9a..f03d9d5f5ba 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1305,7 +1305,7 @@ static const struct rpc_call_ops nfs4_close_ops = {
*
* NOTE: Caller must be holding the sp->so_owner semaphore!
*/
-int nfs4_do_close(struct path *path, struct nfs4_state *state)
+int nfs4_do_close(struct path *path, struct nfs4_state *state, int wait)
{
struct nfs_server *server = NFS_SERVER(state->inode);
struct nfs4_closedata *calldata;
@@ -1333,8 +1333,11 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state)
task = rpc_run_task(server->client, RPC_TASK_ASYNC, &nfs4_close_ops, calldata);
if (IS_ERR(task))
return PTR_ERR(task);
+ status = 0;
+ if (wait)
+ status = rpc_wait_for_completion_task(task);
rpc_put_task(task);
- return 0;
+ return status;
out_free_calldata:
kfree(calldata);
out:
@@ -1365,13 +1368,14 @@ static int nfs4_intent_set_file(struct nameidata *nd, struct path *path, struct
}
ret = PTR_ERR(filp);
out_close:
- nfs4_close_state(path, state, nd->intent.open.flags);
+ nfs4_close_sync(path, state, nd->intent.open.flags);
return ret;
}
struct dentry *
nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
{
+ struct dentry *parent;
struct path path = {
.mnt = nd->mnt,
.dentry = dentry,
@@ -1394,6 +1398,9 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
cred = rpcauth_lookupcred(NFS_CLIENT(dir)->cl_auth, 0);
if (IS_ERR(cred))
return (struct dentry *)cred;
+ parent = dentry->d_parent;
+ /* Protect against concurrent sillydeletes */
+ nfs_block_sillyrename(parent);
state = nfs4_do_open(dir, &path, nd->intent.open.flags, &attr, cred);
put_rpccred(cred);
if (IS_ERR(state)) {
@@ -1401,12 +1408,14 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
d_add(dentry, NULL);
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
}
+ nfs_unblock_sillyrename(parent);
return (struct dentry *)state;
}
res = d_add_unique(dentry, igrab(state->inode));
if (res != NULL)
path.dentry = res;
nfs_set_verifier(path.dentry, nfs_save_change_attribute(dir));
+ nfs_unblock_sillyrename(parent);
nfs4_intent_set_file(nd, &path, state);
return res;
}
@@ -1444,7 +1453,7 @@ nfs4_open_revalidate(struct inode *dir, struct dentry *dentry, int openflags, st
nfs4_intent_set_file(nd, &path, state);
return 1;
}
- nfs4_close_state(&path, state, openflags);
+ nfs4_close_sync(&path, state, openflags);
out_drop:
d_drop(dentry);
return 0;
@@ -1898,7 +1907,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
if (status == 0 && (nd->flags & LOOKUP_OPEN) != 0)
status = nfs4_intent_set_file(nd, &path, state);
else
- nfs4_close_state(&path, state, flags);
+ nfs4_close_sync(&path, state, flags);
out:
return status;
}
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index bfb36261cec..23a9a36556b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -425,7 +425,7 @@ void nfs4_put_open_state(struct nfs4_state *state)
/*
* Close the current file.
*/
-void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+static void __nfs4_close(struct path *path, struct nfs4_state *state, mode_t mode, int wait)
{
struct nfs4_state_owner *owner = state->owner;
int call_close = 0;
@@ -466,7 +466,17 @@ void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
nfs4_put_open_state(state);
nfs4_put_state_owner(owner);
} else
- nfs4_do_close(path, state);
+ nfs4_do_close(path, state, wait);
+}
+
+void nfs4_close_state(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+ __nfs4_close(path, state, mode, 0);
+}
+
+void nfs4_close_sync(struct path *path, struct nfs4_state *state, mode_t mode)
+{
+ __nfs4_close(path, state, mode, 1);
}
/*
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index e87b44ee9ac..4b0334590ee 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -43,7 +43,7 @@
* from being used (thanks to Leo Spiekman)
* Andy Walker : Allow to specify the NFS server in nfs_root
* without giving a path name
- * Swen Thmmler : Allow to specify the NFS options in nfs_root
+ * Swen Thümmler : Allow to specify the NFS options in nfs_root
* without giving a path name. Fix BOOTP request
* for domainname (domainname is NIS domain, not
* DNS domain!). Skip dummy devices for BOOTP.
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 97669ed0550..4f80d88e9fe 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -211,6 +211,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
nfs_fattr_init(&fattr);
dprintk("NFS call create %s\n", dentry->d_name.name);
status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+ nfs_mark_for_revalidate(dir);
if (status == 0)
status = nfs_instantiate(dentry, &fhandle, &fattr);
dprintk("NFS reply create: %d\n", status);
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 1aed850d18f..233ad38161f 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -11,9 +11,11 @@
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs_fs.h>
-
+#include <linux/sched.h>
+#include <linux/wait.h>
struct nfs_unlinkdata {
+ struct hlist_node list;
struct nfs_removeargs args;
struct nfs_removeres res;
struct inode *dir;
@@ -52,6 +54,20 @@ static int nfs_copy_dname(struct dentry *dentry, struct nfs_unlinkdata *data)
return 0;
}
+static void nfs_free_dname(struct nfs_unlinkdata *data)
+{
+ kfree(data->args.name.name);
+ data->args.name.name = NULL;
+ data->args.name.len = 0;
+}
+
+static void nfs_dec_sillycount(struct inode *dir)
+{
+ struct nfs_inode *nfsi = NFS_I(dir);
+ if (atomic_dec_return(&nfsi->silly_count) == 1)
+ wake_up(&nfsi->waitqueue);
+}
+
/**
* nfs_async_unlink_init - Initialize the RPC info
* task: rpc_task of the sillydelete
@@ -95,6 +111,8 @@ static void nfs_async_unlink_done(struct rpc_task *task, void *calldata)
static void nfs_async_unlink_release(void *calldata)
{
struct nfs_unlinkdata *data = calldata;
+
+ nfs_dec_sillycount(data->dir);
nfs_free_unlinkdata(data);
}
@@ -104,33 +122,100 @@ static const struct rpc_call_ops nfs_unlink_ops = {
.rpc_release = nfs_async_unlink_release,
};
-static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct nfs_unlinkdata *data)
{
struct rpc_task *task;
+ struct dentry *alias;
+
+ alias = d_lookup(parent, &data->args.name);
+ if (alias != NULL) {
+ int ret = 0;
+ /*
+ * Hey, we raced with lookup... See if we need to transfer
+ * the sillyrename information to the aliased dentry.
+ */
+ nfs_free_dname(data);
+ spin_lock(&alias->d_lock);
+ if (!(alias->d_flags & DCACHE_NFSFS_RENAMED)) {
+ alias->d_fsdata = data;
+ alias->d_flags ^= DCACHE_NFSFS_RENAMED;
+ ret = 1;
+ }
+ spin_unlock(&alias->d_lock);
+ nfs_dec_sillycount(dir);
+ dput(alias);
+ return ret;
+ }
+ data->dir = igrab(dir);
+ if (!data->dir) {
+ nfs_dec_sillycount(dir);
+ return 0;
+ }
+ data->args.fh = NFS_FH(dir);
+ nfs_fattr_init(&data->res.dir_attr);
+
+ task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data);
+ if (!IS_ERR(task))
+ rpc_put_task(task);
+ return 1;
+}
+
+static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
+{
struct dentry *parent;
struct inode *dir;
+ int ret = 0;
- if (nfs_copy_dname(dentry, data) < 0)
- goto out_free;
parent = dget_parent(dentry);
if (parent == NULL)
goto out_free;
- dir = igrab(parent->d_inode);
+ dir = parent->d_inode;
+ if (nfs_copy_dname(dentry, data) != 0)
+ goto out_dput;
+ /* Non-exclusive lock protects against concurrent lookup() calls */
+ spin_lock(&dir->i_lock);
+ if (atomic_inc_not_zero(&NFS_I(dir)->silly_count) == 0) {
+ /* Deferred delete */
+ hlist_add_head(&data->list, &NFS_I(dir)->silly_list);
+ spin_unlock(&dir->i_lock);
+ ret = 1;
+ goto out_dput;
+ }
+ spin_unlock(&dir->i_lock);
+ ret = nfs_do_call_unlink(parent, dir, data);
+out_dput:
dput(parent);
- if (dir == NULL)
- goto out_free;
+out_free:
+ return ret;
+}
- data->dir = dir;
- data->args.fh = NFS_FH(dir);
- nfs_fattr_init(&data->res.dir_attr);
+void nfs_block_sillyrename(struct dentry *dentry)
+{
+ struct nfs_inode *nfsi = NFS_I(dentry->d_inode);
- task = rpc_run_task(NFS_CLIENT(dir), RPC_TASK_ASYNC, &nfs_unlink_ops, data);
- if (!IS_ERR(task))
- rpc_put_task(task);
- return 1;
-out_free:
- return 0;
+ wait_event(nfsi->waitqueue, atomic_cmpxchg(&nfsi->silly_count, 1, 0) == 1);
+}
+
+void nfs_unblock_sillyrename(struct dentry *dentry)
+{
+ struct inode *dir = dentry->d_inode;
+ struct nfs_inode *nfsi = NFS_I(dir);
+ struct nfs_unlinkdata *data;
+
+ atomic_inc(&nfsi->silly_count);
+ spin_lock(&dir->i_lock);
+ while (!hlist_empty(&nfsi->silly_list)) {
+ if (!atomic_inc_not_zero(&nfsi->silly_count))
+ break;
+ data = hlist_entry(nfsi->silly_list.first, struct nfs_unlinkdata, list);
+ hlist_del(&data->list);
+ spin_unlock(&dir->i_lock);
+ if (nfs_do_call_unlink(dentry, dir, data) == 0)
+ nfs_free_unlinkdata(data);
+ spin_lock(&dir->i_lock);
+ }
+ spin_unlock(&dir->i_lock);
}
/**
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 0cf9d1cd9bd..89527a487ed 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -174,8 +174,6 @@ static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int
return;
if (count != nfs_page_length(page))
return;
- if (count != PAGE_CACHE_SIZE)
- zero_user_page(page, count, PAGE_CACHE_SIZE - count, KM_USER0);
SetPageUptodate(page);
}
@@ -627,7 +625,8 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
return ERR_PTR(error);
}
spin_unlock(&inode->i_lock);
- return new;
+ req = new;
+ goto zero_page;
}
spin_unlock(&inode->i_lock);
@@ -655,13 +654,23 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
if (offset < req->wb_offset) {
req->wb_offset = offset;
req->wb_pgbase = offset;
- req->wb_bytes = rqend - req->wb_offset;
+ req->wb_bytes = max(end, rqend) - req->wb_offset;
+ goto zero_page;
}
if (end > rqend)
req->wb_bytes = end - req->wb_offset;
return req;
+zero_page:
+ /* If this page might potentially be marked as up to date,
+ * then we need to zero any uninitalised data. */
+ if (req->wb_pgbase == 0 && req->wb_bytes != PAGE_CACHE_SIZE
+ && !PageUptodate(req->wb_page))
+ zero_user_page(req->wb_page, req->wb_bytes,
+ PAGE_CACHE_SIZE - req->wb_bytes,
+ KM_USER0);
+ return req;
}
int nfs_flush_incompatible(struct file *file, struct page *page)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 04b26672980..66d0aeb32a4 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -386,15 +386,13 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
dprintk("exp_export: export of non-dev fs without fsid\n");
return -EINVAL;
}
- if (!inode->i_sb->s_export_op) {
+
+ if (!inode->i_sb->s_export_op ||
+ !inode->i_sb->s_export_op->fh_to_dentry) {
dprintk("exp_export: export of invalid fs type.\n");
return -EINVAL;
}
- /* Ok, we can export it */;
- if (!inode->i_sb->s_export_op->find_exported_dentry)
- inode->i_sb->s_export_op->find_exported_dentry =
- find_exported_dentry;
return 0;
}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc0747..6f03918018a 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
{
struct xdr_netobj cksum;
struct hash_desc desc;
- struct scatterlist sg[1];
+ struct scatterlist sg;
__be32 status = nfserr_resource;
dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
if (cksum.data == NULL)
goto out;
- sg[0].page = virt_to_page(clname->data);
- sg[0].offset = offset_in_page(clname->data);
- sg[0].length = clname->len;
+ sg_init_one(&sg, clname->data, clname->len);
- if (crypto_hash_digest(&desc, sg, sg->length, cksum.data))
+ if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
goto out;
md5_to_hex(dname, cksum.data);
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 7011d62acfc..4f712e97058 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
if (!fhp->fh_dentry) {
- __u32 *datap=NULL;
- __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
+ struct fid *fid = NULL, sfid;
int fileid_type;
int data_left = fh->fh_size/4;
@@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
if (fh->fh_version == 1) {
int len;
- datap = fh->fh_auth;
if (--data_left<0) goto out;
switch (fh->fh_auth_type) {
case 0: break;
@@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
fh->fh_fsid[1] = fh->fh_fsid[2];
}
if ((data_left -= len)<0) goto out;
- exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap);
- datap += len;
+ exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
+ fh->fh_auth);
+ fid = (struct fid *)(fh->fh_auth + len);
} else {
+ __u32 tfh[2];
dev_t xdev;
ino_t xino;
if (fh->fh_size != NFS_FHSIZE)
@@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
error = nfserr_badhandle;
if (fh->fh_version != 1) {
- tfh[0] = fh->ofh_ino;
- tfh[1] = fh->ofh_generation;
- tfh[2] = fh->ofh_dirino;
- datap = tfh;
+ sfid.i32.ino = fh->ofh_ino;
+ sfid.i32.gen = fh->ofh_generation;
+ sfid.i32.parent_ino = fh->ofh_dirino;
+ fid = &sfid;
data_left = 3;
if (fh->ofh_dirino == 0)
- fileid_type = 1;
+ fileid_type = FILEID_INO32_GEN;
else
- fileid_type = 2;
+ fileid_type = FILEID_INO32_GEN_PARENT;
} else
fileid_type = fh->fh_fileid_type;
- if (fileid_type == 0)
+ if (fileid_type == FILEID_ROOT)
dentry = dget(exp->ex_dentry);
else {
- dentry = exportfs_decode_fh(exp->ex_mnt, datap,
+ dentry = exportfs_decode_fh(exp->ex_mnt, fid,
data_left, fileid_type,
nfsd_acceptable, exp);
}
@@ -286,16 +286,21 @@ out:
* an inode. In this case a call to fh_update should be made
* before the fh goes out on the wire ...
*/
-static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
- __u32 *datap, int *maxsize)
+static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
+ struct dentry *dentry)
{
- if (dentry == exp->ex_dentry) {
- *maxsize = 0;
- return 0;
- }
+ if (dentry != exp->ex_dentry) {
+ struct fid *fid = (struct fid *)
+ (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
+ int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
+ int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
- return exportfs_encode_fh(dentry, datap, maxsize,
- !(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
+ fhp->fh_handle.fh_fileid_type =
+ exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
+ fhp->fh_handle.fh_size += maxsize * 4;
+ } else {
+ fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
+ }
}
/*
@@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
datap += len/4;
fhp->fh_handle.fh_size = 4 + len;
- if (inode) {
- int size = (fhp->fh_maxsize-len-4)/4;
- fhp->fh_handle.fh_fileid_type =
- _fh_update(dentry, exp, datap, &size);
- fhp->fh_handle.fh_size += size*4;
- }
+ if (inode)
+ _fh_update(fhp, exp, dentry);
if (fhp->fh_handle.fh_fileid_type == 255)
return nfserr_opnotsupp;
}
@@ -479,7 +480,6 @@ __be32
fh_update(struct svc_fh *fhp)
{
struct dentry *dentry;
- __u32 *datap;
if (!fhp->fh_dentry)
goto out_bad;
@@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp)
if (fhp->fh_handle.fh_version != 1) {
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
} else {
- int size;
- if (fhp->fh_handle.fh_fileid_type != 0)
+ if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
goto out;
- datap = fhp->fh_handle.fh_auth+
- fhp->fh_handle.fh_size/4 -1;
- size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
- fhp->fh_handle.fh_fileid_type =
- _fh_update(dentry, fhp->fh_export, datap, &size);
- fhp->fh_handle.fh_size += size*4;
+
+ _fh_update(fhp, fhp->fh_export, dentry);
if (fhp->fh_handle.fh_fileid_type == 255)
return nfserr_opnotsupp;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 46934c97f8f..d0199189924 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1029,13 +1029,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
if (EX_WGATHER(exp)) {
if (atomic_read(&inode->i_writecount) > 1
|| (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) {
- dprintk("nfsd: write defer %d\n", current->pid);
+ dprintk("nfsd: write defer %d\n", task_pid_nr(current));
msleep(10);
- dprintk("nfsd: write resume %d\n", current->pid);
+ dprintk("nfsd: write resume %d\n", task_pid_nr(current));
}
if (inode->i_state & I_DIRTY) {
- dprintk("nfsd: write sync %d\n", current->pid);
+ dprintk("nfsd: write sync %d\n", task_pid_nr(current));
host_err=nfsd_sync(file);
}
#if 0
diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
index 345798ebd36..37c11e19437 100644
--- a/fs/ntfs/ChangeLog
+++ b/fs/ntfs/ChangeLog
@@ -382,7 +382,7 @@ ToDo/Notes:
own locking so it does not matter if the vfs inode is locked.
- Fix bug in mft record writing where we forgot to set the device in
the buffers when mapping them after the VM had discarded them.
- Thanks to Martin MOKREJŠ for the bug report.
+ Thanks to Martin MOKREJÅ for the bug report.
2.1.22 - Many bug and race fixes and error handling improvements.
@@ -1585,7 +1585,7 @@ tng-0.0.4 - Big changes, getting in line with Al Viro's comments.
for reading $MFT (ntfs_mft_readpage). In the process create dedicated
address space operations (ntfs_mft_aops) for $MFT inode mapping. Also
removed the now superfluous exports from the kernel core patch.
- - Fix a bug where kfree() was used insted of ntfs_free().
+ - Fix a bug where kfree() was used instead of ntfs_free().
- Change map_mft_record() to take ntfs_inode as argument instead of
vfs inode. Dito for unmap_mft_record(). Adapt all callers.
- Add pointer to ntfs_volume to ntfs_inode.
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index e93c6142b23..e1781c8b165 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -450,58 +450,40 @@ try_next:
return parent_dent;
}
-/**
- * ntfs_get_dentry - find a dentry for the inode from a file handle sub-fragment
- * @sb: super block identifying the mounted ntfs volume
- * @fh: the file handle sub-fragment
- *
- * Find a dentry for the inode given a file handle sub-fragment. This function
- * is called from fs/exportfs/expfs.c::find_exported_dentry() which in turn is
- * called from the default ->decode_fh() which is export_decode_fh() in the
- * same file. The code is closely based on the default ->get_dentry() helper
- * fs/exportfs/expfs.c::get_object().
- *
- * The @fh contains two 32-bit unsigned values, the first one is the inode
- * number and the second one is the inode generation.
- *
- * Return the dentry on success or the error code on error (IS_ERR() is true).
- */
-static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
+static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
+ u64 ino, u32 generation)
{
- struct inode *vi;
- struct dentry *dent;
- unsigned long ino = ((u32 *)fh)[0];
- u32 gen = ((u32 *)fh)[1];
+ struct inode *inode;
- ntfs_debug("Entering for inode 0x%lx, generation 0x%x.", ino, gen);
- vi = ntfs_iget(sb, ino);
- if (IS_ERR(vi)) {
- ntfs_error(sb, "Failed to get inode 0x%lx.", ino);
- return (struct dentry *)vi;
- }
- if (unlikely(is_bad_inode(vi) || vi->i_generation != gen)) {
- /* We didn't find the right inode. */
- ntfs_error(sb, "Inode 0x%lx, bad count: %d %d or version 0x%x "
- "0x%x.", vi->i_ino, vi->i_nlink,
- atomic_read(&vi->i_count), vi->i_generation,
- gen);
- iput(vi);
- return ERR_PTR(-ESTALE);
- }
- /* Now find a dentry. If possible, get a well-connected one. */
- dent = d_alloc_anon(vi);
- if (unlikely(!dent)) {
- iput(vi);
- return ERR_PTR(-ENOMEM);
+ inode = ntfs_iget(sb, ino);
+ if (!IS_ERR(inode)) {
+ if (is_bad_inode(inode) || inode->i_generation != generation) {
+ iput(inode);
+ inode = ERR_PTR(-ESTALE);
+ }
}
- ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);
- return dent;
+
+ return inode;
+}
+
+static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
+ ntfs_nfs_get_inode);
+}
+
+static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ return generic_fh_to_parent(sb, fid, fh_len, fh_type,
+ ntfs_nfs_get_inode);
}
/**
* Export operations allowing NFS exporting of mounted NTFS partitions.
*
- * We use the default ->decode_fh() and ->encode_fh() for now. Note that they
+ * We use the default ->encode_fh() for now. Note that they
* use 32 bits to store the inode number which is an unsigned long so on 64-bit
* architectures is usually 64 bits so it would all fail horribly on huge
* volumes. I guess we need to define our own encode and decode fh functions
@@ -517,10 +499,9 @@ static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
* allowing the inode number 0 which is used in NTFS for the system file $MFT
* and due to using iget() whereas NTFS needs ntfs_iget().
*/
-struct export_operations ntfs_export_ops = {
+const struct export_operations ntfs_export_ops = {
.get_parent = ntfs_get_parent, /* Find the parent of a given
directory. */
- .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode
- given a file handle
- sub-fragment. */
+ .fh_to_dentry = ntfs_fh_to_dentry,
+ .fh_to_parent = ntfs_fh_to_parent,
};
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index d73f5a9ac34..d6a340bf80f 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -69,7 +69,7 @@ extern const struct inode_operations ntfs_dir_inode_ops;
extern const struct file_operations ntfs_empty_file_ops;
extern const struct inode_operations ntfs_empty_inode_ops;
-extern struct export_operations ntfs_export_ops;
+extern const struct export_operations ntfs_export_ops;
/**
* NTFS_SB - return the ntfs volume given a vfs super block
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
index 4847fbfb010..9ef85e628fe 100644
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -1,7 +1,7 @@
/*
* sysctl.c - Code for sysctl handling in NTFS Linux kernel driver. Part of
* the Linux-NTFS project. Adapted from the old NTFS driver,
- * Copyright (C) 1997 Martin von Lwis, Rgis Duchesne
+ * Copyright (C) 1997 Martin von Löwis, Régis Duchesne
*
* Copyright (c) 2002-2005 Anton Altaparmakov
*
diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h
index beda5bf9640..d4f8ce920d9 100644
--- a/fs/ntfs/sysctl.h
+++ b/fs/ntfs/sysctl.h
@@ -1,7 +1,7 @@
/*
* sysctl.h - Defines for sysctl handling in NTFS Linux kernel driver. Part of
* the Linux-NTFS project. Adapted from the old NTFS driver,
- * Copyright (C) 1997 Martin von Lwis, Rgis Duchesne
+ * Copyright (C) 1997 Martin von Löwis, Régis Duchesne
*
* Copyright (c) 2002-2004 Anton Altaparmakov
*
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index f14b541fab9..9cc7c0418b7 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1372,7 +1372,7 @@ static ssize_t o2hb_region_pid_read(struct o2hb_region *reg,
spin_lock(&o2hb_live_lock);
if (reg->hr_task)
- pid = reg->hr_task->pid;
+ pid = task_pid_nr(reg->hr_task);
spin_unlock(&o2hb_live_lock);
if (!pid)
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 75cd877f6d4..cd046060114 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -192,7 +192,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
* previous token if args expands to nothing.
*/
#define __mlog_printk(level, fmt, args...) \
- printk(level "(%u,%lu):%s:%d " fmt, current->pid, \
+ printk(level "(%u,%lu):%s:%d " fmt, task_pid_nr(current), \
__mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ , \
##args)
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 014e73978da..3094ddb7a25 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -376,7 +376,7 @@ out:
* directory locks. The dentries have already been deleted on other
* nodes via ocfs2_remote_dentry_delete().
*
- * Normally, the VFS handles the d_move() for the file sytem, after
+ * Normally, the VFS handles the d_move() for the file system, after
* the ->rename() callback. OCFS2 wants to handle this internally, so
* the new lock can be created atomically with respect to the cluster.
*/
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index a2c33160bfd..2fde7bf9143 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -259,7 +259,7 @@ static void dlm_print_reco_node_status(struct dlm_ctxt *dlm)
struct dlm_lock_resource *res;
mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n",
- dlm->name, dlm->dlm_reco_thread_task->pid,
+ dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive",
dlm->reco.dead_node, dlm->reco.new_master);
@@ -420,7 +420,7 @@ void dlm_wait_for_recovery(struct dlm_ctxt *dlm)
if (dlm_in_recovery(dlm)) {
mlog(0, "%s: reco thread %d in recovery: "
"state=%d, master=%u, dead=%u\n",
- dlm->name, dlm->dlm_reco_thread_task->pid,
+ dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
dlm->reco.state, dlm->reco.new_master,
dlm->reco.dead_node);
}
@@ -483,7 +483,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
return 0;
}
mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n",
- dlm->name, dlm->dlm_reco_thread_task->pid,
+ dlm->name, task_pid_nr(dlm->dlm_reco_thread_task),
dlm->reco.dead_node);
spin_unlock(&dlm->spinlock);
@@ -507,7 +507,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
mlog(0, "another node will master this recovery session.\n");
}
mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n",
- dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.new_master,
+ dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master,
dlm->node_num, dlm->reco.dead_node);
/* it is safe to start everything back up here
@@ -520,7 +520,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
master_here:
mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n",
- dlm->dlm_reco_thread_task->pid,
+ task_pid_nr(dlm->dlm_reco_thread_task),
dlm->name, dlm->reco.dead_node, dlm->node_num);
status = dlm_remaster_locks(dlm, dlm->reco.dead_node);
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index c3bbc198f9c..535bfa9568a 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -45,9 +45,9 @@ struct ocfs2_inode_handle
u32 ih_generation;
};
-static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *ocfs2_get_dentry(struct super_block *sb,
+ struct ocfs2_inode_handle *handle)
{
- struct ocfs2_inode_handle *handle = vobjp;
struct inode *inode;
struct dentry *result;
@@ -194,54 +194,37 @@ bail:
return type;
}
-static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in,
- int fh_len, int fileid_type,
- int (*acceptable)(void *context,
- struct dentry *de),
- void *context)
+static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
{
- struct ocfs2_inode_handle handle, parent;
- struct dentry *ret = NULL;
- __le32 *fh = (__force __le32 *) fh_in;
-
- mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
- sb, fh, fh_len, fileid_type, acceptable, context);
-
- if (fh_len < 3 || fileid_type > 2)
- goto bail;
-
- if (fileid_type == 2) {
- if (fh_len < 6)
- goto bail;
-
- parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
- parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
- parent.ih_generation = le32_to_cpu(fh[5]);
+ struct ocfs2_inode_handle handle;
- mlog(0, "Decoding parent: blkno: %llu, generation: %u\n",
- (unsigned long long)parent.ih_blkno,
- parent.ih_generation);
- }
+ if (fh_len < 3 || fh_type > 2)
+ return NULL;
- handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32;
- handle.ih_blkno |= (u64)le32_to_cpu(fh[1]);
- handle.ih_generation = le32_to_cpu(fh[2]);
+ handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
+ handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
+ handle.ih_generation = le32_to_cpu(fid->raw[2]);
+ return ocfs2_get_dentry(sb, &handle);
+}
- mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
- (unsigned long long)handle.ih_blkno, handle.ih_generation);
+static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
+{
+ struct ocfs2_inode_handle parent;
- ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent,
- acceptable, context);
+ if (fh_type != 2 || fh_len < 6)
+ return NULL;
-bail:
- mlog_exit_ptr(ret);
- return ret;
+ parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
+ parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
+ parent.ih_generation = le32_to_cpu(fid->raw[5]);
+ return ocfs2_get_dentry(sb, &parent);
}
-struct export_operations ocfs2_export_ops = {
- .decode_fh = ocfs2_decode_fh,
+const struct export_operations ocfs2_export_ops = {
.encode_fh = ocfs2_encode_fh,
-
+ .fh_to_dentry = ocfs2_fh_to_dentry,
+ .fh_to_parent = ocfs2_fh_to_parent,
.get_parent = ocfs2_get_parent,
- .get_dentry = ocfs2_get_dentry,
};
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
index e08bed9e45a..41a738678c3 100644
--- a/fs/ocfs2/export.h
+++ b/fs/ocfs2/export.h
@@ -28,6 +28,6 @@
#include <linux/exportfs.h>
-extern struct export_operations ocfs2_export_ops;
+extern const struct export_operations ocfs2_export_ops;
#endif /* OCFS2_EXPORT_H */
diff --git a/fs/open.c b/fs/open.c
index 75385144df7..3b69c53e183 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
dentry = file->f_path.dentry;
inode = dentry->d_inode;
- audit_inode(NULL, inode);
+ audit_inode(NULL, dentry);
err = -EROFS;
if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
goto out;
dentry = file->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = chown_common(dentry, user, group);
fput(file);
out:
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8ec36b..f249be2fee7 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
#define CL_COPY_ALL 0x04
#define CL_MAKE_SHARED 0x08
#define CL_PROPAGATION 0x10
+#define CL_PRIVATE 0x20
static inline void set_mnt_shared(struct vfsmount *mnt)
{
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 27b59f5f3bd..63c95afb561 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -77,6 +77,7 @@
#include <linux/cpuset.h>
#include <linux/rcupdate.h>
#include <linux/delayacct.h>
+#include <linux/pid_namespace.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -145,8 +146,7 @@ static inline const char *get_task_state(struct task_struct *tsk)
TASK_UNINTERRUPTIBLE |
TASK_STOPPED |
TASK_TRACED)) |
- (tsk->exit_state & (EXIT_ZOMBIE |
- EXIT_DEAD));
+ tsk->exit_state;
const char **p = &task_state_array[0];
while (state) {
@@ -161,8 +161,15 @@ static inline char *task_state(struct task_struct *p, char *buffer)
struct group_info *group_info;
int g;
struct fdtable *fdt = NULL;
+ struct pid_namespace *ns;
+ pid_t ppid, tpid;
+ ns = current->nsproxy->pid_ns;
rcu_read_lock();
+ ppid = pid_alive(p) ?
+ task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
+ tpid = pid_alive(p) && p->ptrace ?
+ task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0;
buffer += sprintf(buffer,
"State:\t%s\n"
"Tgid:\t%d\n"
@@ -172,9 +179,9 @@ static inline char *task_state(struct task_struct *p, char *buffer)
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
- p->tgid, p->pid,
- pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0,
- pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0,
+ task_tgid_nr_ns(p, ns),
+ task_pid_nr_ns(p, ns),
+ ppid, tpid,
p->uid, p->euid, p->suid, p->fsuid,
p->gid, p->egid, p->sgid, p->fsgid);
@@ -394,6 +401,9 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
unsigned long rsslim = 0;
char tcomm[sizeof(task->comm)];
unsigned long flags;
+ struct pid_namespace *ns;
+
+ ns = current->nsproxy->pid_ns;
state = *get_task_state(task);
vsize = eip = esp = 0;
@@ -416,7 +426,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
struct signal_struct *sig = task->signal;
if (sig->tty) {
- tty_pgrp = pid_nr(sig->tty->pgrp);
+ tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns);
tty_nr = new_encode_dev(tty_devnum(sig->tty));
}
@@ -446,12 +456,12 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
maj_flt += sig->maj_flt;
utime = cputime_add(utime, sig->utime);
stime = cputime_add(stime, sig->stime);
- gtime += cputime_add(gtime, sig->gtime);
+ gtime = cputime_add(gtime, sig->gtime);
}
- sid = signal_session(sig);
- pgid = process_group(task);
- ppid = rcu_dereference(task->real_parent)->tgid;
+ sid = task_session_nr_ns(task, ns);
+ pgid = task_pgrp_nr_ns(task, ns);
+ ppid = task_ppid_nr_ns(task, ns);
unlock_task_sighand(task, &flags);
}
@@ -483,7 +493,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole)
res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
- task->pid,
+ task_pid_nr_ns(task, ns),
tcomm,
state,
ppid,
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 4fe74d15641..aeaf0d0f2f5 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -63,16 +63,19 @@
#include <linux/mm.h>
#include <linux/rcupdate.h>
#include <linux/kallsyms.h>
+#include <linux/resource.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/security.h>
#include <linux/ptrace.h>
+#include <linux/cgroup.h>
#include <linux/cpuset.h>
#include <linux/audit.h>
#include <linux/poll.h>
#include <linux/nsproxy.h>
#include <linux/oom.h>
#include <linux/elf.h>
+#include <linux/pid_namespace.h>
#include "internal.h"
/* NOTE:
@@ -301,6 +304,78 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
return sprintf(buffer, "%lu\n", points);
}
+struct limit_names {
+ char *name;
+ char *unit;
+};
+
+static const struct limit_names lnames[RLIM_NLIMITS] = {
+ [RLIMIT_CPU] = {"Max cpu time", "ms"},
+ [RLIMIT_FSIZE] = {"Max file size", "bytes"},
+ [RLIMIT_DATA] = {"Max data size", "bytes"},
+ [RLIMIT_STACK] = {"Max stack size", "bytes"},
+ [RLIMIT_CORE] = {"Max core file size", "bytes"},
+ [RLIMIT_RSS] = {"Max resident set", "bytes"},
+ [RLIMIT_NPROC] = {"Max processes", "processes"},
+ [RLIMIT_NOFILE] = {"Max open files", "files"},
+ [RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"},
+ [RLIMIT_AS] = {"Max address space", "bytes"},
+ [RLIMIT_LOCKS] = {"Max file locks", "locks"},
+ [RLIMIT_SIGPENDING] = {"Max pending signals", "signals"},
+ [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"},
+ [RLIMIT_NICE] = {"Max nice priority", NULL},
+ [RLIMIT_RTPRIO] = {"Max realtime priority", NULL},
+};
+
+/* Display limits for a process */
+static int proc_pid_limits(struct task_struct *task, char *buffer)
+{
+ unsigned int i;
+ int count = 0;
+ unsigned long flags;
+ char *bufptr = buffer;
+
+ struct rlimit rlim[RLIM_NLIMITS];
+
+ rcu_read_lock();
+ if (!lock_task_sighand(task,&flags)) {
+ rcu_read_unlock();
+ return 0;
+ }
+ memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS);
+ unlock_task_sighand(task, &flags);
+ rcu_read_unlock();
+
+ /*
+ * print the file header
+ */
+ count += sprintf(&bufptr[count], "%-25s %-20s %-20s %-10s\n",
+ "Limit", "Soft Limit", "Hard Limit", "Units");
+
+ for (i = 0; i < RLIM_NLIMITS; i++) {
+ if (rlim[i].rlim_cur == RLIM_INFINITY)
+ count += sprintf(&bufptr[count], "%-25s %-20s ",
+ lnames[i].name, "unlimited");
+ else
+ count += sprintf(&bufptr[count], "%-25s %-20lu ",
+ lnames[i].name, rlim[i].rlim_cur);
+
+ if (rlim[i].rlim_max == RLIM_INFINITY)
+ count += sprintf(&bufptr[count], "%-20s ", "unlimited");
+ else
+ count += sprintf(&bufptr[count], "%-20lu ",
+ rlim[i].rlim_max);
+
+ if (lnames[i].unit)
+ count += sprintf(&bufptr[count], "%-10s\n",
+ lnames[i].unit);
+ else
+ count += sprintf(&bufptr[count], "\n");
+ }
+
+ return count;
+}
+
/************************************************************************/
/* Here the fs part begins */
/************************************************************************/
@@ -349,18 +424,21 @@ struct proc_mounts {
static int mounts_open(struct inode *inode, struct file *file)
{
struct task_struct *task = get_proc_task(inode);
+ struct nsproxy *nsp;
struct mnt_namespace *ns = NULL;
struct proc_mounts *p;
int ret = -EINVAL;
if (task) {
- task_lock(task);
- if (task->nsproxy) {
- ns = task->nsproxy->mnt_ns;
+ rcu_read_lock();
+ nsp = task_nsproxy(task);
+ if (nsp) {
+ ns = nsp->mnt_ns;
if (ns)
get_mnt_ns(ns);
}
- task_unlock(task);
+ rcu_read_unlock();
+
put_task_struct(task);
}
@@ -423,16 +501,20 @@ static int mountstats_open(struct inode *inode, struct file *file)
if (!ret) {
struct seq_file *m = file->private_data;
+ struct nsproxy *nsp;
struct mnt_namespace *mnt_ns = NULL;
struct task_struct *task = get_proc_task(inode);
if (task) {
- task_lock(task);
- if (task->nsproxy)
- mnt_ns = task->nsproxy->mnt_ns;
- if (mnt_ns)
- get_mnt_ns(mnt_ns);
- task_unlock(task);
+ rcu_read_lock();
+ nsp = task_nsproxy(task);
+ if (nsp) {
+ mnt_ns = nsp->mnt_ns;
+ if (mnt_ns)
+ get_mnt_ns(mnt_ns);
+ }
+ rcu_read_unlock();
+
put_task_struct(task);
}
@@ -1437,7 +1519,7 @@ static int proc_readfd_common(struct file * filp, void * dirent,
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *p = get_proc_task(inode);
- unsigned int fd, tid, ino;
+ unsigned int fd, ino;
int retval;
struct files_struct * files;
struct fdtable *fdt;
@@ -1446,7 +1528,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
if (!p)
goto out_no_task;
retval = 0;
- tid = p->pid;
fd = filp->f_pos;
switch (fd) {
@@ -1681,7 +1762,6 @@ static int proc_pident_readdir(struct file *filp,
const struct pid_entry *ents, unsigned int nents)
{
int i;
- int pid;
struct dentry *dentry = filp->f_path.dentry;
struct inode *inode = dentry->d_inode;
struct task_struct *task = get_proc_task(inode);
@@ -1694,7 +1774,6 @@ static int proc_pident_readdir(struct file *filp,
goto out_no_task;
ret = 0;
- pid = task->pid;
i = filp->f_pos;
switch (i) {
case 0:
@@ -1928,14 +2007,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
int buflen)
{
char tmp[PROC_NUMBUF];
- sprintf(tmp, "%d", current->tgid);
+ sprintf(tmp, "%d", task_tgid_vnr(current));
return vfs_readlink(dentry,buffer,buflen,tmp);
}
static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
{
char tmp[PROC_NUMBUF];
- sprintf(tmp, "%d", current->tgid);
+ sprintf(tmp, "%d", task_tgid_vnr(current));
return ERR_PTR(vfs_follow_link(nd,tmp));
}
@@ -2101,6 +2180,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
+ INF("limits", S_IRUSR, pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, pid_sched),
#endif
@@ -2130,9 +2210,12 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SCHEDSTATS
INF("schedstat", S_IRUGO, pid_schedstat),
#endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
REG("cpuset", S_IRUGO, cpuset),
#endif
+#ifdef CONFIG_CGROUPS
+ REG("cgroup", S_IRUGO, cgroup),
+#endif
INF("oom_score", S_IRUGO, oom_score),
REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
#ifdef CONFIG_AUDITSYSCALL
@@ -2172,48 +2255,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
.setattr = proc_setattr,
};
-/**
- * proc_flush_task - Remove dcache entries for @task from the /proc dcache.
- *
- * @task: task that should be flushed.
- *
- * Looks in the dcache for
- * /proc/@pid
- * /proc/@tgid/task/@pid
- * if either directory is present flushes it and all of it'ts children
- * from the dcache.
- *
- * It is safe and reasonable to cache /proc entries for a task until
- * that task exits. After that they just clog up the dcache with
- * useless entries, possibly causing useful dcache entries to be
- * flushed instead. This routine is proved to flush those useless
- * dcache entries at process exit time.
- *
- * NOTE: This routine is just an optimization so it does not guarantee
- * that no dcache entries will exist at process exit time it
- * just makes it very unlikely that any will persist.
- */
-void proc_flush_task(struct task_struct *task)
+static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
{
struct dentry *dentry, *leader, *dir;
char buf[PROC_NUMBUF];
struct qstr name;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
- dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name);
+ name.len = snprintf(buf, sizeof(buf), "%d", pid);
+ dentry = d_hash_and_lookup(mnt->mnt_root, &name);
if (dentry) {
shrink_dcache_parent(dentry);
d_drop(dentry);
dput(dentry);
}
- if (thread_group_leader(task))
+ if (tgid == 0)
goto out;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", task->tgid);
- leader = d_hash_and_lookup(proc_mnt->mnt_root, &name);
+ name.len = snprintf(buf, sizeof(buf), "%d", tgid);
+ leader = d_hash_and_lookup(mnt->mnt_root, &name);
if (!leader)
goto out;
@@ -2224,7 +2286,7 @@ void proc_flush_task(struct task_struct *task)
goto out_put_leader;
name.name = buf;
- name.len = snprintf(buf, sizeof(buf), "%d", task->pid);
+ name.len = snprintf(buf, sizeof(buf), "%d", pid);
dentry = d_hash_and_lookup(dir, &name);
if (dentry) {
shrink_dcache_parent(dentry);
@@ -2239,6 +2301,55 @@ out:
return;
}
+/**
+ * proc_flush_task - Remove dcache entries for @task from the /proc dcache.
+ * @task: task that should be flushed.
+ *
+ * When flushing dentries from proc, one needs to flush them from global
+ * proc (proc_mnt) and from all the namespaces' procs this task was seen
+ * in. This call is supposed to do all of this job.
+ *
+ * Looks in the dcache for
+ * /proc/@pid
+ * /proc/@tgid/task/@pid
+ * if either directory is present flushes it and all of it'ts children
+ * from the dcache.
+ *
+ * It is safe and reasonable to cache /proc entries for a task until
+ * that task exits. After that they just clog up the dcache with
+ * useless entries, possibly causing useful dcache entries to be
+ * flushed instead. This routine is proved to flush those useless
+ * dcache entries at process exit time.
+ *
+ * NOTE: This routine is just an optimization so it does not guarantee
+ * that no dcache entries will exist at process exit time it
+ * just makes it very unlikely that any will persist.
+ */
+
+void proc_flush_task(struct task_struct *task)
+{
+ int i, leader;
+ struct pid *pid, *tgid;
+ struct upid *upid;
+
+ leader = thread_group_leader(task);
+ proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0);
+ pid = task_pid(task);
+ if (pid->level == 0)
+ return;
+
+ tgid = task_tgid(task);
+ for (i = 1; i <= pid->level; i++) {
+ upid = &pid->numbers[i];
+ proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr,
+ leader ? 0 : tgid->numbers[i].nr);
+ }
+
+ upid = &pid->numbers[pid->level];
+ if (upid->nr == 1)
+ pid_ns_release_proc(upid->ns);
+}
+
static struct dentry *proc_pid_instantiate(struct inode *dir,
struct dentry * dentry,
struct task_struct *task, const void *ptr)
@@ -2274,6 +2385,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
struct dentry *result = ERR_PTR(-ENOENT);
struct task_struct *task;
unsigned tgid;
+ struct pid_namespace *ns;
result = proc_base_lookup(dir, dentry);
if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
@@ -2283,8 +2395,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
if (tgid == ~0U)
goto out;
+ ns = dentry->d_sb->s_fs_info;
rcu_read_lock();
- task = find_task_by_pid(tgid);
+ task = find_task_by_pid_ns(tgid, ns);
if (task)
get_task_struct(task);
rcu_read_unlock();
@@ -2301,7 +2414,8 @@ out:
* Find the first task with tgid >= tgid
*
*/
-static struct task_struct *next_tgid(unsigned int tgid)
+static struct task_struct *next_tgid(unsigned int tgid,
+ struct pid_namespace *ns)
{
struct task_struct *task;
struct pid *pid;
@@ -2309,9 +2423,9 @@ static struct task_struct *next_tgid(unsigned int tgid)
rcu_read_lock();
retry:
task = NULL;
- pid = find_ge_pid(tgid);
+ pid = find_ge_pid(tgid, ns);
if (pid) {
- tgid = pid->nr + 1;
+ tgid = pid_nr_ns(pid, ns) + 1;
task = pid_task(pid, PIDTYPE_PID);
/* What we to know is if the pid we have find is the
* pid of a thread_group_leader. Testing for task
@@ -2351,6 +2465,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
struct task_struct *task;
int tgid;
+ struct pid_namespace *ns;
if (!reaper)
goto out_no_task;
@@ -2361,11 +2476,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
goto out;
}
+ ns = filp->f_dentry->d_sb->s_fs_info;
tgid = filp->f_pos - TGID_OFFSET;
- for (task = next_tgid(tgid);
+ for (task = next_tgid(tgid, ns);
task;
- put_task_struct(task), task = next_tgid(tgid + 1)) {
- tgid = task->pid;
+ put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
+ tgid = task_pid_nr_ns(task, ns);
filp->f_pos = tgid + TGID_OFFSET;
if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
put_task_struct(task);
@@ -2388,6 +2504,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("environ", S_IRUSR, environ),
INF("auxv", S_IRUSR, pid_auxv),
INF("status", S_IRUGO, pid_status),
+ INF("limits", S_IRUSR, pid_limits),
#ifdef CONFIG_SCHED_DEBUG
REG("sched", S_IRUGO|S_IWUSR, pid_sched),
#endif
@@ -2416,9 +2533,12 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SCHEDSTATS
INF("schedstat", S_IRUGO, pid_schedstat),
#endif
-#ifdef CONFIG_CPUSETS
+#ifdef CONFIG_PROC_PID_CPUSET
REG("cpuset", S_IRUGO, cpuset),
#endif
+#ifdef CONFIG_CGROUPS
+ REG("cgroup", S_IRUGO, cgroup),
+#endif
INF("oom_score", S_IRUGO, oom_score),
REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust),
#ifdef CONFIG_AUDITSYSCALL
@@ -2486,6 +2606,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
struct task_struct *task;
struct task_struct *leader = get_proc_task(dir);
unsigned tid;
+ struct pid_namespace *ns;
if (!leader)
goto out_no_task;
@@ -2494,14 +2615,15 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
if (tid == ~0U)
goto out;
+ ns = dentry->d_sb->s_fs_info;
rcu_read_lock();
- task = find_task_by_pid(tid);
+ task = find_task_by_pid_ns(tid, ns);
if (task)
get_task_struct(task);
rcu_read_unlock();
if (!task)
goto out;
- if (leader->tgid != task->tgid)
+ if (!same_thread_group(leader, task))
goto out_drop_task;
result = proc_task_instantiate(dir, dentry, task, NULL);
@@ -2526,14 +2648,14 @@ out_no_task:
* threads past it.
*/
static struct task_struct *first_tid(struct task_struct *leader,
- int tid, int nr)
+ int tid, int nr, struct pid_namespace *ns)
{
struct task_struct *pos;
rcu_read_lock();
/* Attempt to start with the pid of a thread */
if (tid && (nr > 0)) {
- pos = find_task_by_pid(tid);
+ pos = find_task_by_pid_ns(tid, ns);
if (pos && (pos->group_leader == leader))
goto found;
}
@@ -2602,6 +2724,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
ino_t ino;
int tid;
unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */
+ struct pid_namespace *ns;
task = get_proc_task(inode);
if (!task)
@@ -2635,12 +2758,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
/* f_version caches the tgid value that the last readdir call couldn't
* return. lseek aka telldir automagically resets f_version to 0.
*/
+ ns = filp->f_dentry->d_sb->s_fs_info;
tid = (int)filp->f_version;
filp->f_version = 0;
- for (task = first_tid(leader, tid, pos - 2);
+ for (task = first_tid(leader, tid, pos - 2, ns);
task;
task = next_tid(task), pos++) {
- tid = task->pid;
+ tid = task_pid_nr_ns(task, ns);
if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
/* returning this tgid failed, save it as the first
* pid for the next readir call */
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 99ca00485fc..abe6a3f0436 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -448,7 +448,7 @@ out_mod:
return NULL;
}
-int proc_fill_super(struct super_block *s, void *data, int silent)
+int proc_fill_super(struct super_block *s)
{
struct inode * root_inode;
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index d6dc72c78bc..e0d064e9764 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -91,7 +91,8 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
LOAD_INT(a), LOAD_FRAC(a),
LOAD_INT(b), LOAD_FRAC(b),
LOAD_INT(c), LOAD_FRAC(c),
- nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid);
+ nr_running(), nr_threads,
+ task_active_pid_ns(current)->last_pid);
return proc_calc_metrics(page, start, off, count, eof, len);
}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index cf3046638b0..ec9cb3b6c93 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -18,32 +18,90 @@
#include <linux/bitops.h>
#include <linux/smp_lock.h>
#include <linux/mount.h>
+#include <linux/pid_namespace.h>
#include "internal.h"
struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver;
+static int proc_test_super(struct super_block *sb, void *data)
+{
+ return sb->s_fs_info == data;
+}
+
+static int proc_set_super(struct super_block *sb, void *data)
+{
+ struct pid_namespace *ns;
+
+ ns = (struct pid_namespace *)data;
+ sb->s_fs_info = get_pid_ns(ns);
+ return set_anon_super(sb, NULL);
+}
+
static int proc_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
+ int err;
+ struct super_block *sb;
+ struct pid_namespace *ns;
+ struct proc_inode *ei;
+
if (proc_mnt) {
/* Seed the root directory with a pid so it doesn't need
* to be special in base.c. I would do this earlier but
* the only task alive when /proc is mounted the first time
* is the init_task and it doesn't have any pids.
*/
- struct proc_inode *ei;
ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
if (!ei->pid)
ei->pid = find_get_pid(1);
}
- return get_sb_single(fs_type, flags, data, proc_fill_super, mnt);
+
+ if (flags & MS_KERNMOUNT)
+ ns = (struct pid_namespace *)data;
+ else
+ ns = current->nsproxy->pid_ns;
+
+ sb = sget(fs_type, proc_test_super, proc_set_super, ns);
+ if (IS_ERR(sb))
+ return PTR_ERR(sb);
+
+ if (!sb->s_root) {
+ sb->s_flags = flags;
+ err = proc_fill_super(sb);
+ if (err) {
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ return err;
+ }
+
+ ei = PROC_I(sb->s_root->d_inode);
+ if (!ei->pid) {
+ rcu_read_lock();
+ ei->pid = get_pid(find_pid_ns(1, ns));
+ rcu_read_unlock();
+ }
+
+ sb->s_flags |= MS_ACTIVE;
+ ns->proc_mnt = mnt;
+ }
+
+ return simple_set_mnt(mnt, sb);
+}
+
+static void proc_kill_sb(struct super_block *sb)
+{
+ struct pid_namespace *ns;
+
+ ns = (struct pid_namespace *)sb->s_fs_info;
+ kill_anon_super(sb);
+ put_pid_ns(ns);
}
static struct file_system_type proc_fs_type = {
.name = "proc",
.get_sb = proc_get_sb,
- .kill_sb = kill_anon_super,
+ .kill_sb = proc_kill_sb,
};
void __init proc_root_init(void)
@@ -54,12 +112,13 @@ void __init proc_root_init(void)
err = register_filesystem(&proc_fs_type);
if (err)
return;
- proc_mnt = kern_mount(&proc_fs_type);
+ proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
err = PTR_ERR(proc_mnt);
if (IS_ERR(proc_mnt)) {
unregister_filesystem(&proc_fs_type);
return;
}
+
proc_misc_init();
proc_net_init();
@@ -153,6 +212,22 @@ struct proc_dir_entry proc_root = {
.parent = &proc_root,
};
+int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+ struct vfsmount *mnt;
+
+ mnt = kern_mount_data(&proc_fs_type, ns);
+ if (IS_ERR(mnt))
+ return PTR_ERR(mnt);
+
+ return 0;
+}
+
+void pid_ns_release_proc(struct pid_namespace *ns)
+{
+ mntput(ns->proc_mnt);
+}
+
EXPORT_SYMBOL(proc_symlink);
EXPORT_SYMBOL(proc_mkdir);
EXPORT_SYMBOL(create_proc_entry);
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 2a5dd34649b..16b331dd991 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -47,7 +47,9 @@
test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s))
static inline void get_bit_address(struct super_block *s,
- b_blocknr_t block, int *bmap_nr, int *offset)
+ b_blocknr_t block,
+ unsigned int *bmap_nr,
+ unsigned int *offset)
{
/* It is in the bitmap block number equal to the block
* number divided by the number of bits in a block. */
@@ -56,10 +58,10 @@ static inline void get_bit_address(struct super_block *s,
*offset = block & ((s->s_blocksize << 3) - 1);
}
-#ifdef CONFIG_REISERFS_CHECK
int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
{
- int bmap, offset;
+ unsigned int bmap, offset;
+ unsigned int bmap_count = reiserfs_bmap_count(s);
if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
reiserfs_warning(s,
@@ -75,25 +77,26 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
if (unlikely(test_bit(REISERFS_OLD_FORMAT,
&(REISERFS_SB(s)->s_properties)))) {
b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
- if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
+ if (block >= bmap1 &&
+ block <= bmap1 + bmap_count) {
reiserfs_warning(s, "vs: 4019: is_reusable: "
"bitmap block %lu(%u) can't be freed or reused",
- block, SB_BMAP_NR(s));
+ block, bmap_count);
return 0;
}
} else {
if (offset == 0) {
reiserfs_warning(s, "vs: 4020: is_reusable: "
"bitmap block %lu(%u) can't be freed or reused",
- block, SB_BMAP_NR(s));
+ block, bmap_count);
return 0;
}
}
- if (bmap >= SB_BMAP_NR(s)) {
+ if (bmap >= bmap_count) {
reiserfs_warning(s,
"vs-4030: is_reusable: there is no so many bitmap blocks: "
- "block=%lu, bitmap_nr=%d", block, bmap);
+ "block=%lu, bitmap_nr=%u", block, bmap);
return 0;
}
@@ -106,12 +109,11 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
return 1;
}
-#endif /* CONFIG_REISERFS_CHECK */
/* searches in journal structures for a given block number (bmap, off). If block
is found in reiserfs journal it suggests next free block candidate to test. */
-static inline int is_block_in_journal(struct super_block *s, int bmap, int
- off, int *next)
+static inline int is_block_in_journal(struct super_block *s, unsigned int bmap,
+ int off, int *next)
{
b_blocknr_t tmp;
@@ -132,8 +134,8 @@ static inline int is_block_in_journal(struct super_block *s, int bmap, int
/* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
* block; */
static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
- int bmap_n, int *beg, int boundary, int min,
- int max, int unfm)
+ unsigned int bmap_n, int *beg, int boundary,
+ int min, int max, int unfm)
{
struct super_block *s = th->t_super;
struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
@@ -143,8 +145,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
BUG_ON(!th->t_trans_id);
- RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)",
- bmap_n, SB_BMAP_NR(s) - 1);
+ RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of "
+ "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1);
PROC_INFO_INC(s, scan_bitmap.bmap);
/* this is unclear and lacks comments, explain how journal bitmaps
work here for the reader. Convey a sense of the design here. What
@@ -249,12 +251,12 @@ static int bmap_hash_id(struct super_block *s, u32 id)
} else {
hash_in = (char *)(&id);
hash = keyed_hash(hash_in, 4);
- bm = hash % SB_BMAP_NR(s);
+ bm = hash % reiserfs_bmap_count(s);
if (!bm)
bm = 1;
}
/* this can only be true when SB_BMAP_NR = 1 */
- if (bm >= SB_BMAP_NR(s))
+ if (bm >= reiserfs_bmap_count(s))
bm = 0;
return bm;
}
@@ -273,7 +275,7 @@ static inline int block_group_used(struct super_block *s, u32 id)
* to make a better decision. This favors long-term performace gain
* with a better on-disk layout vs. a short term gain of skipping the
* read and potentially having a bad placement. */
- if (info->first_zero_hint == 0) {
+ if (info->free_count == UINT_MAX) {
struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
brelse(bh);
}
@@ -309,16 +311,16 @@ __le32 reiserfs_choose_packing(struct inode * dir)
* bitmap and place new blocks there. Returns number of allocated blocks. */
static int scan_bitmap(struct reiserfs_transaction_handle *th,
b_blocknr_t * start, b_blocknr_t finish,
- int min, int max, int unfm, unsigned long file_block)
+ int min, int max, int unfm, sector_t file_block)
{
int nr_allocated = 0;
struct super_block *s = th->t_super;
/* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr
* - Hans, it is not a block number - Zam. */
- int bm, off;
- int end_bm, end_off;
- int off_max = s->s_blocksize << 3;
+ unsigned int bm, off;
+ unsigned int end_bm, end_off;
+ unsigned int off_max = s->s_blocksize << 3;
BUG_ON(!th->t_trans_id);
@@ -328,10 +330,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th,
get_bit_address(s, *start, &bm, &off);
get_bit_address(s, finish, &end_bm, &end_off);
- if (bm > SB_BMAP_NR(s))
+ if (bm > reiserfs_bmap_count(s))
return 0;
- if (end_bm > SB_BMAP_NR(s))
- end_bm = SB_BMAP_NR(s);
+ if (end_bm > reiserfs_bmap_count(s))
+ end_bm = reiserfs_bmap_count(s);
/* When the bitmap is more than 10% free, anyone can allocate.
* When it's less than 10% free, only files that already use the
@@ -385,7 +387,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
struct reiserfs_super_block *rs;
struct buffer_head *sbh, *bmbh;
struct reiserfs_bitmap_info *apbi;
- int nr, offset;
+ unsigned int nr, offset;
BUG_ON(!th->t_trans_id);
@@ -397,10 +399,12 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
get_bit_address(s, block, &nr, &offset);
- if (nr >= sb_bmap_nr(rs)) {
+ if (nr >= reiserfs_bmap_count(s)) {
reiserfs_warning(s, "vs-4075: reiserfs_free_block: "
- "block %lu is out of range on %s",
- block, reiserfs_bdevname(s));
+ "block %lu is out of range on %s "
+ "(nr=%u,max=%u)", block,
+ reiserfs_bdevname(s), nr,
+ reiserfs_bmap_count(s));
return;
}
@@ -434,12 +438,19 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th,
int for_unformatted)
{
struct super_block *s = th->t_super;
-
BUG_ON(!th->t_trans_id);
RFALSE(!s, "vs-4061: trying to free block on nonexistent device");
- RFALSE(is_reusable(s, block, 1) == 0,
- "vs-4071: can not free such block");
+ if (!is_reusable(s, block, 1))
+ return;
+
+ if (block > sb_block_count(REISERFS_SB(s)->s_rs)) {
+ reiserfs_panic(th->t_super, "bitmap-4072",
+ "Trying to free block outside file system "
+ "boundaries (%lu > %lu)",
+ block, sb_block_count(REISERFS_SB(s)->s_rs));
+ return;
+ }
/* mark it before we clear it, just in case */
journal_mark_freed(th, s, block);
_reiserfs_free_block(th, inode, block, for_unformatted);
@@ -449,11 +460,11 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th,
static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th,
struct inode *inode, b_blocknr_t block)
{
+ BUG_ON(!th->t_trans_id);
RFALSE(!th->t_super,
"vs-4060: trying to free block on nonexistent device");
- RFALSE(is_reusable(th->t_super, block, 1) == 0,
- "vs-4070: can not free such block");
- BUG_ON(!th->t_trans_id);
+ if (!is_reusable(th->t_super, block, 1))
+ return;
_reiserfs_free_block(th, inode, block, 1);
}
@@ -1207,27 +1218,22 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb,
{
unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
- info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
+ /* The first bit must ALWAYS be 1 */
+ BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data));
+
+ info->free_count = 0;
while (--cur >= (unsigned long *)bh->b_data) {
- int base = ((char *)cur - bh->b_data) << 3;
+ int i;
/* 0 and ~0 are special, we can optimize for them */
- if (*cur == 0) {
- info->first_zero_hint = base;
+ if (*cur == 0)
info->free_count += BITS_PER_LONG;
- } else if (*cur != ~0L) { /* A mix, investigate */
- int b;
- for (b = BITS_PER_LONG - 1; b >= 0; b--) {
- if (!reiserfs_test_le_bit(b, cur)) {
- info->first_zero_hint = base + b;
+ else if (*cur != ~0L) /* A mix, investigate */
+ for (i = BITS_PER_LONG - 1; i >= 0; i--)
+ if (!reiserfs_test_le_bit(i, cur))
info->free_count++;
- }
- }
- }
}
- /* The first bit must ALWAYS be 1 */
- BUG_ON(info->first_zero_hint == 0);
}
struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
@@ -1257,7 +1263,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
BUG_ON(!buffer_uptodate(bh));
BUG_ON(atomic_read(&bh->b_count) == 0);
- if (info->first_zero_hint == 0)
+ if (info->free_count == UINT_MAX)
reiserfs_cache_bitmap_metadata(sb, bh, info);
}
@@ -1267,12 +1273,13 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
int reiserfs_init_bitmap_cache(struct super_block *sb)
{
struct reiserfs_bitmap_info *bitmap;
+ unsigned int bmap_nr = reiserfs_bmap_count(sb);
- bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
+ bitmap = vmalloc(sizeof(*bitmap) * bmap_nr);
if (bitmap == NULL)
return -ENOMEM;
- memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
+ memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr);
SB_AP_BITMAP(sb) = bitmap;
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 0804289d355..231fd5ccadc 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -199,7 +199,7 @@ static inline void set_block_dev_mapped(struct buffer_head *bh,
// files which were created in the earlier version can not be longer,
// than 2 gb
//
-static int file_capable(struct inode *inode, long block)
+static int file_capable(struct inode *inode, sector_t block)
{
if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || // it is new file.
block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb
@@ -242,7 +242,7 @@ static int restart_transaction(struct reiserfs_transaction_handle *th,
// Please improve the english/clarity in the comment above, as it is
// hard to understand.
-static int _get_block_create_0(struct inode *inode, long block,
+static int _get_block_create_0(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int args)
{
INITIALIZE_PATH(path);
@@ -250,7 +250,7 @@ static int _get_block_create_0(struct inode *inode, long block,
struct buffer_head *bh;
struct item_head *ih, tmp_ih;
int fs_gen;
- int blocknr;
+ b_blocknr_t blocknr;
char *p = NULL;
int chars;
int ret;
@@ -569,7 +569,7 @@ static int convert_tail_for_hole(struct inode *inode,
}
static inline int _allocate_block(struct reiserfs_transaction_handle *th,
- long block,
+ sector_t block,
struct inode *inode,
b_blocknr_t * allocated_block_nr,
struct treepath *path, int flags)
@@ -1515,19 +1515,20 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
return inode;
}
-struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
+static struct dentry *reiserfs_get_dentry(struct super_block *sb,
+ u32 objectid, u32 dir_id, u32 generation)
+
{
- __u32 *data = vobjp;
struct cpu_key key;
struct dentry *result;
struct inode *inode;
- key.on_disk_key.k_objectid = data[0];
- key.on_disk_key.k_dir_id = data[1];
+ key.on_disk_key.k_objectid = objectid;
+ key.on_disk_key.k_dir_id = dir_id;
reiserfs_write_lock(sb);
inode = reiserfs_iget(sb, &key);
- if (inode && !IS_ERR(inode) && data[2] != 0 &&
- data[2] != inode->i_generation) {
+ if (inode && !IS_ERR(inode) && generation != 0 &&
+ generation != inode->i_generation) {
iput(inode);
inode = NULL;
}
@@ -1544,14 +1545,9 @@ struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
return result;
}
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
- int len, int fhtype,
- int (*acceptable) (void *contect,
- struct dentry * de),
- void *context)
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
{
- __u32 obj[3], parent[3];
-
/* fhtype happens to reflect the number of u32s encoded.
* due to a bug in earlier code, fhtype might indicate there
* are more u32s then actually fitted.
@@ -1564,32 +1560,28 @@ struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
* 6 - as above plus generation of directory
* 6 does not fit in NFSv2 handles
*/
- if (fhtype > len) {
- if (fhtype != 6 || len != 5)
+ if (fh_type > fh_len) {
+ if (fh_type != 6 || fh_len != 5)
reiserfs_warning(sb,
- "nfsd/reiserfs, fhtype=%d, len=%d - odd",
- fhtype, len);
- fhtype = 5;
+ "nfsd/reiserfs, fhtype=%d, len=%d - odd",
+ fh_type, fh_len);
+ fh_type = 5;
}
- obj[0] = data[0];
- obj[1] = data[1];
- if (fhtype == 3 || fhtype >= 5)
- obj[2] = data[2];
- else
- obj[2] = 0; /* generation number */
+ return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
+ (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
+}
- if (fhtype >= 4) {
- parent[0] = data[fhtype >= 5 ? 3 : 2];
- parent[1] = data[fhtype >= 5 ? 4 : 3];
- if (fhtype == 6)
- parent[2] = data[5];
- else
- parent[2] = 0;
- }
- return sb->s_export_op->find_exported_dentry(sb, obj,
- fhtype < 4 ? NULL : parent,
- acceptable, context);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type)
+{
+ if (fh_type < 4)
+ return NULL;
+
+ return reiserfs_get_dentry(sb,
+ (fh_type >= 5) ? fid->raw[3] : fid->raw[2],
+ (fh_type >= 5) ? fid->raw[4] : fid->raw[3],
+ (fh_type == 6) ? fid->raw[5] : 0);
}
int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 4cad9e75ef5..bb05a3e51b9 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -219,11 +219,12 @@ static void allocate_bitmap_nodes(struct super_block *p_s_sb)
}
}
-static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block,
+static int set_bit_in_list_bitmap(struct super_block *p_s_sb,
+ b_blocknr_t block,
struct reiserfs_list_bitmap *jb)
{
- int bmap_nr = block / (p_s_sb->s_blocksize << 3);
- int bit_nr = block % (p_s_sb->s_blocksize << 3);
+ unsigned int bmap_nr = block / (p_s_sb->s_blocksize << 3);
+ unsigned int bit_nr = block % (p_s_sb->s_blocksize << 3);
if (!jb->bitmaps[bmap_nr]) {
jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb);
@@ -239,7 +240,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb,
if (jb->bitmaps == NULL)
return;
- for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) {
+ for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) {
if (jb->bitmaps[i]) {
free_bitmap_node(p_s_sb, jb->bitmaps[i]);
jb->bitmaps[i] = NULL;
@@ -289,7 +290,7 @@ static int free_bitmap_nodes(struct super_block *p_s_sb)
*/
int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb,
struct reiserfs_list_bitmap *jb_array,
- int bmap_nr)
+ unsigned int bmap_nr)
{
int i;
int failed = 0;
@@ -483,7 +484,7 @@ static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct
**
*/
int reiserfs_in_journal(struct super_block *p_s_sb,
- int bmap_nr, int bit_nr, int search_all,
+ unsigned int bmap_nr, int bit_nr, int search_all,
b_blocknr_t * next_zero_bit)
{
struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb);
@@ -1013,7 +1014,7 @@ static int flush_commit_list(struct super_block *s,
struct reiserfs_journal_list *jl, int flushall)
{
int i;
- int bn;
+ b_blocknr_t bn;
struct buffer_head *tbh = NULL;
unsigned long trans_id = jl->j_trans_id;
struct reiserfs_journal *journal = SB_JOURNAL(s);
@@ -2307,8 +2308,9 @@ static int journal_read_transaction(struct super_block *p_s_sb,
Right now it is only used from journal code. But later we might use it
from other places.
Note: Do not use journal_getblk/sb_getblk functions here! */
-static struct buffer_head *reiserfs_breada(struct block_device *dev, int block,
- int bufsize, unsigned int max_block)
+static struct buffer_head *reiserfs_breada(struct block_device *dev,
+ b_blocknr_t block, int bufsize,
+ b_blocknr_t max_block)
{
struct buffer_head *bhlist[BUFNR];
unsigned int blocks = BUFNR;
@@ -2732,7 +2734,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
journal->j_persistent_trans = 0;
if (reiserfs_allocate_list_bitmaps(p_s_sb,
journal->j_list_bitmap,
- SB_BMAP_NR(p_s_sb)))
+ reiserfs_bmap_count(p_s_sb)))
goto free_and_return;
allocate_bitmap_nodes(p_s_sb);
@@ -2740,7 +2742,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name,
SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ?
REISERFS_OLD_DISK_OFFSET_IN_BYTES
/ p_s_sb->s_blocksize +
- SB_BMAP_NR(p_s_sb) +
+ reiserfs_bmap_count(p_s_sb) +
1 :
REISERFS_DISK_OFFSET_IN_BYTES /
p_s_sb->s_blocksize + 2);
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index bc808a91eea..5e7388b32d0 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -356,13 +356,11 @@ extern struct tree_balance *cur_tb;
void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
{
do_reiserfs_warning(fmt);
- printk(KERN_EMERG "REISERFS: panic (device %s): %s\n",
- reiserfs_bdevname(sb), error_buf);
- BUG();
- /* this is not actually called, but makes reiserfs_panic() "noreturn" */
- panic("REISERFS: panic (device %s): %s\n",
- reiserfs_bdevname(sb), error_buf);
+ dump_stack();
+
+ panic(KERN_EMERG "REISERFS: panic (device %s): %s\n",
+ reiserfs_bdevname(sb), error_buf);
}
void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 976cc7887a0..f71c3948ede 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -61,7 +61,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
}
/* count used bits in last bitmap block */
- block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
+ block_r = SB_BLOCK_COUNT(s) -
+ (reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8;
/* count bitmap blocks in new fs */
bmap_nr_new = block_count_new / (s->s_blocksize * 8);
@@ -73,7 +74,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
/* save old values */
block_count = SB_BLOCK_COUNT(s);
- bmap_nr = SB_BMAP_NR(s);
+ bmap_nr = reiserfs_bmap_count(s);
/* resizing of reiserfs bitmaps (journal and real), if needed */
if (bmap_nr_new > bmap_nr) {
@@ -119,7 +120,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
return -ENOMEM;
}
memset(bitmap, 0,
- sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
+ sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
for (i = 0; i < bmap_nr; i++)
bitmap[i] = old_bitmap[i];
@@ -143,7 +144,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
mark_buffer_dirty(bh);
sync_dirty_buffer(bh);
// update bitmap_info stuff
- bitmap[i].first_zero_hint = 1;
bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
brelse(bh);
}
@@ -173,8 +173,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
for (i = block_r; i < s->s_blocksize * 8; i++)
reiserfs_test_and_clear_le_bit(i, bh->b_data);
info->free_count += s->s_blocksize * 8 - block_r;
- if (!info->first_zero_hint)
- info->first_zero_hint = block_r;
journal_mark_dirty(&th, s, bh);
brelse(bh);
@@ -196,9 +194,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
brelse(bh);
info->free_count -= s->s_blocksize * 8 - block_r_new;
- /* Extreme case where last bitmap is the only valid block in itself. */
- if (!info->free_count)
- info->first_zero_hint = 0;
/* update super */
reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
free_blocks = SB_FREE_BLOCKS(s);
@@ -206,7 +201,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
free_blocks + (block_count_new - block_count -
(bmap_nr_new - bmap_nr)));
PUT_SB_BLOCK_COUNT(s, block_count_new);
- PUT_SB_BMAP_NR(s, bmap_nr_new);
+ PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);
s->s_dirt = 1;
journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index 981027d1187..ca41567d789 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -559,7 +559,7 @@ static int is_tree_node(struct buffer_head *bh, int level)
/* The function is NOT SCHEDULE-SAFE! */
static void search_by_key_reada(struct super_block *s,
struct buffer_head **bh,
- unsigned long *b, int num)
+ b_blocknr_t *b, int num)
{
int i, j;
@@ -611,7 +611,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /*
DISK_LEAF_NODE_LEVEL */
)
{
- int n_block_number;
+ b_blocknr_t n_block_number;
int expected_level;
struct buffer_head *p_s_bh;
struct path_element *p_s_last_element;
@@ -619,7 +619,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /*
int right_neighbor_of_leaf_node;
int fs_gen;
struct buffer_head *reada_bh[SEARCH_BY_KEY_READA];
- unsigned long reada_blocks[SEARCH_BY_KEY_READA];
+ b_blocknr_t reada_blocks[SEARCH_BY_KEY_READA];
int reada_count = 0;
#ifdef CONFIG_REISERFS_CHECK
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index b82897ae090..5cd85fe5df5 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -319,7 +319,7 @@ static int finish_unfinished(struct super_block *s)
/* to protect file being unlinked from getting lost we "safe" link files
being unlinked. This link will be deleted in the same transaction with last
- item of file. mounting the filesytem we scan all these links and remove
+ item of file. mounting the filesystem we scan all these links and remove
files which almost got lost */
void add_save_link(struct reiserfs_transaction_handle *th,
struct inode *inode, int truncate)
@@ -661,11 +661,11 @@ static struct quotactl_ops reiserfs_qctl_operations = {
};
#endif
-static struct export_operations reiserfs_export_ops = {
+static const struct export_operations reiserfs_export_ops = {
.encode_fh = reiserfs_encode_fh,
- .decode_fh = reiserfs_decode_fh,
+ .fh_to_dentry = reiserfs_fh_to_dentry,
+ .fh_to_parent = reiserfs_fh_to_parent,
.get_parent = reiserfs_get_parent,
- .get_dentry = reiserfs_get_dentry,
};
/* this struct is used in reiserfs_getopt () for containing the value for those
@@ -1725,6 +1725,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
set_sb_umount_state(rs, REISERFS_ERROR_FS);
set_sb_fs_state(rs, 0);
+ /* Clear out s_bmap_nr if it would wrap. We can handle this
+ * case, but older revisions can't. This will cause the
+ * file system to fail mount on those older implementations,
+ * avoiding corruption. -jeffm */
+ if (bmap_would_wrap(reiserfs_bmap_count(s)) &&
+ sb_bmap_nr(rs) != 0) {
+ reiserfs_warning(s, "super-2030: This file system "
+ "claims to use %u bitmap blocks in "
+ "its super block, but requires %u. "
+ "Clearing to zero.", sb_bmap_nr(rs),
+ reiserfs_bmap_count(s));
+
+ set_sb_bmap_nr(rs, 0);
+ }
+
if (old_format_only(s)) {
/* filesystem of format 3.5 either with standard or non-standard
journal */
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index fab4b9b2664..1597f6b649e 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -484,7 +484,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
/* Resize it so we're ok to write there */
newattrs.ia_size = buffer_size;
newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
- mutex_lock(&xinode->i_mutex);
+ mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
err = notify_change(fp->f_path.dentry, &newattrs);
if (err)
goto out_filp;
@@ -1223,7 +1223,8 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags)
if (!IS_ERR(dentry)) {
if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
struct inode *inode = dentry->d_parent->d_inode;
- mutex_lock(&inode->i_mutex);
+ mutex_lock_nested(&inode->i_mutex,
+ I_MUTEX_XATTR);
err = inode->i_op->mkdir(inode, dentry, 0700);
mutex_unlock(&inode->i_mutex);
if (err) {
diff --git a/fs/select.c b/fs/select.c
index 7dede89658f..47f47925aea 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -177,11 +177,6 @@ get_max:
return max;
}
-#define BIT(i) (1UL << ((i)&(__NFDBITS-1)))
-#define MEM(i,m) ((m)+(unsigned)(i)/__NFDBITS)
-#define ISSET(i,m) (((i)&*(m)) != 0)
-#define SET(i,m) (*(m) |= (i))
-
#define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
#define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
#define POLLEX_SET (POLLPRI)
diff --git a/fs/super.c b/fs/super.c
index 1bfcca2104b..ceaf2e3d594 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -15,7 +15,7 @@
* Added kerneld support: Jacques Gelinas and Bjorn Ekwall
* Added change_root: Werner Almesberger & Hans Lermen, Feb '96
* Added options to /proc/mounts:
- * Torbjrn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
+ * Torbjörn Lindh (torbjorn.lindh@gopta.se), April 14, 1996.
* Added devfs support: Richard Gooch <rgooch@atnf.csiro.au>, 13-JAN-1998
* Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
*/
@@ -40,10 +40,6 @@
#include <asm/uaccess.h>
-void get_filesystem(struct file_system_type *fs);
-void put_filesystem(struct file_system_type *fs);
-struct file_system_type *get_fs_type(const char *name);
-
LIST_HEAD(super_blocks);
DEFINE_SPINLOCK(sb_lock);
@@ -336,21 +332,21 @@ struct super_block *sget(struct file_system_type *type,
void *data)
{
struct super_block *s = NULL;
- struct list_head *p;
+ struct super_block *old;
int err;
retry:
spin_lock(&sb_lock);
- if (test) list_for_each(p, &type->fs_supers) {
- struct super_block *old;
- old = list_entry(p, struct super_block, s_instances);
- if (!test(old, data))
- continue;
- if (!grab_super(old))
- goto retry;
- if (s)
- destroy_super(s);
- return old;
+ if (test) {
+ list_for_each_entry(old, &type->fs_supers, s_instances) {
+ if (!test(old, data))
+ continue;
+ if (!grab_super(old))
+ goto retry;
+ if (s)
+ destroy_super(s);
+ return old;
+ }
}
if (!s) {
spin_unlock(&sb_lock);
@@ -421,7 +417,7 @@ restart:
}
/*
- * Call the ->sync_fs super_op against all filesytems which are r/w and
+ * Call the ->sync_fs super_op against all filesystems which are r/w and
* which implement it.
*
* This operation is careful to avoid the livelock which could easily happen
@@ -429,7 +425,7 @@ restart:
* is used only here. We set it against all filesystems and then clear it as
* we sync them. So redirtied filesystems are skipped.
*
- * But if process A is currently running sync_filesytems and then process B
+ * But if process A is currently running sync_filesystems and then process B
* calls sync_filesystems as well, process B will set all the s_need_sync_fs
* flags again, which will cause process A to resync everything. Fix that with
* a local mutex.
@@ -948,9 +944,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
return mnt;
}
-struct vfsmount *kern_mount(struct file_system_type *type)
+struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
{
- return vfs_kern_mount(type, 0, type->name, NULL);
+ return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data);
}
-EXPORT_SYMBOL(kern_mount);
+EXPORT_SYMBOL_GPL(kern_mount_data);
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d3be1e7fb48..27d1785b764 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -540,7 +540,7 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr,
/**
* sysfs_create_file - create an attribute file for an object.
* @kobj: object we're creating for.
- * @attr: atrribute descriptor.
+ * @attr: attribute descriptor.
*/
int sysfs_create_file(struct kobject * kobj, const struct attribute * attr)
diff --git a/fs/xattr.c b/fs/xattr.c
index a44fd92caca..6645b7313b3 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
if (!f)
return error;
dentry = f->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = setxattr(dentry, name, value, size, flags);
fput(f);
return error;
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
f = fget(fd);
if (!f)
return error;
- audit_inode(NULL, f->f_path.dentry->d_inode);
+ audit_inode(NULL, f->f_path.dentry);
error = getxattr(f->f_path.dentry, name, value, size);
fput(f);
return error;
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
f = fget(fd);
if (!f)
return error;
- audit_inode(NULL, f->f_path.dentry->d_inode);
+ audit_inode(NULL, f->f_path.dentry);
error = listxattr(f->f_path.dentry, list, size);
fput(f);
return error;
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name)
if (!f)
return error;
dentry = f->f_path.dentry;
- audit_inode(NULL, dentry->d_inode);
+ audit_inode(NULL, dentry);
error = removexattr(dentry, name);
fput(f);
return error;
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 726449d4fd2..15bd4948832 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -33,62 +33,25 @@
static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
/*
- * XFS encodes and decodes the fileid portion of NFS filehandles
- * itself instead of letting the generic NFS code do it. This
- * allows filesystems with 64 bit inode numbers to be exported.
- *
- * Note that a side effect is that xfs_vget() won't be passed a
- * zero inode/generation pair under normal circumstances. As
- * however a malicious client could send us such data, the check
- * remains in that code.
+ * Note that we only accept fileids which are long enough rather than allow
+ * the parent generation number to default to zero. XFS considers zero a
+ * valid generation number not an invalid/wildcard value.
*/
-
-STATIC struct dentry *
-xfs_fs_decode_fh(
- struct super_block *sb,
- __u32 *fh,
- int fh_len,
- int fileid_type,
- int (*acceptable)(
- void *context,
- struct dentry *de),
- void *context)
+static int xfs_fileid_length(int fileid_type)
{
- xfs_fid2_t ifid;
- xfs_fid2_t pfid;
- void *parent = NULL;
- int is64 = 0;
- __u32 *p = fh;
-
-#if XFS_BIG_INUMS
- is64 = (fileid_type & XFS_FILEID_TYPE_64FLAG);
- fileid_type &= ~XFS_FILEID_TYPE_64FLAG;
-#endif
-
- /*
- * Note that we only accept fileids which are long enough
- * rather than allow the parent generation number to default
- * to zero. XFS considers zero a valid generation number not
- * an invalid/wildcard value. There's little point printk'ing
- * a warning here as we don't have the client information
- * which would make such a warning useful.
- */
- if (fileid_type > 2 ||
- fh_len < xfs_fileid_length((fileid_type == 2), is64))
- return NULL;
-
- p = xfs_fileid_decode_fid2(p, &ifid, is64);
-
- if (fileid_type == 2) {
- p = xfs_fileid_decode_fid2(p, &pfid, is64);
- parent = &pfid;
+ switch (fileid_type) {
+ case FILEID_INO32_GEN:
+ return 2;
+ case FILEID_INO32_GEN_PARENT:
+ return 4;
+ case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+ return 3;
+ case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+ return 6;
}
-
- fh = (__u32 *)&ifid;
- return sb->s_export_op->find_exported_dentry(sb, fh, parent, acceptable, context);
+ return 255; /* invalid */
}
-
STATIC int
xfs_fs_encode_fh(
struct dentry *dentry,
@@ -96,21 +59,21 @@ xfs_fs_encode_fh(
int *max_len,
int connectable)
{
+ struct fid *fid = (struct fid *)fh;
+ struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh;
struct inode *inode = dentry->d_inode;
- int type = 1;
- __u32 *p = fh;
+ int fileid_type;
int len;
- int is64 = 0;
-#if XFS_BIG_INUMS
- if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
- /* filesystem may contain 64bit inode numbers */
- is64 = XFS_FILEID_TYPE_64FLAG;
- }
-#endif
/* Directories don't need their parent encoded, they have ".." */
if (S_ISDIR(inode->i_mode))
- connectable = 0;
+ fileid_type = FILEID_INO32_GEN;
+ else
+ fileid_type = FILEID_INO32_GEN_PARENT;
+
+ /* filesystem may contain 64bit inode numbers */
+ if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS))
+ fileid_type |= XFS_FILEID_TYPE_64FLAG;
/*
* Only encode if there is enough space given. In practice
@@ -118,39 +81,118 @@ xfs_fs_encode_fh(
* over NFSv2 with the subtree_check export option; the other
* seven combinations work. The real answer is "don't use v2".
*/
- len = xfs_fileid_length(connectable, is64);
+ len = xfs_fileid_length(fileid_type);
if (*max_len < len)
return 255;
*max_len = len;
- p = xfs_fileid_encode_inode(p, inode, is64);
- if (connectable) {
+ switch (fileid_type) {
+ case FILEID_INO32_GEN_PARENT:
spin_lock(&dentry->d_lock);
- p = xfs_fileid_encode_inode(p, dentry->d_parent->d_inode, is64);
+ fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino;
+ fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
spin_unlock(&dentry->d_lock);
- type = 2;
+ /*FALLTHRU*/
+ case FILEID_INO32_GEN:
+ fid->i32.ino = inode->i_ino;
+ fid->i32.gen = inode->i_generation;
+ break;
+ case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+ spin_lock(&dentry->d_lock);
+ fid64->parent_ino = dentry->d_parent->d_inode->i_ino;
+ fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
+ spin_unlock(&dentry->d_lock);
+ /*FALLTHRU*/
+ case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+ fid64->ino = inode->i_ino;
+ fid64->gen = inode->i_generation;
+ break;
}
- BUG_ON((p - fh) != len);
- return type | is64;
+
+ return fileid_type;
}
-STATIC struct dentry *
-xfs_fs_get_dentry(
+STATIC struct inode *
+xfs_nfs_get_inode(
struct super_block *sb,
- void *data)
-{
+ u64 ino,
+ u32 generation)
+ {
+ xfs_fid_t xfid;
bhv_vnode_t *vp;
- struct inode *inode;
- struct dentry *result;
int error;
- error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data);
- if (error || vp == NULL)
- return ERR_PTR(-ESTALE) ;
+ xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len);
+ xfid.fid_pad = 0;
+ xfid.fid_ino = ino;
+ xfid.fid_gen = generation;
- inode = vn_to_inode(vp);
+ error = xfs_vget(XFS_M(sb), &vp, &xfid);
+ if (error)
+ return ERR_PTR(-error);
+
+ return vp ? vn_to_inode(vp) : NULL;
+}
+
+STATIC struct dentry *
+xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fileid_type)
+{
+ struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
+ struct inode *inode = NULL;
+ struct dentry *result;
+
+ if (fh_len < xfs_fileid_length(fileid_type))
+ return NULL;
+
+ switch (fileid_type) {
+ case FILEID_INO32_GEN_PARENT:
+ case FILEID_INO32_GEN:
+ inode = xfs_nfs_get_inode(sb, fid->i32.ino, fid->i32.gen);
+ break;
+ case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+ case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
+ inode = xfs_nfs_get_inode(sb, fid64->ino, fid64->gen);
+ break;
+ }
+
+ if (!inode)
+ return NULL;
+ if (IS_ERR(inode))
+ return ERR_PTR(PTR_ERR(inode));
+ result = d_alloc_anon(inode);
+ if (!result) {
+ iput(inode);
+ return ERR_PTR(-ENOMEM);
+ }
+ return result;
+}
+
+STATIC struct dentry *
+xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fileid_type)
+{
+ struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
+ struct inode *inode = NULL;
+ struct dentry *result;
+
+ switch (fileid_type) {
+ case FILEID_INO32_GEN_PARENT:
+ inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
+ fid->i32.parent_gen);
+ break;
+ case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
+ inode = xfs_nfs_get_inode(sb, fid64->parent_ino,
+ fid64->parent_gen);
+ break;
+ }
+
+ if (!inode)
+ return NULL;
+ if (IS_ERR(inode))
+ return ERR_PTR(PTR_ERR(inode));
result = d_alloc_anon(inode);
- if (!result) {
+ if (!result) {
iput(inode);
return ERR_PTR(-ENOMEM);
}
@@ -178,9 +220,9 @@ xfs_fs_get_parent(
return parent;
}
-struct export_operations xfs_export_operations = {
- .decode_fh = xfs_fs_decode_fh,
+const struct export_operations xfs_export_operations = {
.encode_fh = xfs_fs_encode_fh,
+ .fh_to_dentry = xfs_fs_fh_to_dentry,
+ .fh_to_parent = xfs_fs_fh_to_parent,
.get_parent = xfs_fs_get_parent,
- .get_dentry = xfs_fs_get_dentry,
};
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h
index e794ca4efc7..3272b6ae7a3 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/linux-2.6/xfs_export.h
@@ -59,50 +59,14 @@
* a subdirectory) or use the "fsid" export option.
*/
+struct xfs_fid64 {
+ u64 ino;
+ u32 gen;
+ u64 parent_ino;
+ u32 parent_gen;
+} __attribute__((packed));
+
/* This flag goes on the wire. Don't play with it. */
#define XFS_FILEID_TYPE_64FLAG 0x80 /* NFS fileid has 64bit inodes */
-/* Calculate the length in u32 units of the fileid data */
-static inline int
-xfs_fileid_length(int hasparent, int is64)
-{
- return hasparent ? (is64 ? 6 : 4) : (is64 ? 3 : 2);
-}
-
-/*
- * Decode encoded inode information (either for the inode itself
- * or the parent) into an xfs_fid2_t structure. Advances and
- * returns the new data pointer
- */
-static inline __u32 *
-xfs_fileid_decode_fid2(__u32 *p, xfs_fid2_t *fid, int is64)
-{
- fid->fid_len = sizeof(xfs_fid2_t) - sizeof(fid->fid_len);
- fid->fid_pad = 0;
- fid->fid_ino = *p++;
-#if XFS_BIG_INUMS
- if (is64)
- fid->fid_ino |= (((__u64)(*p++)) << 32);
-#endif
- fid->fid_gen = *p++;
- return p;
-}
-
-/*
- * Encode inode information (either for the inode itself or the
- * parent) into a fileid buffer. Advances and returns the new
- * data pointer.
- */
-static inline __u32 *
-xfs_fileid_encode_inode(__u32 *p, struct inode *inode, int is64)
-{
- *p++ = (__u32)inode->i_ino;
-#if XFS_BIG_INUMS
- if (is64)
- *p++ = (__u32)(inode->i_ino >> 32);
-#endif
- *p++ = inode->i_generation;
- return p;
-}
-
#endif /* __XFS_EXPORT_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index ffec630e7db..2b34bad48b0 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -152,11 +152,11 @@ xfs_find_handle(
lock_mode = xfs_ilock_map_shared(ip);
/* fill in fid section of handle from inode */
- handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) -
- sizeof(handle.ha_fid.xfs_fid_len);
- handle.ha_fid.xfs_fid_pad = 0;
- handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen;
- handle.ha_fid.xfs_fid_ino = ip->i_ino;
+ handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+ sizeof(handle.ha_fid.fid_len);
+ handle.ha_fid.fid_pad = 0;
+ handle.ha_fid.fid_gen = ip->i_d.di_gen;
+ handle.ha_fid.fid_ino = ip->i_ino;
xfs_iunlock_map_shared(ip, lock_mode);
@@ -222,10 +222,10 @@ xfs_vget_fsop_handlereq(
if (hlen < sizeof(*handlep))
memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
if (hlen > sizeof(handlep->ha_fsid)) {
- if (handlep->ha_fid.xfs_fid_len !=
- (hlen - sizeof(handlep->ha_fsid)
- - sizeof(handlep->ha_fid.xfs_fid_len))
- || handlep->ha_fid.xfs_fid_pad)
+ if (handlep->ha_fid.fid_len !=
+ (hlen - sizeof(handlep->ha_fsid) -
+ sizeof(handlep->ha_fid.fid_len)) ||
+ handlep->ha_fid.fid_pad)
return XFS_ERROR(EINVAL);
}
@@ -233,9 +233,9 @@ xfs_vget_fsop_handlereq(
* Crack the handle, obtain the inode # & generation #
*/
xfid = (struct xfs_fid *)&handlep->ha_fid;
- if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
- ino = xfid->xfs_fid_ino;
- igen = xfid->xfs_fid_gen;
+ if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) {
+ ino = xfid->fid_ino;
+ igen = xfid->fid_gen;
} else {
return XFS_ERROR(EINVAL);
}
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index c78c23310fe..3efcf45b14a 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -118,7 +118,7 @@ extern int xfs_blkdev_get(struct xfs_mount *, const char *,
extern void xfs_blkdev_put(struct block_device *);
extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern struct export_operations xfs_export_operations;
+extern const struct export_operations xfs_export_operations;
#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
index 6cd5704258a..a1e55fb9d5d 100644
--- a/fs/xfs/xfs_dmops.c
+++ b/fs/xfs/xfs_dmops.c
@@ -41,29 +41,16 @@ int
xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
{
if (args->flags & XFSMNT_DMAPI) {
- struct xfs_dmops *ops;
-
- ops = symbol_get(xfs_dmcore_xfs);
- if (!ops) {
- request_module("xfs_dmapi");
- ops = symbol_get(xfs_dmcore_xfs);
- }
-
- if (!ops) {
- cmn_err(CE_WARN, "XFS: no dmapi support available.");
- return EINVAL;
- }
- mp->m_dm_ops = ops;
- } else {
- mp->m_dm_ops = &xfs_dmcore_stub;
+ cmn_err(CE_WARN,
+ "XFS: dmapi support not available in this kernel.");
+ return EINVAL;
}
+ mp->m_dm_ops = &xfs_dmcore_stub;
return 0;
}
void
xfs_dmops_put(struct xfs_mount *mp)
{
- if (mp->m_dm_ops != &xfs_dmcore_stub)
- symbol_put(xfs_dmcore_xfs);
}
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index ec3c9c27e0d..aab96627651 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -389,30 +389,13 @@ typedef struct xfs_fsop_attrmulti_handlereq {
*/
typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */
-
-#ifndef HAVE_FID
-#define MAXFIDSZ 46
-
-typedef struct fid {
- __u16 fid_len; /* length of data in bytes */
- unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */
-} fid_t;
-#endif
-
typedef struct xfs_fid {
- __u16 xfs_fid_len; /* length of remainder */
- __u16 xfs_fid_pad;
- __u32 xfs_fid_gen; /* generation number */
- __u64 xfs_fid_ino; /* 64 bits inode number */
+ __u16 fid_len; /* length of remainder */
+ __u16 fid_pad;
+ __u32 fid_gen; /* generation number */
+ __u64 fid_ino; /* 64 bits inode number */
} xfs_fid_t;
-typedef struct xfs_fid2 {
- __u16 fid_len; /* length of remainder */
- __u16 fid_pad; /* padding, must be zero */
- __u32 fid_gen; /* generation number */
- __u64 fid_ino; /* inode number */
-} xfs_fid2_t;
-
typedef struct xfs_handle {
union {
__s64 align; /* force alignment of ha_fid */
@@ -422,9 +405,9 @@ typedef struct xfs_handle {
} xfs_handle_t;
#define ha_fsid ha_u._ha_fsid
-#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.xfs_fid_pad \
+#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.fid_pad \
- (char *) &(handle)) \
- + (handle).ha_fid.xfs_fid_len)
+ + (handle).ha_fid.fid_len)
/*
* Flags for going down operation
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c
index c266a0184b4..2ec1d8a2735 100644
--- a/fs/xfs/xfs_qmops.c
+++ b/fs/xfs/xfs_qmops.c
@@ -135,19 +135,13 @@ int
xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
{
if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) {
- struct xfs_qmops *ops;
-
- ops = symbol_get(xfs_qmcore_xfs);
- if (!ops) {
- request_module("xfs_quota");
- ops = symbol_get(xfs_qmcore_xfs);
- }
-
- if (!ops) {
- cmn_err(CE_WARN, "XFS: no quota support available.");
- return EINVAL;
- }
- mp->m_qm_ops = ops;
+#ifdef CONFIG_XFS_QUOTA
+ mp->m_qm_ops = &xfs_qmcore_xfs;
+#else
+ cmn_err(CE_WARN,
+ "XFS: qouta support not available in this kernel.");
+ return EINVAL;
+#endif
} else {
mp->m_qm_ops = &xfs_qmcore_stub;
}
@@ -158,6 +152,4 @@ xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args)
void
xfs_qmops_put(struct xfs_mount *mp)
{
- if (mp->m_qm_ops != &xfs_qmcore_stub)
- symbol_put(xfs_qmcore_xfs);
}
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index a5a8454f2a6..a1544597bcd 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -1635,9 +1635,8 @@ int
xfs_vget(
xfs_mount_t *mp,
bhv_vnode_t **vpp,
- fid_t *fidp)
+ xfs_fid_t *xfid)
{
- xfs_fid_t *xfid = (struct xfs_fid *)fidp;
xfs_inode_t *ip;
int error;
xfs_ino_t ino;
@@ -1647,11 +1646,11 @@ xfs_vget(
* Invalid. Since handles can be created in user space and passed in
* via gethandle(), this is not cause for a panic.
*/
- if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len))
+ if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len))
return XFS_ERROR(EINVAL);
- ino = xfid->xfs_fid_ino;
- igen = xfid->xfs_fid_gen;
+ ino = xfid->fid_ino;
+ igen = xfid->fid_gen;
/*
* NFS can sometimes send requests for ino 0. Fail them gracefully.
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h
index bc99e3eb7db..a592fe02a33 100644
--- a/fs/xfs/xfs_vfsops.h
+++ b/fs/xfs/xfs_vfsops.h
@@ -2,7 +2,7 @@
#define _XFS_VFSOPS_H 1
struct cred;
-struct fid;
+struct xfs_fid;
struct inode;
struct kstatfs;
struct xfs_mount;
@@ -17,7 +17,7 @@ int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp);
int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp,
bhv_vnode_t *vp);
int xfs_sync(struct xfs_mount *mp, int flags);
-int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp);
+int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid);
int xfs_parseargs(struct xfs_mount *mp, char *options,
struct xfs_mount_args *args, int update);
int xfs_showargs(struct xfs_mount *mp, struct seq_file *m);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 5e3c57ca998..efd5aff9eaf 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -3466,23 +3466,14 @@ std_return:
}
-/*
- * xfs_fid2
- *
- * A fid routine that takes a pointer to a previously allocated
- * fid structure (like xfs_fast_fid) but uses a 64 bit inode number.
- */
int
xfs_fid2(
xfs_inode_t *ip,
- fid_t *fidp)
+ xfs_fid_t *xfid)
{
- xfs_fid2_t *xfid = (xfs_fid2_t *)fidp;
-
vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address);
- ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t));
- xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len);
+ xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len);
xfid->fid_pad = 0;
/*
* use memcpy because the inode is a long long and there's no
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index f36e74f2f0c..b7e461c40cf 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -39,7 +39,7 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize,
int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry,
char *target_path, mode_t mode, bhv_vnode_t **vpp,
struct cred *credp);
-int xfs_fid2(struct xfs_inode *ip, fid_t *fidp);
+int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid);
int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype);
int xfs_inode_flush(struct xfs_inode *ip, int flags);
diff --git a/include/acpi/achware.h b/include/acpi/achware.h
index 9df275cf7bc..4053df94345 100644
--- a/include/acpi/achware.h
+++ b/include/acpi/achware.h
@@ -71,9 +71,9 @@ u32 acpi_hw_get_mode(void);
struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
acpi_status
-acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value);
+acpi_hw_register_read(u32 register_id, u32 * return_value);
-acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value);
+acpi_status acpi_hw_register_write(u32 register_id, u32 value);
acpi_status
acpi_hw_low_level_read(u32 width,
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 86aea44ce6d..7b74b60a68a 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -264,7 +264,6 @@ struct acpi_device_wakeup_flags {
struct acpi_device_wakeup_state {
u8 enabled:1;
- u8 active:1;
};
struct acpi_device_wakeup {
@@ -333,6 +332,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state);
int acpi_bus_set_power(acpi_handle handle, int state);
#ifdef CONFIG_ACPI_PROC_EVENT
int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data);
+int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data);
int acpi_bus_receive_event(struct acpi_bus_event *event);
#else
static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index 3d7ab9e0c9f..9512f0456ad 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -314,6 +314,8 @@ acpi_resource_to_address64(struct acpi_resource *resource,
*/
acpi_status acpi_get_register(u32 register_id, u32 * return_value);
+acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value);
+
acpi_status acpi_set_register(u32 register_id, u32 value);
acpi_status
diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h
index 4e5d3ca53a8..a1b1b2ee3e5 100644
--- a/include/acpi/actbl1.h
+++ b/include/acpi/actbl1.h
@@ -257,7 +257,8 @@ struct acpi_table_dbgp {
struct acpi_table_dmar {
struct acpi_table_header header; /* Common ACPI table header */
u8 width; /* Host Address Width */
- u8 reserved[11];
+ u8 flags;
+ u8 reserved[10];
};
/* DMAR subtable header */
@@ -265,8 +266,6 @@ struct acpi_table_dmar {
struct acpi_dmar_header {
u16 type;
u16 length;
- u8 flags;
- u8 reserved[3];
};
/* Values for subtable type in struct acpi_dmar_header */
@@ -274,13 +273,15 @@ struct acpi_dmar_header {
enum acpi_dmar_type {
ACPI_DMAR_TYPE_HARDWARE_UNIT = 0,
ACPI_DMAR_TYPE_RESERVED_MEMORY = 1,
- ACPI_DMAR_TYPE_RESERVED = 2 /* 2 and greater are reserved */
+ ACPI_DMAR_TYPE_ATSR = 2,
+ ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */
};
struct acpi_dmar_device_scope {
u8 entry_type;
u8 length;
- u8 segment;
+ u16 reserved;
+ u8 enumeration_id;
u8 bus;
};
@@ -290,7 +291,14 @@ enum acpi_dmar_scope_type {
ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0,
ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1,
ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2,
- ACPI_DMAR_SCOPE_TYPE_RESERVED = 3 /* 3 and greater are reserved */
+ ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3,
+ ACPI_DMAR_SCOPE_TYPE_HPET = 4,
+ ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */
+};
+
+struct acpi_dmar_pci_path {
+ u8 dev;
+ u8 fn;
};
/*
@@ -301,6 +309,9 @@ enum acpi_dmar_scope_type {
struct acpi_dmar_hardware_unit {
struct acpi_dmar_header header;
+ u8 flags;
+ u8 reserved;
+ u16 segment;
u64 address; /* Register Base Address */
};
@@ -312,7 +323,9 @@ struct acpi_dmar_hardware_unit {
struct acpi_dmar_reserved_memory {
struct acpi_dmar_header header;
- u64 address; /* 4_k aligned base address */
+ u16 reserved;
+ u16 segment;
+ u64 base_address; /* 4_k aligned base address */
u64 end_address; /* 4_k aligned limit address */
};
diff --git a/include/acpi/processor.h b/include/acpi/processor.h
index 99934a999e6..26d79f6db8a 100644
--- a/include/acpi/processor.h
+++ b/include/acpi/processor.h
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/cpu.h>
+#include <linux/cpuidle.h>
#include <asm/acpi.h>
@@ -75,7 +76,9 @@ struct acpi_processor_cx {
};
struct acpi_processor_power {
+ struct cpuidle_device dev;
struct acpi_processor_cx *state;
+ struct acpi_processor_cx *bm_state;
unsigned long bm_check_timestamp;
u32 default_state;
u32 bm_activity;
@@ -199,6 +202,7 @@ struct acpi_processor_flags {
u8 bm_check:1;
u8 has_cst:1;
u8 power_setup_done:1;
+ u8 bm_rld_set:1;
};
struct acpi_processor {
@@ -322,6 +326,7 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
struct acpi_device *device);
int acpi_processor_suspend(struct acpi_device * device, pm_message_t state);
int acpi_processor_resume(struct acpi_device * device);
+extern struct cpuidle_driver acpi_idle_driver;
/* in processor_thermal.c */
int acpi_processor_get_limit_info(struct acpi_processor *pr);
diff --git a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
index 381b4f5b4d5..9e19a704d48 100644
--- a/include/asm-alpha/bitops.h
+++ b/include/asm-alpha/bitops.h
@@ -1,6 +1,10 @@
#ifndef _ALPHA_BITOPS_H
#define _ALPHA_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/compiler.h>
#include <asm/barrier.h>
diff --git a/include/asm-alpha/ide.h b/include/asm-alpha/ide.h
index 2a5cc0b367a..b7bf68d0407 100644
--- a/include/asm-alpha/ide.h
+++ b/include/asm-alpha/ide.h
@@ -40,7 +40,6 @@ static inline unsigned long ide_default_io_base(int index)
}
}
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#ifdef CONFIG_PCI
diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h
index 917365405e8..440747ca634 100644
--- a/include/asm-alpha/scatterlist.h
+++ b/include/asm-alpha/scatterlist.h
@@ -5,7 +5,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-alpha/tlbflush.h b/include/asm-alpha/tlbflush.h
index 1ca3ed3bd6d..eefab3fb51a 100644
--- a/include/asm-alpha/tlbflush.h
+++ b/include/asm-alpha/tlbflush.h
@@ -92,17 +92,6 @@ flush_tlb_other(struct mm_struct *mm)
if (*mmc) *mmc = 0;
}
-/* Flush a specified range of user mapping page tables from TLB.
- Although Alpha uses VPTE caches, this can be a nop, as Alpha does
- not have finegrained tlb flushing, so it will flush VPTE stuff
- during next flush_tlb_range. */
-
-static inline void
-flush_tlb_pgtables(struct mm_struct *mm, unsigned long start,
- unsigned long end)
-{
-}
-
#ifndef CONFIG_SMP
/* Flush everything (kernel mapping may also have changed
due to vmalloc/vfree). */
diff --git a/include/asm-arm/arch-aaec2000/aaec2000.h b/include/asm-arm/arch-aaec2000/aaec2000.h
index 002227924b9..a6d1ee0980f 100644
--- a/include/asm-arm/arch-aaec2000/aaec2000.h
+++ b/include/asm-arm/arch-aaec2000/aaec2000.h
@@ -140,11 +140,11 @@
#define TIMER3_CLEAR __REG(0x80000e0c) /* Timer 3 Clear Register */
/* Timer Control register bits */
-#define TIMER_CTRL_ENABLE (1 << 7) /* Enable (Start° Timer */
+#define TIMER_CTRL_ENABLE (1 << 7) /* Enable (Start Timer) */
#define TIMER_CTRL_PERIODIC (1 << 6) /* Periodic Running Mode */
#define TIMER_CTRL_FREE_RUNNING (0 << 6) /* Normal Running Mode */
#define TIMER_CTRL_CLKSEL_508K (1 << 3) /* 508KHz Clock select (Timer 1, 2) */
-#define TIMER_CTRL_CLKSEL_2K (0 << 3) /* 2KHz Clock Select (Timer 1, 2)*/
+#define TIMER_CTRL_CLKSEL_2K (0 << 3) /* 2KHz Clock Select (Timer 1, 2) */
/* Power and State Control */
#define POWER_BASE __REG(0x80000400)
diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h
index c72f9d79417..eeeea90cd5a 100644
--- a/include/asm-arm/arch-ixp4xx/io.h
+++ b/include/asm-arm/arch-ixp4xx/io.h
@@ -17,9 +17,6 @@
#define IO_SPACE_LIMIT 0xffff0000
-#define BIT(x) ((1)<<(x))
-
-
extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h
index 52fe05895de..47a6b086eee 100644
--- a/include/asm-arm/bitops.h
+++ b/include/asm-arm/bitops.h
@@ -19,6 +19,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/system.h>
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 678134bf247..1eb8aac4322 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -401,7 +401,7 @@ extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enu
*
* On the SA-1111, a bug limits DMA to only certain regions of RAM.
* On the IXP425, the PCI inbound window is 64MB (256MB total RAM)
- * On some ADI engineering sytems, PCI inbound window is 32MB (12MB total RAM)
+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM)
*
* The following are helper functions used by the dmabounce subystem
*
diff --git a/include/asm-arm/ide.h b/include/asm-arm/ide.h
index 4f68c8a5a19..f348fcf3150 100644
--- a/include/asm-arm/ide.h
+++ b/include/asm-arm/ide.h
@@ -18,7 +18,6 @@
#endif
#if !defined(CONFIG_ARCH_L7200)
-# define IDE_ARCH_OBSOLETE_INIT
# ifdef CONFIG_ARCH_CLPS7500
# define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
# else
diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h
index de2f65eb42e..ca0a37d0340 100644
--- a/include/asm-arm/scatterlist.h
+++ b/include/asm-arm/scatterlist.h
@@ -5,7 +5,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page; /* buffer page */
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset; /* buffer offset */
dma_addr_t dma_address; /* dma address */
unsigned int length; /* length */
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index 71be4fded7e..8c6bc1bb9d1 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -463,11 +463,6 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
*/
extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte);
-/*
- * ARM processors do not cache TLB tables in RAM.
- */
-#define flush_tlb_pgtables(mm,start,end) do { } while (0)
-
#endif
#endif /* CONFIG_MMU */
diff --git a/include/asm-avr32/bitops.h b/include/asm-avr32/bitops.h
index f3faddfd46a..1a50b69b1a1 100644
--- a/include/asm-avr32/bitops.h
+++ b/include/asm-avr32/bitops.h
@@ -8,6 +8,10 @@
#ifndef __ASM_AVR32_BITOPS_H
#define __ASM_AVR32_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/byteorder.h>
#include <asm/system.h>
diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h
index c6d5ce3b3a2..377320e3bd1 100644
--- a/include/asm-avr32/scatterlist.h
+++ b/include/asm-avr32/scatterlist.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-avr32/tlbflush.h b/include/asm-avr32/tlbflush.h
index 730e268f81f..5bc7c88a577 100644
--- a/include/asm-avr32/tlbflush.h
+++ b/include/asm-avr32/tlbflush.h
@@ -19,7 +19,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void flush_tlb(void);
extern void flush_tlb_all(void);
@@ -29,12 +28,6 @@ extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
extern void __flush_tlb_page(unsigned long asid, unsigned long page);
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* Nothing to do */
-}
-
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
#endif /* __ASM_AVR32_TLBFLUSH_H */
diff --git a/include/asm-blackfin/bf5xx_timers.h b/include/asm-blackfin/bf5xx_timers.h
deleted file mode 100644
index 86c770321b6..00000000000
--- a/include/asm-blackfin/bf5xx_timers.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * include/asm/bf5xx_timers.h
- *
- * This file contains the major Data structures and constants
- * used for General Purpose Timer Implementation in BF5xx
- *
- * Copyright (C) 2005 John DeHority
- * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
- *
- */
-
-#ifndef _BLACKFIN_TIMERS_H_
-#define _BLACKFIN_TIMERS_H_
-
-#undef MAX_BLACKFIN_GPTIMERS
-/*
- * BF537: 8 timers:
- */
-#if defined(CONFIG_BF537)
-# define MAX_BLACKFIN_GPTIMERS 8
-# define TIMER0_GROUP_REG TIMER_ENABLE
-#endif
-/*
- * BF561: 12 timers:
- */
-#if defined(CONFIG_BF561)
-# define MAX_BLACKFIN_GPTIMERS 12
-# define TIMER0_GROUP_REG TMRS8_ENABLE
-# define TIMER8_GROUP_REG TMRS4_ENABLE
-#endif
-/*
- * All others: 3 timers:
- */
-#if !defined(MAX_BLACKFIN_GPTIMERS)
-# define MAX_BLACKFIN_GPTIMERS 3
-# define TIMER0_GROUP_REG TIMER_ENABLE
-#endif
-
-#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
-#define BFIN_TIMER_OCTET(x) ((x) >> 3)
-
-/* used in masks for timer_enable() and timer_disable() */
-#define TIMER0bit 0x0001 /* 0001b */
-#define TIMER1bit 0x0002 /* 0010b */
-#define TIMER2bit 0x0004 /* 0100b */
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-# define TIMER3bit 0x0008
-# define TIMER4bit 0x0010
-# define TIMER5bit 0x0020
-# define TIMER6bit 0x0040
-# define TIMER7bit 0x0080
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-# define TIMER8bit 0x0100
-# define TIMER9bit 0x0200
-# define TIMER10bit 0x0400
-# define TIMER11bit 0x0800
-#endif
-
-#define TIMER0_id 0
-#define TIMER1_id 1
-#define TIMER2_id 2
-
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-# define TIMER3_id 3
-# define TIMER4_id 4
-# define TIMER5_id 5
-# define TIMER6_id 6
-# define TIMER7_id 7
-#endif
-
-#if (MAX_BLACKFIN_GPTIMERS > 8)
-# define TIMER8_id 8
-# define TIMER9_id 9
-# define TIMER10_id 10
-# define TIMER11_id 11
-#endif
-
-/* associated timers for ppi framesync: */
-
-#if defined(CONFIG_BF561)
-# define FS0_1_TIMER_ID TIMER8_id
-# define FS0_2_TIMER_ID TIMER9_id
-# define FS1_1_TIMER_ID TIMER10_id
-# define FS1_2_TIMER_ID TIMER11_id
-# define FS0_1_TIMER_BIT TIMER8bit
-# define FS0_2_TIMER_BIT TIMER9bit
-# define FS1_1_TIMER_BIT TIMER10bit
-# define FS1_2_TIMER_BIT TIMER11bit
-# undef FS1_TIMER_ID
-# undef FS2_TIMER_ID
-# undef FS1_TIMER_BIT
-# undef FS2_TIMER_BIT
-#else
-# define FS1_TIMER_ID TIMER0_id
-# define FS2_TIMER_ID TIMER1_id
-# define FS1_TIMER_BIT TIMER0bit
-# define FS2_TIMER_BIT TIMER1bit
-#endif
-
-/*
-** Timer Configuration Register Bits
-*/
-#define TIMER_ERR 0xC000
-#define TIMER_ERR_OVFL 0x4000
-#define TIMER_ERR_PROG_PER 0x8000
-#define TIMER_ERR_PROG_PW 0xC000
-#define TIMER_EMU_RUN 0x0200
-#define TIMER_TOGGLE_HI 0x0100
-#define TIMER_CLK_SEL 0x0080
-#define TIMER_OUT_DIS 0x0040
-#define TIMER_TIN_SEL 0x0020
-#define TIMER_IRQ_ENA 0x0010
-#define TIMER_PERIOD_CNT 0x0008
-#define TIMER_PULSE_HI 0x0004
-#define TIMER_MODE 0x0003
-#define TIMER_MODE_PWM 0x0001
-#define TIMER_MODE_WDTH 0x0002
-#define TIMER_MODE_EXT_CLK 0x0003
-
-/*
-** Timer Status Register Bits
-*/
-#define TIMER_STATUS_TIMIL0 0x0001
-#define TIMER_STATUS_TIMIL1 0x0002
-#define TIMER_STATUS_TIMIL2 0x0004
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-# define TIMER_STATUS_TIMIL3 0x00000008
-# define TIMER_STATUS_TIMIL4 0x00010000
-# define TIMER_STATUS_TIMIL5 0x00020000
-# define TIMER_STATUS_TIMIL6 0x00040000
-# define TIMER_STATUS_TIMIL7 0x00080000
-# if (MAX_BLACKFIN_GPTIMERS > 8)
-# define TIMER_STATUS_TIMIL8 0x0001
-# define TIMER_STATUS_TIMIL9 0x0002
-# define TIMER_STATUS_TIMIL10 0x0004
-# define TIMER_STATUS_TIMIL11 0x0008
-# endif
-# define TIMER_STATUS_INTR 0x000F000F
-#else
-# define TIMER_STATUS_INTR 0x0007 /* any timer interrupt */
-#endif
-
-#define TIMER_STATUS_TOVF0 0x0010 /* timer 0 overflow error */
-#define TIMER_STATUS_TOVF1 0x0020
-#define TIMER_STATUS_TOVF2 0x0040
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-# define TIMER_STATUS_TOVF3 0x00000080
-# define TIMER_STATUS_TOVF4 0x00100000
-# define TIMER_STATUS_TOVF5 0x00200000
-# define TIMER_STATUS_TOVF6 0x00400000
-# define TIMER_STATUS_TOVF7 0x00800000
-# if (MAX_BLACKFIN_GPTIMERS > 8)
-# define TIMER_STATUS_TOVF8 0x0010
-# define TIMER_STATUS_TOVF9 0x0020
-# define TIMER_STATUS_TOVF10 0x0040
-# define TIMER_STATUS_TOVF11 0x0080
-# endif
-# define TIMER_STATUS_OFLOW 0x00F000F0
-#else
-# define TIMER_STATUS_OFLOW 0x0070 /* any timer overflow */
-#endif
-
-/*
-** Timer Slave Enable Status : write 1 to clear
-*/
-#define TIMER_STATUS_TRUN0 0x1000
-#define TIMER_STATUS_TRUN1 0x2000
-#define TIMER_STATUS_TRUN2 0x4000
-#if (MAX_BLACKFIN_GPTIMERS > 3)
-# define TIMER_STATUS_TRUN3 0x00008000
-# define TIMER_STATUS_TRUN4 0x10000000
-# define TIMER_STATUS_TRUN5 0x20000000
-# define TIMER_STATUS_TRUN6 0x40000000
-# define TIMER_STATUS_TRUN7 0x80000000
-# define TIMER_STATUS_TRUN 0xF000F000
-# if (MAX_BLACKFIN_GPTIMERS > 8)
-# define TIMER_STATUS_TRUN8 0x1000
-# define TIMER_STATUS_TRUN9 0x2000
-# define TIMER_STATUS_TRUN10 0x4000
-# define TIMER_STATUS_TRUN11 0x8000
-# endif
-#else
-# define TIMER_STATUS_TRUN 0x7000
-#endif
-
-/*******************************************************************************
-* GP_TIMER API's
-*******************************************************************************/
-
-void set_gptimer_pwidth (int timer_id, int width);
-int get_gptimer_pwidth (int timer_id);
-void set_gptimer_period (int timer_id, int period);
-int get_gptimer_period (int timer_id);
-int get_gptimer_count (int timer_id);
-short get_gptimer_intr (int timer_id);
-void set_gptimer_config (int timer_id, short config);
-short get_gptimer_config (int timer_id);
-void set_gptimer_pulse_hi (int timer_id);
-void clear_gptimer_pulse_hi(int timer_id);
-void enable_gptimers (short mask);
-void disable_gptimers (short mask);
-short get_enabled_timers (void);
-int get_gptimer_status (int octet);
-void set_gptimer_status (int octet, int value);
-
-#endif
diff --git a/include/asm-blackfin/bfin-global.h b/include/asm-blackfin/bfin-global.h
index a970781a0f9..14cb8d35924 100644
--- a/include/asm-blackfin/bfin-global.h
+++ b/include/asm-blackfin/bfin-global.h
@@ -47,6 +47,8 @@
extern unsigned long get_cclk(void);
extern unsigned long get_sclk(void);
+extern unsigned long sclk_to_usecs(unsigned long sclk);
+extern unsigned long usecs_to_sclk(unsigned long usecs);
extern void dump_thread(struct pt_regs *regs, struct user *dump);
extern void dump_bfin_regs(struct pt_regs *fp, void *retaddr);
@@ -105,7 +107,7 @@ extern void led_disp_num(int);
extern void led_toggle_num(int);
extern void init_leds(void);
-extern char *bfin_board_name __attribute__ ((weak));
+extern const char bfin_board_name[];
extern unsigned long wall_jiffies;
extern unsigned long ipdt_table[];
extern unsigned long dpdt_table[];
diff --git a/include/asm-blackfin/bitops.h b/include/asm-blackfin/bitops.h
index 03ecedc1f2a..b39a175c79c 100644
--- a/include/asm-blackfin/bitops.h
+++ b/include/asm-blackfin/bitops.h
@@ -11,6 +11,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/sched.h>
diff --git a/include/asm-blackfin/dma.h b/include/asm-blackfin/dma.h
index b42a531e7a1..b469505af36 100644
--- a/include/asm-blackfin/dma.h
+++ b/include/asm-blackfin/dma.h
@@ -109,9 +109,7 @@ struct dma_register {
unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer
register */
- unsigned short curr_addr_ptr_lo; /* DMA Current Address Pointer
- register */
- unsigned short curr_addr_ptr_hi; /* DMA Current Address Pointer
+ unsigned long curr_addr_ptr; /* DMA Current Address Pointer
register */
unsigned short irq_status; /* DMA irq status register */
unsigned short dummy6;
@@ -166,6 +164,9 @@ void set_dma_curr_addr(unsigned int channel, unsigned long addr);
unsigned short get_dma_curr_irqstat(unsigned int channel);
unsigned short get_dma_curr_xcount(unsigned int channel);
unsigned short get_dma_curr_ycount(unsigned int channel);
+unsigned long get_dma_next_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_desc_ptr(unsigned int channel);
+unsigned long get_dma_curr_addr(unsigned int channel);
/* set large DMA mode descriptor */
void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg);
diff --git a/include/asm-blackfin/gpio.h b/include/asm-blackfin/gpio.h
index dd203cd9379..33ce98ef7e0 100644
--- a/include/asm-blackfin/gpio.h
+++ b/include/asm-blackfin/gpio.h
@@ -29,6 +29,7 @@
/*
* Number BF537/6/4 BF561 BF533/2/1
+* BF527/5/2
*
* GPIO_0 PF0 PF0 PF0
* GPIO_1 PF1 PF1 PF1
@@ -164,7 +165,7 @@
#endif
-#ifdef BF537_FAMILY
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
#define MAX_BLACKFIN_GPIOS 48
#define GPIO_PF0 0
diff --git a/include/asm-blackfin/gptimers.h b/include/asm-blackfin/gptimers.h
new file mode 100644
index 00000000000..c97ab03e43a
--- /dev/null
+++ b/include/asm-blackfin/gptimers.h
@@ -0,0 +1,210 @@
+/*
+ * include/asm/bf5xx_timers.h
+ *
+ * This file contains the major Data structures and constants
+ * used for General Purpose Timer Implementation in BF5xx
+ *
+ * Copyright (C) 2005 John DeHority
+ * Copyright (C) 2006 Hella Aglaia GmbH (awe@aglaia-gmbh.de)
+ *
+ */
+
+#ifndef _BLACKFIN_TIMERS_H_
+#define _BLACKFIN_TIMERS_H_
+
+#include <linux/types.h>
+#include <asm/blackfin.h>
+
+/*
+ * BF537/BF527: 8 timers:
+ */
+#if defined(BF527_FAMILY) || defined(BF537_FAMILY)
+# define MAX_BLACKFIN_GPTIMERS 8
+# define TIMER0_GROUP_REG TIMER_ENABLE
+#endif
+/*
+ * BF561: 12 timers:
+ */
+#if defined(CONFIG_BF561)
+# define MAX_BLACKFIN_GPTIMERS 12
+# define TIMER0_GROUP_REG TMRS8_ENABLE
+# define TIMER8_GROUP_REG TMRS4_ENABLE
+#endif
+/*
+ * All others: 3 timers:
+ */
+#if !defined(MAX_BLACKFIN_GPTIMERS)
+# define MAX_BLACKFIN_GPTIMERS 3
+# define TIMER0_GROUP_REG TIMER_ENABLE
+#endif
+
+#define BLACKFIN_GPTIMER_IDMASK ((1UL << MAX_BLACKFIN_GPTIMERS) - 1)
+#define BFIN_TIMER_OCTET(x) ((x) >> 3)
+
+/* used in masks for timer_enable() and timer_disable() */
+#define TIMER0bit 0x0001 /* 0001b */
+#define TIMER1bit 0x0002 /* 0010b */
+#define TIMER2bit 0x0004 /* 0100b */
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3bit 0x0008
+# define TIMER4bit 0x0010
+# define TIMER5bit 0x0020
+# define TIMER6bit 0x0040
+# define TIMER7bit 0x0080
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8bit 0x0100
+# define TIMER9bit 0x0200
+# define TIMER10bit 0x0400
+# define TIMER11bit 0x0800
+#endif
+
+#define TIMER0_id 0
+#define TIMER1_id 1
+#define TIMER2_id 2
+
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER3_id 3
+# define TIMER4_id 4
+# define TIMER5_id 5
+# define TIMER6_id 6
+# define TIMER7_id 7
+#endif
+
+#if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER8_id 8
+# define TIMER9_id 9
+# define TIMER10_id 10
+# define TIMER11_id 11
+#endif
+
+/* associated timers for ppi framesync: */
+
+#if defined(CONFIG_BF561)
+# define FS0_1_TIMER_ID TIMER8_id
+# define FS0_2_TIMER_ID TIMER9_id
+# define FS1_1_TIMER_ID TIMER10_id
+# define FS1_2_TIMER_ID TIMER11_id
+# define FS0_1_TIMER_BIT TIMER8bit
+# define FS0_2_TIMER_BIT TIMER9bit
+# define FS1_1_TIMER_BIT TIMER10bit
+# define FS1_2_TIMER_BIT TIMER11bit
+# undef FS1_TIMER_ID
+# undef FS2_TIMER_ID
+# undef FS1_TIMER_BIT
+# undef FS2_TIMER_BIT
+#else
+# define FS1_TIMER_ID TIMER0_id
+# define FS2_TIMER_ID TIMER1_id
+# define FS1_TIMER_BIT TIMER0bit
+# define FS2_TIMER_BIT TIMER1bit
+#endif
+
+/*
+ * Timer Configuration Register Bits
+ */
+#define TIMER_ERR 0xC000
+#define TIMER_ERR_OVFL 0x4000
+#define TIMER_ERR_PROG_PER 0x8000
+#define TIMER_ERR_PROG_PW 0xC000
+#define TIMER_EMU_RUN 0x0200
+#define TIMER_TOGGLE_HI 0x0100
+#define TIMER_CLK_SEL 0x0080
+#define TIMER_OUT_DIS 0x0040
+#define TIMER_TIN_SEL 0x0020
+#define TIMER_IRQ_ENA 0x0010
+#define TIMER_PERIOD_CNT 0x0008
+#define TIMER_PULSE_HI 0x0004
+#define TIMER_MODE 0x0003
+#define TIMER_MODE_PWM 0x0001
+#define TIMER_MODE_WDTH 0x0002
+#define TIMER_MODE_EXT_CLK 0x0003
+
+/*
+ * Timer Status Register Bits
+ */
+#define TIMER_STATUS_TIMIL0 0x0001
+#define TIMER_STATUS_TIMIL1 0x0002
+#define TIMER_STATUS_TIMIL2 0x0004
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TIMIL3 0x00000008
+# define TIMER_STATUS_TIMIL4 0x00010000
+# define TIMER_STATUS_TIMIL5 0x00020000
+# define TIMER_STATUS_TIMIL6 0x00040000
+# define TIMER_STATUS_TIMIL7 0x00080000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TIMIL8 0x0001
+# define TIMER_STATUS_TIMIL9 0x0002
+# define TIMER_STATUS_TIMIL10 0x0004
+# define TIMER_STATUS_TIMIL11 0x0008
+# endif
+# define TIMER_STATUS_INTR 0x000F000F
+#else
+# define TIMER_STATUS_INTR 0x0007 /* any timer interrupt */
+#endif
+
+#define TIMER_STATUS_TOVF0 0x0010 /* timer 0 overflow error */
+#define TIMER_STATUS_TOVF1 0x0020
+#define TIMER_STATUS_TOVF2 0x0040
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TOVF3 0x00000080
+# define TIMER_STATUS_TOVF4 0x00100000
+# define TIMER_STATUS_TOVF5 0x00200000
+# define TIMER_STATUS_TOVF6 0x00400000
+# define TIMER_STATUS_TOVF7 0x00800000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TOVF8 0x0010
+# define TIMER_STATUS_TOVF9 0x0020
+# define TIMER_STATUS_TOVF10 0x0040
+# define TIMER_STATUS_TOVF11 0x0080
+# endif
+# define TIMER_STATUS_OFLOW 0x00F000F0
+#else
+# define TIMER_STATUS_OFLOW 0x0070 /* any timer overflow */
+#endif
+
+/*
+ * Timer Slave Enable Status : write 1 to clear
+ */
+#define TIMER_STATUS_TRUN0 0x1000
+#define TIMER_STATUS_TRUN1 0x2000
+#define TIMER_STATUS_TRUN2 0x4000
+#if (MAX_BLACKFIN_GPTIMERS > 3)
+# define TIMER_STATUS_TRUN3 0x00008000
+# define TIMER_STATUS_TRUN4 0x10000000
+# define TIMER_STATUS_TRUN5 0x20000000
+# define TIMER_STATUS_TRUN6 0x40000000
+# define TIMER_STATUS_TRUN7 0x80000000
+# define TIMER_STATUS_TRUN 0xF000F000
+# if (MAX_BLACKFIN_GPTIMERS > 8)
+# define TIMER_STATUS_TRUN8 0x1000
+# define TIMER_STATUS_TRUN9 0x2000
+# define TIMER_STATUS_TRUN10 0x4000
+# define TIMER_STATUS_TRUN11 0x8000
+# endif
+#else
+# define TIMER_STATUS_TRUN 0x7000
+#endif
+
+/* The actual gptimer API */
+
+void set_gptimer_pwidth (int timer_id, uint32_t width);
+uint32_t get_gptimer_pwidth (int timer_id);
+void set_gptimer_period (int timer_id, uint32_t period);
+uint32_t get_gptimer_period (int timer_id);
+uint32_t get_gptimer_count (int timer_id);
+uint16_t get_gptimer_intr (int timer_id);
+void clear_gptimer_intr (int timer_id);
+void set_gptimer_config (int timer_id, uint16_t config);
+uint16_t get_gptimer_config (int timer_id);
+void set_gptimer_pulse_hi (int timer_id);
+void clear_gptimer_pulse_hi(int timer_id);
+void enable_gptimers (uint16_t mask);
+void disable_gptimers (uint16_t mask);
+uint16_t get_enabled_gptimers (void);
+uint32_t get_gptimer_status (int group);
+void set_gptimer_status (int group, uint32_t value);
+
+#endif
diff --git a/include/asm-blackfin/ide.h b/include/asm-blackfin/ide.h
index 41b2db46a16..121e272581d 100644
--- a/include/asm-blackfin/ide.h
+++ b/include/asm-blackfin/ide.h
@@ -20,7 +20,6 @@
#define MAX_HWIFS 1
/* Legacy ... BLK_DEV_IDECS */
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
diff --git a/include/asm-blackfin/mach-bf527/anomaly.h b/include/asm-blackfin/mach-bf527/anomaly.h
index 991db986cd4..a89120445be 100644
--- a/include/asm-blackfin/mach-bf527/anomaly.h
+++ b/include/asm-blackfin/mach-bf527/anomaly.h
@@ -38,4 +38,12 @@
/* Anomalies that don't exist on this proc */
#define ANOMALY_05000323 (0)
+#define ANOMALY_05000244 (0)
+#define ANOMALY_05000198 (0)
+#define ANOMALY_05000125 (0)
+#define ANOMALY_05000158 (0)
+#define ANOMALY_05000273 (0)
+#define ANOMALY_05000263 (0)
+#define ANOMALY_05000311 (0)
+#define ANOMALY_05000230 (0)
#endif
diff --git a/include/asm-blackfin/mach-bf527/bf527.h b/include/asm-blackfin/mach-bf527/bf527.h
new file mode 100644
index 00000000000..056eb4b9cd2
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/bf527.h
@@ -0,0 +1,127 @@
+/*
+ * File: include/asm-blackfin/mach-bf527/bf527.h
+ * Based on: include/asm-blackfin/mach-bf537/bf537.h
+ * Author: Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * Created:
+ * Description: SYSTEM MMR REGISTER AND MEMORY MAP FOR ADSP-BF527
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see the file COPYING, or write
+ * to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __MACH_BF527_H__
+#define __MACH_BF527_H__
+
+#define SUPPORTED_REVID 2
+
+#define OFFSET_(x) ((x) & 0x0000FFFF)
+
+/*some misc defines*/
+#define IMASK_IVG15 0x8000
+#define IMASK_IVG14 0x4000
+#define IMASK_IVG13 0x2000
+#define IMASK_IVG12 0x1000
+
+#define IMASK_IVG11 0x0800
+#define IMASK_IVG10 0x0400
+#define IMASK_IVG9 0x0200
+#define IMASK_IVG8 0x0100
+
+#define IMASK_IVG7 0x0080
+#define IMASK_IVGTMR 0x0040
+#define IMASK_IVGHW 0x0020
+
+/***************************/
+
+#define BFIN_DSUBBANKS 4
+#define BFIN_DWAYS 2
+#define BFIN_DLINES 64
+#define BFIN_ISUBBANKS 4
+#define BFIN_IWAYS 4
+#define BFIN_ILINES 32
+
+#define WAY0_L 0x1
+#define WAY1_L 0x2
+#define WAY01_L 0x3
+#define WAY2_L 0x4
+#define WAY02_L 0x5
+#define WAY12_L 0x6
+#define WAY012_L 0x7
+
+#define WAY3_L 0x8
+#define WAY03_L 0x9
+#define WAY13_L 0xA
+#define WAY013_L 0xB
+
+#define WAY32_L 0xC
+#define WAY320_L 0xD
+#define WAY321_L 0xE
+#define WAYALL_L 0xF
+
+#define DMC_ENABLE (2<<2) /*yes, 2, not 1 */
+
+/********************************* EBIU Settings ************************************/
+#define AMBCTL0VAL ((CONFIG_BANK_1 << 16) | CONFIG_BANK_0)
+#define AMBCTL1VAL ((CONFIG_BANK_3 << 16) | CONFIG_BANK_2)
+
+#ifdef CONFIG_C_AMBEN_ALL
+#define V_AMBEN AMBEN_ALL
+#endif
+#ifdef CONFIG_C_AMBEN
+#define V_AMBEN 0x0
+#endif
+#ifdef CONFIG_C_AMBEN_B0
+#define V_AMBEN AMBEN_B0
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1
+#define V_AMBEN AMBEN_B0_B1
+#endif
+#ifdef CONFIG_C_AMBEN_B0_B1_B2
+#define V_AMBEN AMBEN_B0_B1_B2
+#endif
+#ifdef CONFIG_C_AMCKEN
+#define V_AMCKEN AMCKEN
+#else
+#define V_AMCKEN 0x0
+#endif
+#ifdef CONFIG_C_CDPRIO
+#define V_CDPRIO 0x100
+#else
+#define V_CDPRIO 0x0
+#endif
+
+#define AMGCTLVAL (V_AMBEN | V_AMCKEN | V_CDPRIO)
+
+#ifdef CONFIG_BF527
+#define CPU "BF527"
+#endif
+#ifdef CONFIG_BF525
+#define CPU "BF525"
+#endif
+#ifdef CONFIG_BF522
+#define CPU "BF522"
+#endif
+#ifndef CPU
+#define CPU "UNKNOWN"
+#define CPUID 0x0
+#endif
+
+#endif /* __MACH_BF527_H__ */
diff --git a/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
new file mode 100644
index 00000000000..0b867e6a76c
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h
@@ -0,0 +1,152 @@
+#include <linux/serial.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+
+#define NR_PORTS 2
+
+#define OFFSET_THR 0x00 /* Transmit Holding register */
+#define OFFSET_RBR 0x00 /* Receive Buffer register */
+#define OFFSET_DLL 0x00 /* Divisor Latch (Low-Byte) */
+#define OFFSET_IER 0x04 /* Interrupt Enable Register */
+#define OFFSET_DLH 0x04 /* Divisor Latch (High-Byte) */
+#define OFFSET_IIR 0x08 /* Interrupt Identification Register */
+#define OFFSET_LCR 0x0C /* Line Control Register */
+#define OFFSET_MCR 0x10 /* Modem Control Register */
+#define OFFSET_LSR 0x14 /* Line Status Register */
+#define OFFSET_MSR 0x18 /* Modem Status Register */
+#define OFFSET_SCR 0x1C /* SCR Scratch Register */
+#define OFFSET_GCTL 0x24 /* Global Control Register */
+
+#define UART_GET_CHAR(uart) bfin_read16(((uart)->port.membase + OFFSET_RBR))
+#define UART_GET_DLL(uart) bfin_read16(((uart)->port.membase + OFFSET_DLL))
+#define UART_GET_IER(uart) bfin_read16(((uart)->port.membase + OFFSET_IER))
+#define UART_GET_DLH(uart) bfin_read16(((uart)->port.membase + OFFSET_DLH))
+#define UART_GET_IIR(uart) bfin_read16(((uart)->port.membase + OFFSET_IIR))
+#define UART_GET_LCR(uart) bfin_read16(((uart)->port.membase + OFFSET_LCR))
+#define UART_GET_LSR(uart) bfin_read16(((uart)->port.membase + OFFSET_LSR))
+#define UART_GET_GCTL(uart) bfin_read16(((uart)->port.membase + OFFSET_GCTL))
+
+#define UART_PUT_CHAR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_THR), v)
+#define UART_PUT_DLL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLL), v)
+#define UART_PUT_IER(uart, v) bfin_write16(((uart)->port.membase + OFFSET_IER), v)
+#define UART_PUT_DLH(uart, v) bfin_write16(((uart)->port.membase + OFFSET_DLH), v)
+#define UART_PUT_LCR(uart, v) bfin_write16(((uart)->port.membase + OFFSET_LCR), v)
+#define UART_PUT_GCTL(uart, v) bfin_write16(((uart)->port.membase + OFFSET_GCTL), v)
+
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
+# define CONFIG_SERIAL_BFIN_CTSRTS
+
+# ifndef CONFIG_UART0_CTS_PIN
+# define CONFIG_UART0_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART0_RTS_PIN
+# define CONFIG_UART0_RTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_CTS_PIN
+# define CONFIG_UART1_CTS_PIN -1
+# endif
+
+# ifndef CONFIG_UART1_RTS_PIN
+# define CONFIG_UART1_RTS_PIN -1
+# endif
+#endif
+/*
+ * The pin configuration is different from schematic
+ */
+struct bfin_serial_port {
+ struct uart_port port;
+ unsigned int old_status;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ int tx_done;
+ int tx_count;
+ struct circ_buf rx_dma_buf;
+ struct timer_list rx_dma_timer;
+ int rx_dma_nrows;
+ unsigned int tx_dma_channel;
+ unsigned int rx_dma_channel;
+ struct work_struct tx_dma_workqueue;
+#else
+ struct work_struct cts_workqueue;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int cts_pin;
+ int rts_pin;
+#endif
+};
+
+struct bfin_serial_port bfin_serial_ports[NR_PORTS];
+struct bfin_serial_res {
+ unsigned long uart_base_addr;
+ int uart_irq;
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ unsigned int uart_tx_dma_channel;
+ unsigned int uart_rx_dma_channel;
+#endif
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
+#endif
+};
+
+struct bfin_serial_res bfin_serial_resource[] = {
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ {
+ 0xFFC00400,
+ IRQ_UART0_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART0_TX,
+ CH_UART0_RX,
+#endif
+#ifdef CONFIG_BFIN_UART0_CTSRTS
+ CONFIG_UART0_CTS_PIN,
+ CONFIG_UART0_RTS_PIN,
+#endif
+ },
+#endif
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ {
+ 0xFFC02000,
+ IRQ_UART1_RX,
+#ifdef CONFIG_SERIAL_BFIN_DMA
+ CH_UART1_TX,
+ CH_UART1_RX,
+#endif
+#ifdef CONFIG_BFIN_UART1_CTSRTS
+ CONFIG_UART1_CTS_PIN,
+ CONFIG_UART1_RTS_PIN,
+#endif
+ },
+#endif
+};
+
+int nr_ports = ARRAY_SIZE(bfin_serial_resource);
+
+#define DRIVER_NAME "bfin-uart"
+
+static void bfin_serial_hw_init(struct bfin_serial_port *uart)
+{
+
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ peripheral_request(P_UART0_TX, DRIVER_NAME);
+ peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ peripheral_request(P_UART1_TX, DRIVER_NAME);
+ peripheral_request(P_UART1_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, DRIVER_NAME);
+ gpio_direction_input(uart->cts_pin);
+ }
+
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->rts_pin);
+ }
+#endif
+}
diff --git a/include/asm-blackfin/mach-bf527/blackfin.h b/include/asm-blackfin/mach-bf527/blackfin.h
new file mode 100644
index 00000000000..1bd07e30781
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/blackfin.h
@@ -0,0 +1,78 @@
+/*
+ * File: include/asm-blackfin/mach-bf527/blackfin.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ *
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MACH_BLACKFIN_H_
+#define _MACH_BLACKFIN_H_
+
+#define BF527_FAMILY
+
+#include "bf527.h"
+#include "mem_map.h"
+#include "defBF522.h"
+#include "anomaly.h"
+
+#if defined(CONFIG_BF527)
+#include "defBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "defBF525.h"
+#endif
+
+#if !defined(__ASSEMBLY__)
+#include "cdefBF522.h"
+
+#if defined(CONFIG_BF527)
+#include "cdefBF527.h"
+#endif
+
+#if defined(CONFIG_BF525)
+#include "cdefBF525.h"
+#endif
+#endif
+
+/* UART_IIR Register */
+#define STATUS(x) ((x << 1) & 0x06)
+#define STATUS_P1 0x02
+#define STATUS_P0 0x01
+
+/* DPMC*/
+#define bfin_read_STOPCK_OFF() bfin_read_STOPCK()
+#define bfin_write_STOPCK_OFF(val) bfin_write_STOPCK(val)
+#define STOPCK_OFF STOPCK
+
+/* PLL_DIV Masks */
+#define CCLK_DIV1 CSEL_DIV1 /* CCLK = VCO / 1 */
+#define CCLK_DIV2 CSEL_DIV2 /* CCLK = VCO / 2 */
+#define CCLK_DIV4 CSEL_DIV4 /* CCLK = VCO / 4 */
+#define CCLK_DIV8 CSEL_DIV8 /* CCLK = VCO / 8 */
+
+#endif
diff --git a/include/asm-blackfin/mach-bf527/cdefBF52x_base.h b/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
index 5f801a0ef79..3f4de5d9d4c 100644
--- a/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
+++ b/include/asm-blackfin/mach-bf527/cdefBF52x_base.h
@@ -45,8 +45,8 @@
#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT, val)
#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT)
#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT, val)
-#define bfin_read_CHIPID() bfin_read16(CHIPID)
-#define bfin_write_CHIPID(val) bfin_write16(CHIPID, val)
+#define bfin_read_CHIPID() bfin_read32(CHIPID)
+#define bfin_write_CHIPID(val) bfin_write32(CHIPID, val)
/* System Interrupt Controller (0xFFC00100 - 0xFFC001FF) */
@@ -59,9 +59,8 @@
#define bfin_write_SIC_RVECT(val) bfin_write32(SIC_RVECT, val)
#define bfin_read_SIC_IMASK0() bfin_read32(SIC_IMASK0)
#define bfin_write_SIC_IMASK0(val) bfin_write32(SIC_IMASK0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IMASK() bfin_read32(SIC_IMASK)
-#define bfin_write_SIC_IMASK(val) bfin_write32(SIC_IMASK, val)
+#define bfin_read_SIC_IMASK(x) bfin_read32(SIC_IMASK0 + (x << 6))
+#define bfin_write_SIC_IMASK(x, val) bfin_write32((SIC_IMASK0 + (x << 6)), val)
#define bfin_read_SIC_IAR0() bfin_read32(SIC_IAR0)
#define bfin_write_SIC_IAR0(val) bfin_write32(SIC_IAR0, val)
@@ -74,15 +73,13 @@
#define bfin_read_SIC_ISR0() bfin_read32(SIC_ISR0)
#define bfin_write_SIC_ISR0(val) bfin_write32(SIC_ISR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_ISR() bfin_read32(SIC_ISR)
-#define bfin_write_SIC_ISR(val) bfin_write32(SIC_ISR, val)
+#define bfin_read_SIC_ISR(x) bfin_read32(SIC_ISR0 + (x << 6))
+#define bfin_write_SIC_ISR(x, val) bfin_write32((SIC_ISR0 + (x << 6)), val)
#define bfin_read_SIC_IWR0() bfin_read32(SIC_IWR0)
#define bfin_write_SIC_IWR0(val) bfin_write32(SIC_IWR0, val)
-/* legacy register name (below) provided for backwards code compatibility */
-#define bfin_read_SIC_IWR() bfin_read32(SIC_IWR)
-#define bfin_write_SIC_IWR(val) bfin_write32(SIC_IWR, val)
+#define bfin_read_SIC_IWR(x) bfin_read32(SIC_IWR0 + (x << 6))
+#define bfin_write_SIC_IWR(x, val) bfin_write32((SIC_IWR0 + (x << 6)), val)
/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
diff --git a/include/asm-blackfin/mach-bf527/defBF527.h b/include/asm-blackfin/mach-bf527/defBF527.h
index 2be3293f9e2..82134f578f3 100644
--- a/include/asm-blackfin/mach-bf527/defBF527.h
+++ b/include/asm-blackfin/mach-bf527/defBF527.h
@@ -32,12 +32,12 @@
#define _DEF_BF527_H
/* Include all Core registers and bit definitions */
-#include <def_LPBlackfin.h>
+#include <asm/mach-common/def_LPBlackfin.h>
/* SYSTEM & MMR ADDRESS DEFINITIONS FOR ADSP-BF527 */
/* Include defBF52x_base.h for the set of #defines that are common to all ADSP-BF52x processors */
-#include <defBF52x_base.h>
+#include "defBF52x_base.h"
/* The following are the #defines needed by ADSP-BF527 that are not in the common header */
/* 10/100 Ethernet Controller (0xFFC03000 - 0xFFC031FF) */
diff --git a/include/asm-blackfin/mach-bf527/defBF52x_base.h b/include/asm-blackfin/mach-bf527/defBF52x_base.h
index b1ff67db01f..d6c24c54699 100644
--- a/include/asm-blackfin/mach-bf527/defBF52x_base.h
+++ b/include/asm-blackfin/mach-bf527/defBF52x_base.h
@@ -52,13 +52,13 @@
#define SYSCR 0xFFC00104 /* System Configuration Register */
#define SIC_RVECT 0xFFC00108 /* Interrupt Reset Vector Address Register */
-#define SIC_IMASK 0xFFC0010C /* Interrupt Mask Register */
+#define SIC_IMASK0 0xFFC0010C /* Interrupt Mask Register */
#define SIC_IAR0 0xFFC00110 /* Interrupt Assignment Register 0 */
#define SIC_IAR1 0xFFC00114 /* Interrupt Assignment Register 1 */
#define SIC_IAR2 0xFFC00118 /* Interrupt Assignment Register 2 */
#define SIC_IAR3 0xFFC0011C /* Interrupt Assignment Register 3 */
-#define SIC_ISR 0xFFC00120 /* Interrupt Status Register */
-#define SIC_IWR 0xFFC00124 /* Interrupt Wakeup Register */
+#define SIC_ISR0 0xFFC00120 /* Interrupt Status Register */
+#define SIC_IWR0 0xFFC00124 /* Interrupt Wakeup Register */
/* SIC Additions to ADSP-BF52x (0xFFC0014C - 0xFFC00162) */
#define SIC_IMASK1 0xFFC0014C /* Interrupt Mask register of SIC2 */
@@ -691,6 +691,8 @@
/* ************* SYSTEM INTERRUPT CONTROLLER MASKS *************************************/
/* Peripheral Masks For SIC_ISR, SIC_IWR, SIC_IMASK */
+
+#if 0
#define IRQ_PLL_WAKEUP 0x00000001 /* PLL Wakeup Interrupt */
#define IRQ_ERROR1 0x00000002 /* Error Interrupt (DMA, DMARx Block, DMARx Overflow) */
@@ -732,6 +734,7 @@
#define IRQ_DMA15 0x40000000 /* DMA Channels 15 (MDMA0 Destination) TX Interrupt */
#define IRQ_WDOG 0x80000000 /* Software Watchdog Timer Interrupt */
#define IRQ_PFB_PORTG 0x10000000 /* PF Port G (PF31:16) Interrupt B */
+#endif
/* SIC_IAR0 Macros */
#define P0_IVG(x) (((x)&0xF)-7) /* Peripheral #0 assigned IVG #x */
diff --git a/include/asm-blackfin/mach-bf527/dma.h b/include/asm-blackfin/mach-bf527/dma.h
new file mode 100644
index 00000000000..a41627ae913
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/dma.h
@@ -0,0 +1,60 @@
+/*
+ * file: include/asm-blackfin/mach-bf527/dma.h
+ * based on: include/asm-blackfin/mach-bf537/dma.h
+ * author: Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ * system DMA map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MACH_DMA_H_
+#define _MACH_DMA_H_
+
+#define MAX_BLACKFIN_DMA_CHANNEL 16
+
+#define CH_PPI 0 /* PPI receive/transmit or NFC */
+#define CH_NFC 0 /* PPI receive/transmit or NFC */
+#define CH_EMAC_RX 1 /* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_HOSTDP 1 /* Ethernet MAC receive or HOSTDP */
+#define CH_EMAC_TX 2 /* Ethernet MAC transmit or NFC */
+#define CH_SPORT0_RX 3 /* SPORT0 receive */
+#define CH_SPORT0_TX 4 /* SPORT0 transmit */
+#define CH_SPORT1_RX 5 /* SPORT1 receive */
+#define CH_SPORT1_TX 6 /* SPORT1 transmit */
+#define CH_SPI 7 /* SPI transmit/receive */
+#define CH_UART0_RX 8 /* UART0 receive */
+#define CH_UART0_TX 9 /* UART0 transmit */
+#define CH_UART1_RX 10 /* UART1 receive */
+#define CH_UART1_TX 11 /* UART1 transmit */
+
+#define CH_MEM_STREAM0_DEST 12 /* TX */
+#define CH_MEM_STREAM0_SRC 13 /* RX */
+#define CH_MEM_STREAM1_DEST 14 /* TX */
+#define CH_MEM_STREAM1_SRC 15 /* RX */
+
+extern int channel2irq(unsigned int channel);
+extern struct dma_register *base_addr[];
+
+#endif
diff --git a/include/asm-blackfin/mach-bf527/irq.h b/include/asm-blackfin/mach-bf527/irq.h
new file mode 100644
index 00000000000..304f5bcfebe
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/irq.h
@@ -0,0 +1,263 @@
+/*
+ * file: include/asm-blackfin/mach-bf527/irq.h
+ * based on: include/asm-blackfin/mach-bf537/irq.h
+ * author: Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ * system mmr register map
+ * rev:
+ *
+ * modified:
+ *
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _BF527_IRQ_H_
+#define _BF527_IRQ_H_
+
+/*
+ * Interrupt source definitions
+ Event Source Core Event Name
+ Core Emulation **
+ Events (highest priority) EMU 0
+ Reset RST 1
+ NMI NMI 2
+ Exception EVX 3
+ Reserved -- 4
+ Hardware Error IVHW 5
+ Core Timer IVTMR 6 *
+
+ .....
+
+ Software Interrupt 1 IVG14 31
+ Software Interrupt 2 --
+ (lowest priority) IVG15 32 *
+*/
+
+#define NR_PERI_INTS (2 * 32)
+
+/* The ABSTRACT IRQ definitions */
+/** the first seven of the following are fixed, the rest you change if you need to **/
+#define IRQ_EMU 0 /* Emulation */
+#define IRQ_RST 1 /* reset */
+#define IRQ_NMI 2 /* Non Maskable */
+#define IRQ_EVX 3 /* Exception */
+#define IRQ_UNUSED 4 /* - unused interrupt */
+#define IRQ_HWERR 5 /* Hardware Error */
+#define IRQ_CORETMR 6 /* Core timer */
+
+#define BFIN_IRQ(x) ((x) + 7)
+
+#define IRQ_PLL_WAKEUP BFIN_IRQ(0) /* PLL Wakeup Interrupt */
+#define IRQ_DMA0_ERROR BFIN_IRQ(1) /* DMA Error 0 (generic) */
+#define IRQ_DMAR0_BLK BFIN_IRQ(2) /* DMAR0 Block Interrupt */
+#define IRQ_DMAR1_BLK BFIN_IRQ(3) /* DMAR1 Block Interrupt */
+#define IRQ_DMAR0_OVR BFIN_IRQ(4) /* DMAR0 Overflow Error */
+#define IRQ_DMAR1_OVR BFIN_IRQ(5) /* DMAR1 Overflow Error */
+#define IRQ_PPI_ERROR BFIN_IRQ(6) /* PPI Error */
+#define IRQ_MAC_ERROR BFIN_IRQ(7) /* MAC Status */
+#define IRQ_SPORT0_ERROR BFIN_IRQ(8) /* SPORT0 Status */
+#define IRQ_SPORT1_ERROR BFIN_IRQ(9) /* SPORT1 Status */
+#define IRQ_UART0_ERROR BFIN_IRQ(12) /* UART0 Status */
+#define IRQ_UART1_ERROR BFIN_IRQ(13) /* UART1 Status */
+#define IRQ_RTC BFIN_IRQ(14) /* RTC */
+#define IRQ_PPI BFIN_IRQ(15) /* DMA Channel 0 (PPI/NAND) */
+#define IRQ_SPORT0_RX BFIN_IRQ(16) /* DMA 3 Channel (SPORT0 RX) */
+#define IRQ_SPORT0_TX BFIN_IRQ(17) /* DMA 4 Channel (SPORT0 TX) */
+#define IRQ_SPORT1_RX BFIN_IRQ(18) /* DMA 5 Channel (SPORT1 RX) */
+#define IRQ_SPORT1_TX BFIN_IRQ(19) /* DMA 6 Channel (SPORT1 TX) */
+#define IRQ_TWI BFIN_IRQ(20) /* TWI */
+#define IRQ_SPI BFIN_IRQ(21) /* DMA 7 Channel (SPI) */
+#define IRQ_UART0_RX BFIN_IRQ(22) /* DMA8 Channel (UART0 RX) */
+#define IRQ_UART0_TX BFIN_IRQ(23) /* DMA9 Channel (UART0 TX) */
+#define IRQ_UART1_RX BFIN_IRQ(24) /* DMA10 Channel (UART1 RX) */
+#define IRQ_UART1_TX BFIN_IRQ(25) /* DMA11 Channel (UART1 TX) */
+#define IRQ_OPTSEC BFIN_IRQ(26) /* OTPSEC Interrupt */
+#define IRQ_CNT BFIN_IRQ(27) /* GP Counter */
+#define IRQ_MAC_RX BFIN_IRQ(28) /* DMA1 Channel (MAC RX/HDMA) */
+#define IRQ_PORTH_INTA BFIN_IRQ(29) /* Port H Interrupt A */
+#define IRQ_MAC_TX BFIN_IRQ(30) /* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_NFC BFIN_IRQ(30) /* DMA2 Channel (MAC TX/NAND) */
+#define IRQ_PORTH_INTB BFIN_IRQ(31) /* Port H Interrupt B */
+#define IRQ_TMR0 BFIN_IRQ(32) /* Timer 0 */
+#define IRQ_TMR1 BFIN_IRQ(33) /* Timer 1 */
+#define IRQ_TMR2 BFIN_IRQ(34) /* Timer 2 */
+#define IRQ_TMR3 BFIN_IRQ(35) /* Timer 3 */
+#define IRQ_TMR4 BFIN_IRQ(36) /* Timer 4 */
+#define IRQ_TMR5 BFIN_IRQ(37) /* Timer 5 */
+#define IRQ_TMR6 BFIN_IRQ(38) /* Timer 6 */
+#define IRQ_TMR7 BFIN_IRQ(39) /* Timer 7 */
+#define IRQ_PORTG_INTA BFIN_IRQ(40) /* Port G Interrupt A */
+#define IRQ_PORTG_INTB BFIN_IRQ(41) /* Port G Interrupt B */
+#define IRQ_MEM_DMA0 BFIN_IRQ(42) /* MDMA Stream 0 */
+#define IRQ_MEM_DMA1 BFIN_IRQ(43) /* MDMA Stream 1 */
+#define IRQ_WATCH BFIN_IRQ(44) /* Software Watchdog Timer */
+#define IRQ_PORTF_INTA BFIN_IRQ(45) /* Port F Interrupt A */
+#define IRQ_PORTF_INTB BFIN_IRQ(46) /* Port F Interrupt B */
+#define IRQ_SPI_ERROR BFIN_IRQ(47) /* SPI Status */
+#define IRQ_NFC_ERROR BFIN_IRQ(48) /* NAND Error */
+#define IRQ_HDMA_ERROR BFIN_IRQ(49) /* HDMA Error */
+#define IRQ_HDMA BFIN_IRQ(50) /* HDMA (TFI) */
+#define IRQ_USB_EINT BFIN_IRQ(51) /* USB_EINT Interrupt */
+#define IRQ_USB_INT0 BFIN_IRQ(52) /* USB_INT0 Interrupt */
+#define IRQ_USB_INT1 BFIN_IRQ(53) /* USB_INT1 Interrupt */
+#define IRQ_USB_INT2 BFIN_IRQ(54) /* USB_INT2 Interrupt */
+#define IRQ_USB_DMA BFIN_IRQ(55) /* USB_DMAINT Interrupt */
+
+#define SYS_IRQS BFIN_IRQ(63) /* 70 */
+
+#define IRQ_PF0 71
+#define IRQ_PF1 72
+#define IRQ_PF2 73
+#define IRQ_PF3 74
+#define IRQ_PF4 75
+#define IRQ_PF5 76
+#define IRQ_PF6 77
+#define IRQ_PF7 78
+#define IRQ_PF8 79
+#define IRQ_PF9 80
+#define IRQ_PF10 81
+#define IRQ_PF11 82
+#define IRQ_PF12 83
+#define IRQ_PF13 84
+#define IRQ_PF14 85
+#define IRQ_PF15 86
+
+#define IRQ_PG0 87
+#define IRQ_PG1 88
+#define IRQ_PG2 89
+#define IRQ_PG3 90
+#define IRQ_PG4 91
+#define IRQ_PG5 92
+#define IRQ_PG6 93
+#define IRQ_PG7 94
+#define IRQ_PG8 95
+#define IRQ_PG9 96
+#define IRQ_PG10 97
+#define IRQ_PG11 98
+#define IRQ_PG12 99
+#define IRQ_PG13 100
+#define IRQ_PG14 101
+#define IRQ_PG15 102
+
+#define IRQ_PH0 103
+#define IRQ_PH1 104
+#define IRQ_PH2 105
+#define IRQ_PH3 106
+#define IRQ_PH4 107
+#define IRQ_PH5 108
+#define IRQ_PH6 109
+#define IRQ_PH7 110
+#define IRQ_PH8 111
+#define IRQ_PH9 112
+#define IRQ_PH10 113
+#define IRQ_PH11 114
+#define IRQ_PH12 115
+#define IRQ_PH13 116
+#define IRQ_PH14 117
+#define IRQ_PH15 118
+
+#define GPIO_IRQ_BASE IRQ_PF0
+
+#ifdef CONFIG_IRQCHIP_DEMUX_GPIO
+#define NR_IRQS (IRQ_PH15+1)
+#else
+#define NR_IRQS (SYS_IRQS+1)
+#endif
+
+#define IVG7 7
+#define IVG8 8
+#define IVG9 9
+#define IVG10 10
+#define IVG11 11
+#define IVG12 12
+#define IVG13 13
+#define IVG14 14
+#define IVG15 15
+
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS 0
+#define IRQ_DMA0_ERROR_POS 4
+#define IRQ_DMAR0_BLK_POS 8
+#define IRQ_DMAR1_BLK_POS 12
+#define IRQ_DMAR0_OVR_POS 16
+#define IRQ_DMAR1_OVR_POS 20
+#define IRQ_PPI_ERROR_POS 24
+#define IRQ_MAC_ERROR_POS 28
+
+/* IAR1 BIT FIELDS */
+#define IRQ_SPORT0_ERROR_POS 0
+#define IRQ_SPORT1_ERROR_POS 4
+#define IRQ_UART0_ERROR_POS 16
+#define IRQ_UART1_ERROR_POS 20
+#define IRQ_RTC_POS 24
+#define IRQ_PPI_POS 28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_SPORT0_RX_POS 0
+#define IRQ_SPORT0_TX_POS 4
+#define IRQ_SPORT1_RX_POS 8
+#define IRQ_SPORT1_TX_POS 12
+#define IRQ_TWI_POS 16
+#define IRQ_SPI_POS 20
+#define IRQ_UART0_RX_POS 24
+#define IRQ_UART0_TX_POS 28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_UART1_RX_POS 0
+#define IRQ_UART1_TX_POS 4
+#define IRQ_OPTSEC_POS 8
+#define IRQ_CNT_POS 12
+#define IRQ_MAC_RX_POS 16
+#define IRQ_PORTH_INTA_POS 20
+#define IRQ_MAC_TX_POS 24
+#define IRQ_PORTH_INTB_POS 28
+
+/* IAR4 BIT FIELDS */
+#define IRQ_TMR0_POS 0
+#define IRQ_TMR1_POS 4
+#define IRQ_TMR2_POS 8
+#define IRQ_TMR3_POS 12
+#define IRQ_TMR4_POS 16
+#define IRQ_TMR5_POS 20
+#define IRQ_TMR6_POS 24
+#define IRQ_TMR7_POS 28
+
+/* IAR5 BIT FIELDS */
+#define IRQ_PORTG_INTA_POS 0
+#define IRQ_PORTG_INTB_POS 4
+#define IRQ_MEM_DMA0_POS 8
+#define IRQ_MEM_DMA1_POS 12
+#define IRQ_WATCH_POS 16
+#define IRQ_PORTF_INTA_POS 20
+#define IRQ_PORTF_INTB_POS 24
+#define IRQ_SPI_ERROR_POS 28
+
+/* IAR6 BIT FIELDS */
+#define IRQ_NFC_ERROR_POS 0
+#define IRQ_HDMA_ERROR_POS 4
+#define IRQ_HDMA_POS 8
+#define IRQ_USB_EINT_POS 12
+#define IRQ_USB_INT0_POS 16
+#define IRQ_USB_INT1_POS 20
+#define IRQ_USB_INT2_POS 24
+#define IRQ_USB_DMA_POS 28
+
+#endif /* _BF527_IRQ_H_ */
diff --git a/include/asm-blackfin/mach-bf527/mem_init.h b/include/asm-blackfin/mach-bf527/mem_init.h
new file mode 100644
index 00000000000..008ca66719e
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/mem_init.h
@@ -0,0 +1,337 @@
+/*
+ * File: include/asm-blackfin/mach-bf527/mem_init.h
+ * Based on:
+ * Author:
+ *
+ * Created:
+ * Description:
+ *
+ * Rev:
+ *
+ * Modified:
+ * Copyright 2004-2007 Analog Devices Inc.
+ *
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75 || CONFIG_MEM_MT48LC64M4A2FB_7E || CONFIG_MEM_MT48LC16M8A2TG_75 || CONFIG_MEM_GENERIC_BOARD || CONFIG_MEM_MT48LC32M8A2_75 || CONFIG_MEM_MT48LC32M16A2TG_75)
+#if (CONFIG_SCLK_HZ > 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_7
+#define SDRAM_tRAS_num 7
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 104477612) && (CONFIG_SCLK_HZ <= 119402985)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_6
+#define SDRAM_tRAS_num 6
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 89552239) && (CONFIG_SCLK_HZ <= 104477612)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_5
+#define SDRAM_tRAS_num 5
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 74626866) && (CONFIG_SCLK_HZ <= 89552239)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 4
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 66666667) && (CONFIG_SCLK_HZ <= 74626866)
+#define SDRAM_tRP TRP_2
+#define SDRAM_tRP_num 2
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_2
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 59701493) && (CONFIG_SCLK_HZ <= 66666667)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_4
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 44776119) && (CONFIG_SCLK_HZ <= 59701493)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_3
+#define SDRAM_tRAS_num 3
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ > 29850746) && (CONFIG_SCLK_HZ <= 44776119)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_2
+#define SDRAM_tRAS_num 2
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#if (CONFIG_SCLK_HZ <= 29850746)
+#define SDRAM_tRP TRP_1
+#define SDRAM_tRP_num 1
+#define SDRAM_tRAS TRAS_1
+#define SDRAM_tRAS_num 1
+#define SDRAM_tRCD TRCD_1
+#define SDRAM_tWR TWR_2
+#endif
+#endif
+
+#if (CONFIG_MEM_MT48LC16M16A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC16M8A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 4096 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M8A2_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC64M4A2FB_7E)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_GENERIC_BOARD)
+ /*SDRAM INFORMATION: Modify this for your board */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_MT48LC32M16A2TG_75)
+ /*SDRAM INFORMATION: */
+#define SDRAM_Tref 64 /* Refresh period in milliseconds */
+#define SDRAM_NRA 8192 /* Number of row addresses in SDRAM */
+#define SDRAM_CL CL_3
+#endif
+
+#if (CONFIG_MEM_SIZE == 128)
+#define SDRAM_SIZE EBSZ_128
+#endif
+#if (CONFIG_MEM_SIZE == 64)
+#define SDRAM_SIZE EBSZ_64
+#endif
+#if (CONFIG_MEM_SIZE == 32)
+#define SDRAM_SIZE EBSZ_32
+#endif
+#if (CONFIG_MEM_SIZE == 16)
+#define SDRAM_SIZE EBSZ_16
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 11)
+#define SDRAM_WIDTH EBCAW_11
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 10)
+#define SDRAM_WIDTH EBCAW_10
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 9)
+#define SDRAM_WIDTH EBCAW_9
+#endif
+#if (CONFIG_MEM_ADD_WIDTH == 8)
+#define SDRAM_WIDTH EBCAW_8
+#endif
+
+#define mem_SDBCTL (SDRAM_WIDTH | SDRAM_SIZE | EBE)
+
+/* Equation from section 17 (p17-46) of BF533 HRM */
+#define mem_SDRRC (((CONFIG_SCLK_HZ / 1000) * SDRAM_Tref) / SDRAM_NRA) - (SDRAM_tRAS_num + SDRAM_tRP_num)
+
+/* Enable SCLK Out */
+#define mem_SDGCTL (SCTLE | SDRAM_CL | SDRAM_tRAS | SDRAM_tRP | SDRAM_tRCD | SDRAM_tWR | PSS)
+
+#if defined CONFIG_CLKIN_HALF
+#define CLKIN_HALF 1
+#else
+#define CLKIN_HALF 0
+#endif
+
+#if defined CONFIG_PLL_BYPASS
+#define PLL_BYPASS 1
+#else
+#define PLL_BYPASS 0
+#endif
+
+/***************************************Currently Not Being Used *********************************/
+#define flash_EBIU_AMBCTL_WAT ((CONFIG_FLASH_SPEED_BWAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_RAT ((CONFIG_FLASH_SPEED_BRAT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_HT ((CONFIG_FLASH_SPEED_BHT * 4) / (4000000000 / CONFIG_SCLK_HZ))
+#define flash_EBIU_AMBCTL_ST ((CONFIG_FLASH_SPEED_BST * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+#define flash_EBIU_AMBCTL_TT ((CONFIG_FLASH_SPEED_BTT * 4) / (4000000000 / CONFIG_SCLK_HZ)) + 1
+
+#if (flash_EBIU_AMBCTL_TT > 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_4
+#endif
+#if (flash_EBIU_AMBCTL_TT == 3)
+#define flash_EBIU_AMBCTL0_TT B0TT_3
+#endif
+#if (flash_EBIU_AMBCTL_TT == 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_2
+#endif
+#if (flash_EBIU_AMBCTL_TT < 2)
+#define flash_EBIU_AMBCTL0_TT B0TT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_ST > 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_4
+#endif
+#if (flash_EBIU_AMBCTL_ST == 3)
+#define flash_EBIU_AMBCTL0_ST B0ST_3
+#endif
+#if (flash_EBIU_AMBCTL_ST == 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_2
+#endif
+#if (flash_EBIU_AMBCTL_ST < 2)
+#define flash_EBIU_AMBCTL0_ST B0ST_1
+#endif
+
+#if (flash_EBIU_AMBCTL_HT > 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_3
+#endif
+#if (flash_EBIU_AMBCTL_HT == 2)
+#define flash_EBIU_AMBCTL0_HT B0HT_2
+#endif
+#if (flash_EBIU_AMBCTL_HT == 1)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT == 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_0
+#endif
+#if (flash_EBIU_AMBCTL_HT == 0 && CONFIG_FLASH_SPEED_BHT != 0)
+#define flash_EBIU_AMBCTL0_HT B0HT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_WAT > 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_15
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 14)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_14
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 13)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_13
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 12)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_12
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 11)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_11
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 10)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_10
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 9)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_9
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 8)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_8
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 7)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_7
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 6)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_6
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 5)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_5
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 4)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_4
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 3)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_3
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 2)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_2
+#endif
+#if (flash_EBIU_AMBCTL_WAT == 1)
+#define flash_EBIU_AMBCTL0_WAT B0WAT_1
+#endif
+
+#if (flash_EBIU_AMBCTL_RAT > 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_15
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 14)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_14
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 13)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_13
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 12)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_12
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 11)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_11
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 10)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_10
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 9)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_9
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 8)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_8
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 7)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_7
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 6)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_6
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 5)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_5
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 4)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_4
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 3)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_3
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 2)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_2
+#endif
+#if (flash_EBIU_AMBCTL_RAT == 1)
+#define flash_EBIU_AMBCTL0_RAT B0RAT_1
+#endif
+
+#define flash_EBIU_AMBCTL0 \
+ (flash_EBIU_AMBCTL0_WAT | flash_EBIU_AMBCTL0_RAT | flash_EBIU_AMBCTL0_HT | \
+ flash_EBIU_AMBCTL0_ST | flash_EBIU_AMBCTL0_TT | CONFIG_FLASH_SPEED_RDYEN)
diff --git a/include/asm-blackfin/mach-bf527/mem_map.h b/include/asm-blackfin/mach-bf527/mem_map.h
new file mode 100644
index 00000000000..c5aa20102b2
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/mem_map.h
@@ -0,0 +1,98 @@
+/*
+ * file: include/asm-blackfin/mach-bf527/mem_map.h
+ * based on: include/asm-blackfin/mach-bf537/mem_map.h
+ * author: Michael Hennerich (michael.hennerich@analog.com)
+ *
+ * created:
+ * description:
+ * Memory MAP Common header file for blackfin BF527/5/2 of processors.
+ * rev:
+ *
+ * modified:
+ *
+ * bugs: enter bugs at http://blackfin.uclinux.org/
+ *
+ * this program is free software; you can redistribute it and/or modify
+ * it under the terms of the gnu general public license as published by
+ * the free software foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * this program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * merchantability or fitness for a particular purpose. see the
+ * gnu general public license for more details.
+ *
+ * you should have received a copy of the gnu general public license
+ * along with this program; see the file copying.
+ * if not, write to the free software foundation,
+ * 59 temple place - suite 330, boston, ma 02111-1307, usa.
+ */
+
+#ifndef _MEM_MAP_527_H_
+#define _MEM_MAP_527_H_
+
+#define COREMMR_BASE 0xFFE00000 /* Core MMRs */
+#define SYSMMR_BASE 0xFFC00000 /* System MMRs */
+
+/* Async Memory Banks */
+#define ASYNC_BANK3_BASE 0x20300000 /* Async Bank 3 */
+#define ASYNC_BANK3_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK2_BASE 0x20200000 /* Async Bank 2 */
+#define ASYNC_BANK2_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK1_BASE 0x20100000 /* Async Bank 1 */
+#define ASYNC_BANK1_SIZE 0x00100000 /* 1M */
+#define ASYNC_BANK0_BASE 0x20000000 /* Async Bank 0 */
+#define ASYNC_BANK0_SIZE 0x00100000 /* 1M */
+
+/* Boot ROM Memory */
+
+#define BOOT_ROM_START 0xEF000000
+
+/* Level 1 Memory */
+
+/* Memory Map for ADSP-BF527 ADSP-BF525 ADSP-BF522 processors */
+
+#ifdef CONFIG_BFIN_ICACHE
+#define BFIN_ICACHESIZE (16*1024)
+#else
+#define BFIN_ICACHESIZE (0*1024)
+#endif
+
+#define L1_CODE_START 0xFFA00000
+#define L1_DATA_A_START 0xFF800000
+#define L1_DATA_B_START 0xFF900000
+
+#define L1_CODE_LENGTH 0xC000
+
+#ifdef CONFIG_BFIN_DCACHE
+
+#ifdef CONFIG_BFIN_DCACHE_BANKA
+#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH 0x8000
+#define BFIN_DCACHESIZE (16*1024)
+#define BFIN_DSUPBANKS 1
+#else
+#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH (0x8000 - 0x4000)
+#define L1_DATA_B_LENGTH (0x8000 - 0x4000)
+#define BFIN_DCACHESIZE (32*1024)
+#define BFIN_DSUPBANKS 2
+#endif
+
+#else
+#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0)
+#define L1_DATA_A_LENGTH 0x8000
+#define L1_DATA_B_LENGTH 0x8000
+#define BFIN_DCACHESIZE (0*1024)
+#define BFIN_DSUPBANKS 0
+#endif /*CONFIG_BFIN_DCACHE */
+
+/* Scratch Pad Memory */
+
+#if defined(CONFIG_BF527) || defined(CONFIG_BF536) || defined(CONFIG_BF534)
+#define L1_SCRATCH_START 0xFFB00000
+#define L1_SCRATCH_LENGTH 0x1000
+#endif
+
+#endif /* _MEM_MAP_527_H_ */
diff --git a/include/asm-blackfin/mach-bf527/portmux.h b/include/asm-blackfin/mach-bf527/portmux.h
new file mode 100644
index 00000000000..dcf001adc63
--- /dev/null
+++ b/include/asm-blackfin/mach-bf527/portmux.h
@@ -0,0 +1,205 @@
+#ifndef _MACH_PORTMUX_H_
+#define _MACH_PORTMUX_H_
+
+#define P_PPI0_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(0))
+#define P_PPI0_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(0))
+#define P_PPI0_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(0))
+#define P_PPI0_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(0))
+#define P_PPI0_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(0))
+#define P_PPI0_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(0))
+#define P_PPI0_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(0))
+#define P_PPI0_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(0))
+#define P_PPI0_D8 (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(0))
+#define P_PPI0_D9 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(0))
+#define P_PPI0_D10 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(0))
+#define P_PPI0_D11 (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(0))
+#define P_PPI0_D12 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(0))
+#define P_PPI0_D13 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(0))
+#define P_PPI0_D14 (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(0))
+#define P_PPI0_D15 (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(0))
+
+#if defined(CONFIG_BF527_SPORT0_PORTF)
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(1))
+#define P_SPORT0_RFS (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(1))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(1))
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(1))
+#define P_SPORT0_TFS (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(1))
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(1))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(1))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_PORTG)
+#define P_SPORT0_DTPRI (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(0))
+#define P_SPORT0_DRSEC (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(1))
+#define P_SPORT0_DTSEC (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(1))
+#define P_SPORT0_DRPRI (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(1))
+#define P_SPORT0_RFS (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(1))
+#define P_SPORT0_RSCLK (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(1))
+#if defined(CONFIG_BF527_SPORT0_TSCLK_PG10)
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(1))
+#elif defined(CONFIG_BF527_SPORT0_TSCLK_PG14)
+#define P_SPORT0_TSCLK (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(0))
+#endif
+#define P_SPORT0_TFS (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(0))
+#endif
+
+#define P_SPORT1_DRPRI (P_DEFINED | P_IDENT(GPIO_PF8) | P_FUNCT(1))
+#define P_SPORT1_RSCLK (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(1))
+#define P_SPORT1_RFS (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(1))
+#define P_SPORT1_TFS (P_DEFINED | P_IDENT(GPIO_PF11) | P_FUNCT(1))
+#define P_SPORT1_DTPRI (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(1))
+#define P_SPORT1_TSCLK (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(1))
+#define P_SPORT1_DTSEC (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(1))
+#define P_SPORT1_DRSEC (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(1))
+
+#define P_SPI0_SSEL6 (P_DEFINED | P_IDENT(GPIO_PF9) | P_FUNCT(2))
+#define P_SPI0_SSEL7 (P_DEFINED | P_IDENT(GPIO_PF10) | P_FUNCT(2))
+
+#define P_SPI0_SSEL2 (P_DEFINED | P_IDENT(GPIO_PF12) | P_FUNCT(2))
+#define P_SPI0_SSEL3 (P_DEFINED | P_IDENT(GPIO_PF13) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_UART1_PORTF)
+#define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PF14) | P_FUNCT(2))
+#define P_UART1_RX (P_DEFINED | P_IDENT(GPIO_PF15) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_UART1_PORTG)
+#define P_UART1_TX (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(1))
+#define P_UART1_RX (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(1))
+#endif
+
+#define P_HWAIT (P_DONTCARE)
+
+#define P_SPI0_SS (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(0))
+#define P_SPI0_SSEL1 (P_DEFINED | P_IDENT(GPIO_PG1) | P_FUNCT(2))
+#define P_SPI0_SCK (P_DEFINED | P_IDENT(GPIO_PG2) | P_FUNCT(2))
+#define P_SPI0_MISO (P_DEFINED | P_IDENT(GPIO_PG3) | P_FUNCT(2))
+#define P_SPI0_MOSI (P_DEFINED | P_IDENT(GPIO_PG4) | P_FUNCT(2))
+#define P_TMR1 (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_PPI0_FS2 (P_DEFINED | P_IDENT(GPIO_PG5) | P_FUNCT(0))
+#define P_TMR3 (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(0))
+#define P_TMR4 (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(0))
+#define P_TMR5 (P_DEFINED | P_IDENT(GPIO_PG9) | P_FUNCT(0))
+#define P_TMR6 (P_DEFINED | P_IDENT(GPIO_PG10) | P_FUNCT(0))
+/* #define P_TMR7 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(0)) */
+#define P_DMAR1 (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(0))
+#define P_DMAR0 (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(0))
+#define P_TMR2 (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(1))
+#define P_TMR7 (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(1))
+#define P_MDC (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(1))
+#define P_RMII0_MDINT (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+#define P_MII0_PHYINT (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(1))
+
+#define P_PPI0_FS3 (P_DEFINED | P_IDENT(GPIO_PG6) | P_FUNCT(2))
+#define P_UART0_TX (P_DEFINED | P_IDENT(GPIO_PG7) | P_FUNCT(2))
+#define P_UART0_RX (P_DEFINED | P_IDENT(GPIO_PG8) | P_FUNCT(2))
+
+#define P_HOST_WR (P_DEFINED | P_IDENT(GPIO_PG11) | P_FUNCT(2))
+#define P_HOST_ACK (P_DEFINED | P_IDENT(GPIO_PG12) | P_FUNCT(2))
+#define P_HOST_ADDR (P_DEFINED | P_IDENT(GPIO_PG13) | P_FUNCT(2))
+#define P_HOST_RD (P_DEFINED | P_IDENT(GPIO_PG14) | P_FUNCT(2))
+#define P_HOST_CE (P_DEFINED | P_IDENT(GPIO_PG15) | P_FUNCT(2))
+
+#if defined(CONFIG_BF527_NAND_D_PORTF)
+#define P_NAND_D0 (P_DEFINED | P_IDENT(GPIO_PF0) | P_FUNCT(2))
+#define P_NAND_D1 (P_DEFINED | P_IDENT(GPIO_PF1) | P_FUNCT(2))
+#define P_NAND_D2 (P_DEFINED | P_IDENT(GPIO_PF2) | P_FUNCT(2))
+#define P_NAND_D3 (P_DEFINED | P_IDENT(GPIO_PF3) | P_FUNCT(2))
+#define P_NAND_D4 (P_DEFINED | P_IDENT(GPIO_PF4) | P_FUNCT(2))
+#define P_NAND_D5 (P_DEFINED | P_IDENT(GPIO_PF5) | P_FUNCT(2))
+#define P_NAND_D6 (P_DEFINED | P_IDENT(GPIO_PF6) | P_FUNCT(2))
+#define P_NAND_D7 (P_DEFINED | P_IDENT(GPIO_PF7) | P_FUNCT(2))
+#elif defined(CONFIG_BF527_NAND_D_PORTH)
+#define P_NAND_D0 (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(0))
+#define P_NAND_D1 (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(0))
+#define P_NAND_D2 (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(0))
+#define P_NAND_D3 (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(0))
+#define P_NAND_D4 (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(0))
+#define P_NAND_D5 (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(0))
+#define P_NAND_D6 (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(0))
+#define P_NAND_D7 (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(0))
+#endif
+
+#define P_SPI0_SSEL4 (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(0))
+#define P_SPI0_SSEL5 (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(0))
+#define P_NAND_CE (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(0))
+#define P_NAND_WE (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(0))
+#define P_NAND_RE (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(0))
+#define P_NAND_RB (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(0))
+#define P_NAND_CLE (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(0))
+#define P_NAND_ALE (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(0))
+
+#define P_HOST_D0 (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(2))
+#define P_HOST_D1 (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(2))
+#define P_HOST_D2 (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(2))
+#define P_HOST_D3 (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(2))
+#define P_HOST_D4 (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(2))
+#define P_HOST_D5 (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(2))
+#define P_HOST_D6 (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(2))
+#define P_HOST_D7 (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(2))
+#define P_HOST_D8 (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(2))
+#define P_HOST_D9 (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(2))
+#define P_HOST_D10 (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(2))
+#define P_HOST_D11 (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(2))
+#define P_HOST_D12 (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(2))
+#define P_HOST_D13 (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(2))
+#define P_HOST_D14 (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(2))
+#define P_HOST_D15 (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(2))
+
+#define P_MII0_ETxD0 (P_DEFINED | P_IDENT(GPIO_PH5) | P_FUNCT(1))
+#define P_MII0_ETxD1 (P_DEFINED | P_IDENT(GPIO_PH7) | P_FUNCT(1))
+#define P_MII0_ETxD2 (P_DEFINED | P_IDENT(GPIO_PH9) | P_FUNCT(1))
+#define P_MII0_ETxD3 (P_DEFINED | P_IDENT(GPIO_PH11) | P_FUNCT(1))
+#define P_MII0_ETxEN (P_DEFINED | P_IDENT(GPIO_PH3) | P_FUNCT(1))
+#define P_MII0_TxCLK (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_MII0_COL (P_DEFINED | P_IDENT(GPIO_PH15) | P_FUNCT(1))
+#define P_MII0_ERxD0 (P_DEFINED | P_IDENT(GPIO_PH6) | P_FUNCT(1))
+#define P_MII0_ERxD1 (P_DEFINED | P_IDENT(GPIO_PH8) | P_FUNCT(1))
+#define P_MII0_ERxD2 (P_DEFINED | P_IDENT(GPIO_PH10) | P_FUNCT(1))
+#define P_MII0_ERxD3 (P_DEFINED | P_IDENT(GPIO_PH12) | P_FUNCT(1))
+#define P_MII0_ERxDV (P_DEFINED | P_IDENT(GPIO_PH14) | P_FUNCT(1))
+#define P_MII0_ERxCLK (P_DEFINED | P_IDENT(GPIO_PH13) | P_FUNCT(1))
+#define P_MII0_ERxER (P_DEFINED | P_IDENT(GPIO_PH1) | P_FUNCT(1))
+#define P_MII0_CRS (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_RMII0_REF_CLK (P_DEFINED | P_IDENT(GPIO_PH4) | P_FUNCT(1))
+#define P_RMII0_CRS_DV (P_DEFINED | P_IDENT(GPIO_PH0) | P_FUNCT(1))
+#define P_MDIO (P_DEFINED | P_IDENT(GPIO_PH2) | P_FUNCT(1))
+
+#define P_TWI0_SCL (P_DONTCARE)
+#define P_TWI0_SDA (P_DONTCARE)
+#define P_PPI0_FS1 (P_DONTCARE)
+#define P_TMR0 (P_DONTCARE)
+#define P_TMRCLK (P_DONTCARE)
+#define P_PPI0_CLK (P_DONTCARE)
+
+#define P_MII0 {\
+ P_MII0_ETxD0, \
+ P_MII0_ETxD1, \
+ P_MII0_ETxD2, \
+ P_MII0_ETxD3, \
+ P_MII0_ETxEN, \
+ P_MII0_TxCLK, \
+ P_MII0_PHYINT, \
+ P_MII0_COL, \
+ P_MII0_ERxD0, \
+ P_MII0_ERxD1, \
+ P_MII0_ERxD2, \
+ P_MII0_ERxD3, \
+ P_MII0_ERxDV, \
+ P_MII0_ERxCLK, \
+ P_MII0_ERxER, \
+ P_MII0_CRS, \
+ P_MDC, \
+ P_MDIO, 0}
+
+#define P_RMII0 {\
+ P_MII0_ETxD0, \
+ P_MII0_ETxD1, \
+ P_MII0_ETxEN, \
+ P_MII0_ERxD0, \
+ P_MII0_ERxD1, \
+ P_MII0_ERxER, \
+ P_RMII0_REF_CLK, \
+ P_RMII0_MDINT, \
+ P_RMII0_CRS_DV, \
+ P_MDC, \
+ P_MDIO, 0}
+
+#endif /* _MACH_PORTMUX_H_ */
diff --git a/include/asm-blackfin/mach-bf548/defBF549.h b/include/asm-blackfin/mach-bf548/defBF549.h
index 50b3fe55ef0..4e46d657e50 100644
--- a/include/asm-blackfin/mach-bf548/defBF549.h
+++ b/include/asm-blackfin/mach-bf548/defBF549.h
@@ -1178,7 +1178,7 @@
/* Bit masks for HOST_STATUS */
-#define READY 0x1 /* DMA Ready */
+#define DMA_READY 0x1 /* DMA Ready */
#define FIFOFULL 0x2 /* FIFO Full */
#define FIFOEMPTY 0x4 /* FIFO Empty */
#define DMA_COMPLETE 0x8 /* DMA Complete */
diff --git a/include/asm-blackfin/mach-bf548/defBF54x_base.h b/include/asm-blackfin/mach-bf548/defBF54x_base.h
index e2632db74ba..1d365c844ff 100644
--- a/include/asm-blackfin/mach-bf548/defBF54x_base.h
+++ b/include/asm-blackfin/mach-bf548/defBF54x_base.h
@@ -47,6 +47,10 @@
/* Debug/MP/Emulation Registers (0xFFC00014 - 0xFFC00014) */
#define CHIPID 0xffc00014
+/* CHIPID Masks */
+#define CHIPID_VERSION 0xF0000000
+#define CHIPID_FAMILY 0x0FFFF000
+#define CHIPID_MANUFACTURE 0x00000FFE
/* System Reset and Interrupt Controller (0xFFC00100 - 0xFFC00104) */
@@ -3299,7 +3303,7 @@
#define MFD 0xf000 /* Multi channel Frame Delay */
#define FSDR 0x80 /* Frame Sync to Data Relationship */
-#define MCMEM 0x10 /* Multi channel Frame Mode Enable */
+#define MCMEN 0x10 /* Multi channel Frame Mode Enable */
#define MCDRXPE 0x8 /* Multi channel DMA Receive Packing */
#define MCDTXPE 0x4 /* Multi channel DMA Transmit Packing */
#define MCCRM 0x3 /* 2X Clock Recovery Mode */
diff --git a/include/asm-blackfin/mach-bf548/dma.h b/include/asm-blackfin/mach-bf548/dma.h
index 14cb10cc24a..4d97d3aa97c 100644
--- a/include/asm-blackfin/mach-bf548/dma.h
+++ b/include/asm-blackfin/mach-bf548/dma.h
@@ -70,5 +70,5 @@
#define MAX_BLACKFIN_DMA_CHANNEL 32
extern int channel2irq(unsigned int channel);
-extern struct dma_register *base_addr[];
+extern struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL];
#endif
diff --git a/include/asm-blackfin/scatterlist.h b/include/asm-blackfin/scatterlist.h
index 60e07b92044..32128d53469 100644
--- a/include/asm-blackfin/scatterlist.h
+++ b/include/asm-blackfin/scatterlist.h
@@ -4,7 +4,10 @@
#include <linux/mm.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-blackfin/system.h b/include/asm-blackfin/system.h
index 2b3d47d0bbb..4a927379ee1 100644
--- a/include/asm-blackfin/system.h
+++ b/include/asm-blackfin/system.h
@@ -128,9 +128,7 @@ extern unsigned long irq_flags;
#define mb() asm volatile ("" : : :"memory")
#define rmb() asm volatile ("" : : :"memory")
#define wmb() asm volatile ("" : : :"memory")
-#define set_rmb(var, value) do { (void) xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+#define set_mb(var, value) do { (void) xchg(&var, value); } while (0)
#define read_barrier_depends() do { } while(0)
diff --git a/include/asm-blackfin/tlbflush.h b/include/asm-blackfin/tlbflush.h
index 10a07ba1e01..277b400924b 100644
--- a/include/asm-blackfin/tlbflush.h
+++ b/include/asm-blackfin/tlbflush.h
@@ -53,10 +53,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
BUG();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG();
-}
-
#endif
diff --git a/include/asm-cris/arch-v32/ide.h b/include/asm-cris/arch-v32/ide.h
index 6590f657500..11296170d05 100644
--- a/include/asm-cris/arch-v32/ide.h
+++ b/include/asm-cris/arch-v32/ide.h
@@ -54,7 +54,7 @@ static inline unsigned long ide_default_io_base(int index)
#define SUPPORT_VLB_SYNC 0
#define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif) (hwif)->hw.ack_intr(hwif)
+#define ide_ack_intr(hwif) ((hwif)->ack_intr(hwif))
#endif /* __KERNEL__ */
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h
index 617151b9b72..e2f49c27ed2 100644
--- a/include/asm-cris/bitops.h
+++ b/include/asm-cris/bitops.h
@@ -14,6 +14,10 @@
/* Currently this is unsuitable for consumption outside the kernel. */
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/arch/bitops.h>
#include <asm/system.h>
#include <asm/atomic.h>
diff --git a/include/asm-cris/posix_types.h b/include/asm-cris/posix_types.h
index 7b9ed22ab5d..92000d0c3f9 100644
--- a/include/asm-cris/posix_types.h
+++ b/include/asm-cris/posix_types.h
@@ -52,7 +52,7 @@ typedef struct {
} __kernel_fsid_t;
#ifdef __KERNEL__
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#undef __FD_SET
#define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
diff --git a/include/asm-cris/scatterlist.h b/include/asm-cris/scatterlist.h
index 4bdc44c4ac3..faff53ad1f9 100644
--- a/include/asm-cris/scatterlist.h
+++ b/include/asm-cris/scatterlist.h
@@ -2,11 +2,14 @@
#define __ASM_CRIS_SCATTERLIST_H
struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
char * address; /* Location data is to be transferred to */
unsigned int length;
/* The following is i386 highmem junk - not used by us */
- struct page * page; /* Location for highmem page, if any */
+ unsigned long page_link;
unsigned int offset;/* for highmem, page offset */
};
diff --git a/include/asm-cris/tlbflush.h b/include/asm-cris/tlbflush.h
index 0569612477e..20697e7ef4f 100644
--- a/include/asm-cris/tlbflush.h
+++ b/include/asm-cris/tlbflush.h
@@ -38,13 +38,6 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st
flush_tlb_mm(vma->vm_mm);
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* CRIS does not keep any page table caches in TLB */
-}
-
-
static inline void flush_tlb(void)
{
flush_tlb_mm(current->mm);
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h
index 8dba74b1a25..e29de7131b7 100644
--- a/include/asm-frv/bitops.h
+++ b/include/asm-frv/bitops.h
@@ -21,6 +21,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm-generic/bitops/ffz.h>
/*
diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h
index 8e827fa853f..f7da007b763 100644
--- a/include/asm-frv/scatterlist.h
+++ b/include/asm-frv/scatterlist.h
@@ -22,7 +22,10 @@
* and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
*/
struct scatterlist {
- struct page *page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset; /* for highmem, page offset */
dma_addr_t dma_address;
diff --git a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
index 8370f97e41e..7ac5eafc5d9 100644
--- a/include/asm-frv/tlbflush.h
+++ b/include/asm-frv/tlbflush.h
@@ -57,7 +57,6 @@ do { \
#define __flush_tlb_global() flush_tlb_all()
#define flush_tlb() flush_tlb_all()
#define flush_tlb_kernel_range(start, end) flush_tlb_all()
-#define flush_tlb_pgtables(mm,start,end) do { } while(0)
#else
@@ -66,7 +65,6 @@ do { \
#define flush_tlb_mm(mm) BUG()
#define flush_tlb_page(vma,addr) BUG()
#define flush_tlb_range(mm,start,end) BUG()
-#define flush_tlb_pgtables(mm,start,end) BUG()
#define flush_tlb_kernel_range(start, end) BUG()
#endif
diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index e022a0f59e6..15e6f253dda 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -19,6 +19,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
diff --git a/include/asm-generic/bitops/atomic.h b/include/asm-generic/bitops/atomic.h
index cd8a9641bd6..4657f3e410f 100644
--- a/include/asm-generic/bitops/atomic.h
+++ b/include/asm-generic/bitops/atomic.h
@@ -3,9 +3,6 @@
#include <asm/types.h>
-#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-
#ifdef CONFIG_SMP
#include <asm/spinlock.h>
#include <asm/cache.h> /* we use L1_CACHE_BYTES */
@@ -66,8 +63,8 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;
*/
static inline void set_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
@@ -87,8 +84,8 @@ static inline void set_bit(int nr, volatile unsigned long *addr)
*/
static inline void clear_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
@@ -108,8 +105,8 @@ static inline void clear_bit(int nr, volatile unsigned long *addr)
*/
static inline void change_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long flags;
_atomic_spin_lock_irqsave(p, flags);
@@ -128,8 +125,8 @@ static inline void change_bit(int nr, volatile unsigned long *addr)
*/
static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
@@ -152,8 +149,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
*/
static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
@@ -175,8 +172,8 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)
*/
static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old;
unsigned long flags;
diff --git a/include/asm-generic/bitops/non-atomic.h b/include/asm-generic/bitops/non-atomic.h
index 46a825cf2ae..697cc2b7e0f 100644
--- a/include/asm-generic/bitops/non-atomic.h
+++ b/include/asm-generic/bitops/non-atomic.h
@@ -3,9 +3,6 @@
#include <asm/types.h>
-#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-
/**
* __set_bit - Set a bit in memory
* @nr: the bit to set
@@ -17,16 +14,16 @@
*/
static inline void __set_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p |= mask;
}
static inline void __clear_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p &= ~mask;
}
@@ -42,8 +39,8 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr)
*/
static inline void __change_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
*p ^= mask;
}
@@ -59,8 +56,8 @@ static inline void __change_bit(int nr, volatile unsigned long *addr)
*/
static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old | mask;
@@ -78,8 +75,8 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
*/
static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old & ~mask;
@@ -90,8 +87,8 @@ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
static inline int __test_and_change_bit(int nr,
volatile unsigned long *addr)
{
- unsigned long mask = BITOP_MASK(nr);
- unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
unsigned long old = *p;
*p = old ^ mask;
@@ -105,7 +102,7 @@ static inline int __test_and_change_bit(int nr,
*/
static inline int test_bit(int nr, const volatile unsigned long *addr)
{
- return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 5615440027e..9f584cc5c5f 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -12,7 +12,11 @@
/* .data section */
#define DATA_DATA \
*(.data) \
- *(.data.init.refok)
+ *(.data.init.refok) \
+ . = ALIGN(8); \
+ VMLINUX_SYMBOL(__start___markers) = .; \
+ *(__markers) \
+ VMLINUX_SYMBOL(__stop___markers) = .;
#define RO_DATA(align) \
. = ALIGN((align)); \
@@ -20,6 +24,7 @@
VMLINUX_SYMBOL(__start_rodata) = .; \
*(.rodata) *(.rodata.*) \
*(__vermagic) /* Kernel version magic */ \
+ *(__markers_strings) /* Markers: strings */ \
} \
\
.rodata1 : AT(ADDR(.rodata1) - LOAD_OFFSET) { \
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h
index e64ad315656..cb18e3b0aa9 100644
--- a/include/asm-h8300/bitops.h
+++ b/include/asm-h8300/bitops.h
@@ -10,6 +10,11 @@
#include <asm/system.h>
#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
/*
* Function prototypes to keep gcc -Wall happy
*/
diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h
index 985fdf54eac..d3ecdd87ac9 100644
--- a/include/asm-h8300/scatterlist.h
+++ b/include/asm-h8300/scatterlist.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-h8300/system.h b/include/asm-h8300/system.h
index 7807018f850..2c1e83f7b41 100644
--- a/include/asm-h8300/system.h
+++ b/include/asm-h8300/system.h
@@ -82,8 +82,7 @@ asmlinkage void resume(void);
#define mb() asm volatile ("" : : :"memory")
#define rmb() asm volatile ("" : : :"memory")
#define wmb() asm volatile ("" : : :"memory")
-#define set_rmb(var, value) do { xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
#ifdef CONFIG_SMP
#define smp_mb() mb()
diff --git a/include/asm-h8300/tlbflush.h b/include/asm-h8300/tlbflush.h
index 9a2c5c9fd70..41c148a9208 100644
--- a/include/asm-h8300/tlbflush.h
+++ b/include/asm-h8300/tlbflush.h
@@ -52,10 +52,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
BUG();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG();
-}
-
#endif /* _H8300_TLBFLUSH_H */
diff --git a/include/asm-ia64/bitops.h b/include/asm-ia64/bitops.h
index 2144f1a8ed6..a977affaebe 100644
--- a/include/asm-ia64/bitops.h
+++ b/include/asm-ia64/bitops.h
@@ -9,6 +9,10 @@
* O(1) scheduler patch
*/
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <linux/types.h>
#include <asm/intrinsics.h>
diff --git a/include/asm-ia64/cacheflush.h b/include/asm-ia64/cacheflush.h
index 4906916d715..afcfbda76e2 100644
--- a/include/asm-ia64/cacheflush.h
+++ b/include/asm-ia64/cacheflush.h
@@ -7,8 +7,8 @@
*/
#include <linux/page-flags.h>
+#include <linux/bitops.h>
-#include <asm/bitops.h>
#include <asm/page.h>
/*
diff --git a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h
index e928675de35..1ccf2380932 100644
--- a/include/asm-ia64/ide.h
+++ b/include/asm-ia64/ide.h
@@ -46,7 +46,6 @@ static inline unsigned long ide_default_io_base(int index)
}
}
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#ifdef CONFIG_PCI
diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h
index 3a62878e84f..f93308f54b6 100644
--- a/include/asm-ia64/meminit.h
+++ b/include/asm-ia64/meminit.h
@@ -35,7 +35,7 @@ extern void find_memory (void);
extern void reserve_memory (void);
extern void find_initrd (void);
extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg);
-extern void efi_memmap_init(unsigned long *, unsigned long *);
+extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e);
extern int find_max_min_low_pfn (unsigned long , unsigned long, void *);
extern unsigned long vmcore_find_descriptor_size(unsigned long address);
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index 0971ec90807..e6204f14f61 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -150,7 +150,7 @@
# ifndef __ASSEMBLY__
#include <linux/sched.h> /* for mm_struct */
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/cacheflush.h>
#include <asm/mmu_context.h>
#include <asm/processor.h>
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index 7d5234d5031..d6f57874041 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -9,7 +9,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length; /* buffer length */
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index 1703c9d885b..471cc2ee9ac 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -14,8 +14,8 @@
#include <linux/threads.h>
#include <linux/kernel.h>
#include <linux/cpumask.h>
+#include <linux/bitops.h>
-#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/param.h>
#include <asm/processor.h>
diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
index ff857e31738..0229fb95fb3 100644
--- a/include/asm-ia64/spinlock.h
+++ b/include/asm-ia64/spinlock.h
@@ -11,9 +11,9 @@
#include <linux/compiler.h>
#include <linux/kernel.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>
-#include <asm/bitops.h>
#include <asm/intrinsics.h>
#include <asm/system.h>
diff --git a/include/asm-ia64/tlbflush.h b/include/asm-ia64/tlbflush.h
index e37f9fbf33a..80bcb0a38e8 100644
--- a/include/asm-ia64/tlbflush.h
+++ b/include/asm-ia64/tlbflush.h
@@ -84,19 +84,6 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr)
}
/*
- * Flush the TLB entries mapping the virtually mapped linear page
- * table corresponding to address range [START-END).
- */
-static inline void
-flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end)
-{
- /*
- * Deprecated. The virtual page table is now flushed via the normal gather/flush
- * interface (see tlb.h).
- */
-}
-
-/*
* Flush the local TLB. Invoked from another cpu using an IPI.
*/
#ifdef CONFIG_SMP
diff --git a/include/asm-m32r/bitops.h b/include/asm-m32r/bitops.h
index 313a02c4a88..6dc9b81bf9f 100644
--- a/include/asm-m32r/bitops.h
+++ b/include/asm-m32r/bitops.h
@@ -11,6 +11,10 @@
* Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org>
*/
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/assembler.h>
#include <asm/system.h>
diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h
index 4672a49e876..5d2044e529a 100644
--- a/include/asm-m32r/ide.h
+++ b/include/asm-m32r/ide.h
@@ -65,7 +65,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
}
}
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-m32r/pgtable.h b/include/asm-m32r/pgtable.h
index 92d7266783f..86505387be0 100644
--- a/include/asm-m32r/pgtable.h
+++ b/include/asm-m32r/pgtable.h
@@ -21,9 +21,9 @@
#ifndef __ASSEMBLY__
#include <linux/threads.h>
+#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/addrspace.h>
-#include <asm/bitops.h>
#include <asm/page.h>
struct mm_struct;
diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h
index 352415ff5eb..1ed372c73d0 100644
--- a/include/asm-m32r/scatterlist.h
+++ b/include/asm-m32r/scatterlist.h
@@ -4,9 +4,12 @@
#include <asm/types.h>
struct scatterlist {
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
char * address; /* Location data is to be transferred to, NULL for
* highmem page */
- struct page * page; /* Location for highmem page, if any */
+ unsigned long page_link;
unsigned int offset;/* for highmem, page offset */
dma_addr_t dma_address;
diff --git a/include/asm-m32r/tlbflush.h b/include/asm-m32r/tlbflush.h
index 3d37ac002bc..0ef95307784 100644
--- a/include/asm-m32r/tlbflush.h
+++ b/include/asm-m32r/tlbflush.h
@@ -12,7 +12,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void local_flush_tlb_all(void);
@@ -93,8 +92,6 @@ static __inline__ void __flush_tlb_all(void)
);
}
-#define flush_tlb_pgtables(mm, start, end) do { } while (0)
-
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
#endif /* _ASM_M32R_TLBFLUSH_H */
diff --git a/include/asm-m68k/bitops.h b/include/asm-m68k/bitops.h
index da151f70cdc..2976b5d68e9 100644
--- a/include/asm-m68k/bitops.h
+++ b/include/asm-m68k/bitops.h
@@ -8,6 +8,10 @@
* for more details.
*/
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
/*
diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h
index f9ffb2cbbae..909c6dfd385 100644
--- a/include/asm-m68k/ide.h
+++ b/include/asm-m68k/ide.h
@@ -137,7 +137,7 @@ ide_get_lock(irq_handler_t handler, void *data)
#endif /* CONFIG_BLK_DEV_FALCON_IDE */
#define IDE_ARCH_ACK_INTR
-#define ide_ack_intr(hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
#endif /* __KERNEL__ */
#endif /* _M68K_IDE_H */
diff --git a/include/asm-m68k/scatterlist.h b/include/asm-m68k/scatterlist.h
index 24887a2d9c7..d3a7a0edfec 100644
--- a/include/asm-m68k/scatterlist.h
+++ b/include/asm-m68k/scatterlist.h
@@ -4,7 +4,10 @@
#include <linux/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-m68k/tlbflush.h b/include/asm-m68k/tlbflush.h
index 31678831ee4..17707ec315e 100644
--- a/include/asm-m68k/tlbflush.h
+++ b/include/asm-m68k/tlbflush.h
@@ -92,11 +92,6 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
flush_tlb_all();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
#else
@@ -219,11 +214,6 @@ static inline void flush_tlb_kernel_page (unsigned long addr)
sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
#endif
#endif /* _M68K_TLBFLUSH_H */
diff --git a/include/asm-m68knommu/bitops.h b/include/asm-m68knommu/bitops.h
index b8b2770d687..f8dfb7ba2e2 100644
--- a/include/asm-m68knommu/bitops.h
+++ b/include/asm-m68knommu/bitops.h
@@ -10,6 +10,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/__ffs.h>
#include <asm-generic/bitops/sched.h>
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 4da79d3d3f3..10942840e88 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -5,7 +5,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 1bd1142685e..15b4c7d45c9 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -104,8 +104,7 @@ asmlinkage void resume(void);
#define mb() asm volatile ("" : : :"memory")
#define rmb() asm volatile ("" : : :"memory")
#define wmb() asm volatile ("" : : :"memory")
-#define set_rmb(var, value) do { xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
+#define set_mb(var, value) do { xchg(&var, value); } while (0)
#ifdef CONFIG_SMP
#define smp_mb() mb()
diff --git a/include/asm-m68knommu/tlbflush.h b/include/asm-m68knommu/tlbflush.h
index de858db28b0..a470cfb803e 100644
--- a/include/asm-m68knommu/tlbflush.h
+++ b/include/asm-m68knommu/tlbflush.h
@@ -52,10 +52,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
BUG();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG();
-}
-
#endif /* _M68KNOMMU_TLBFLUSH_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index 77ed0c79830..ec75ce4cdb8 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -9,6 +9,10 @@
#ifndef _ASM_BITOPS_H
#define _ASM_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <linux/irqflags.h>
#include <linux/types.h>
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h
index 483685b1592..e59d4c03966 100644
--- a/include/asm-mips/fpu.h
+++ b/include/asm-mips/fpu.h
@@ -12,12 +12,12 @@
#include <linux/sched.h>
#include <linux/thread_info.h>
+#include <linux/bitops.h>
#include <asm/mipsregs.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
#include <asm/hazards.h>
-#include <asm/bitops.h>
#include <asm/processor.h>
#include <asm/current.h>
diff --git a/include/asm-mips/gt64120.h b/include/asm-mips/gt64120.h
index 4bf8e28f885..e64b41093c4 100644
--- a/include/asm-mips/gt64120.h
+++ b/include/asm-mips/gt64120.h
@@ -21,6 +21,8 @@
#ifndef _ASM_GT64120_H
#define _ASM_GT64120_H
+#include <linux/clocksource.h>
+
#include <asm/addrspace.h>
#include <asm/byteorder.h>
@@ -572,4 +574,7 @@
#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs))
#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data))
+extern void gt641xx_set_base_clock(unsigned int clock);
+extern int gt641xx_timer0_state(void);
+
#endif /* _ASM_GT64120_H */
diff --git a/include/asm-mips/i8253.h b/include/asm-mips/i8253.h
index 8f689d7df6b..affb32ce4af 100644
--- a/include/asm-mips/i8253.h
+++ b/include/asm-mips/i8253.h
@@ -2,8 +2,8 @@
* Machine specific IO port address definition for generic.
* Written by Osamu Tomita <tomita@cinet.co.jp>
*/
-#ifndef _MACH_IO_PORTS_H
-#define _MACH_IO_PORTS_H
+#ifndef __ASM_I8253_H
+#define __ASM_I8253_H
/* i8253A PIT registers */
#define PIT_MODE 0x43
@@ -27,4 +27,4 @@
extern void setup_pit_timer(void);
-#endif /* !_MACH_IO_PORTS_H */
+#endif /* __ASM_I8253_H */
diff --git a/include/asm-mips/ip32/crime.h b/include/asm-mips/ip32/crime.h
index a13702fafa8..7c36b0e5b1c 100644
--- a/include/asm-mips/ip32/crime.h
+++ b/include/asm-mips/ip32/crime.h
@@ -17,9 +17,6 @@
*/
#define CRIME_BASE 0x14000000 /* physical */
-#undef BIT
-#define BIT(x) (1UL << (x))
-
struct sgi_crime {
volatile unsigned long id;
#define CRIME_ID_MASK 0xff
diff --git a/include/asm-mips/ip32/mace.h b/include/asm-mips/ip32/mace.h
index 990082c81f3..d08d7c67213 100644
--- a/include/asm-mips/ip32/mace.h
+++ b/include/asm-mips/ip32/mace.h
@@ -17,9 +17,6 @@
*/
#define MACE_BASE 0x1f000000 /* physical */
-#undef BIT
-#define BIT(x) (1UL << (x))
-
/*
* PCI interface
*/
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h
index a77128362a7..4ec2b930dfb 100644
--- a/include/asm-mips/mach-generic/ide.h
+++ b/include/asm-mips/mach-generic/ide.h
@@ -98,7 +98,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
}
}
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-mips/pci/bridge.h b/include/asm-mips/pci/bridge.h
index b84feebf2ce..5f4b9d4e411 100644
--- a/include/asm-mips/pci/bridge.h
+++ b/include/asm-mips/pci/bridge.h
@@ -538,7 +538,7 @@ typedef struct bridge_err_cmdword_s {
BRIDGE_ISR_PMU_ESIZE_FAULT)
/*
- * List of Errors which are fatal and kill the sytem
+ * List of Errors which are fatal and kill the system
*/
#define BRIDGE_ISR_ERROR_FATAL \
((BRIDGE_ISR_XTALK_ERROR & ~BRIDGE_ISR_XREAD_REQ_TIMEOUT)|\
diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h
index 7af104c95b2..83d69fe17c9 100644
--- a/include/asm-mips/scatterlist.h
+++ b/include/asm-mips/scatterlist.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page * page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-mips/sibyte/sb1250.h b/include/asm-mips/sibyte/sb1250.h
index 494aa65dcfb..0dad844a3b5 100644
--- a/include/asm-mips/sibyte/sb1250.h
+++ b/include/asm-mips/sibyte/sb1250.h
@@ -45,13 +45,11 @@ extern unsigned int soc_type;
extern unsigned int periph_rev;
extern unsigned int zbbus_mhz;
-extern void sb1250_hpt_setup(void);
extern void sb1250_time_init(void);
extern void sb1250_mask_irq(int cpu, int irq);
extern void sb1250_unmask_irq(int cpu, int irq);
extern void sb1250_smp_finish(void);
-extern void bcm1480_hpt_setup(void);
extern void bcm1480_time_init(void);
extern void bcm1480_mask_irq(int cpu, int irq);
extern void bcm1480_unmask_irq(int cpu, int irq);
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h
index 4d43dbb7f8b..af081457f84 100644
--- a/include/asm-mips/sni.h
+++ b/include/asm-mips/sni.h
@@ -141,8 +141,6 @@ extern unsigned int sni_brd_type;
#define A20R_PT_TIM0_ACK 0xbc050000
#define A20R_PT_TIM1_ACK 0xbc060000
-#define SNI_MIPS_IRQ_CPU_TIMER (MIPS_CPU_IRQ_BASE+7)
-
#define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE
#define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5)
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index cf76f4f7435..bc47af313bc 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -21,6 +21,7 @@
#include <linux/ptrace.h>
#include <linux/rtc.h>
#include <linux/spinlock.h>
+#include <linux/clockchips.h>
#include <linux/clocksource.h>
extern spinlock_t rtc_lock;
@@ -83,4 +84,8 @@ static inline void mips_clockevent_init(void)
}
#endif
+extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
+extern void clockevent_set_clock(struct clock_event_device *cd,
+ unsigned int clock);
+
#endif /* _ASM_TIME_H */
diff --git a/include/asm-mips/tlbflush.h b/include/asm-mips/tlbflush.h
index 730e841fb08..86b21de12e9 100644
--- a/include/asm-mips/tlbflush.h
+++ b/include/asm-mips/tlbflush.h
@@ -11,7 +11,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void local_flush_tlb_all(void);
extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -45,10 +44,4 @@ extern void flush_tlb_one(unsigned long vaddr);
#endif /* CONFIG_SMP */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* Nothing to do on MIPS. */
-}
-
#endif /* __ASM_TLBFLUSH_H */
diff --git a/include/asm-parisc/Kbuild b/include/asm-parisc/Kbuild
index c68e1680da0..f88b252e419 100644
--- a/include/asm-parisc/Kbuild
+++ b/include/asm-parisc/Kbuild
@@ -1 +1,3 @@
include include/asm-generic/Kbuild.asm
+
+unifdef-y += pdc.h
diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h
index 03ae287baf8..f8eebcbad01 100644
--- a/include/asm-parisc/bitops.h
+++ b/include/asm-parisc/bitops.h
@@ -1,6 +1,10 @@
#ifndef _PARISC_BITOPS_H
#define _PARISC_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/types.h> /* for BITS_PER_LONG/SHIFT_PER_LONG */
#include <asm/byteorder.h>
diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
index b27bf7aeb25..be8760fbc8e 100644
--- a/include/asm-parisc/ide.h
+++ b/include/asm-parisc/ide.h
@@ -17,7 +17,6 @@
#define MAX_HWIFS 2
#endif
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h
index 95f00e11c7b..55ddb184210 100644
--- a/include/asm-parisc/io.h
+++ b/include/asm-parisc/io.h
@@ -138,7 +138,7 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign
/* Most machines react poorly to I/O-space being cacheable... Instead let's
* define ioremap() in terms of ioremap_nocache().
*/
-extern inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
{
return __ioremap(offset, size, _PAGE_NO_CACHE);
}
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h
index f6bba4c1366..b59a1504fc7 100644
--- a/include/asm-parisc/page.h
+++ b/include/asm-parisc/page.h
@@ -3,6 +3,8 @@
#ifdef __KERNEL__
+#include <linux/const.h>
+
#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
# define PAGE_SHIFT 12
#elif defined(CONFIG_PARISC_PAGE_SIZE_16KB)
@@ -12,7 +14,7 @@
#else
# error "unknown default kernel page size"
#endif
-#define PAGE_SIZE (1UL << PAGE_SHIFT)
+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h
index 61fbd57a832..4ba868f44a5 100644
--- a/include/asm-parisc/pci.h
+++ b/include/asm-parisc/pci.h
@@ -207,7 +207,7 @@ extern struct pci_bios_ops *pci_bios;
extern void pcibios_register_hba(struct pci_hba_data *);
extern void pcibios_set_master(struct pci_dev *);
#else
-extern inline void pcibios_register_hba(struct pci_hba_data *x)
+static inline void pcibios_register_hba(struct pci_hba_data *x)
{
}
#endif
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
index 876fd8116d4..5e0c3ca5450 100644
--- a/include/asm-parisc/pdc.h
+++ b/include/asm-parisc/pdc.h
@@ -1,7 +1,6 @@
#ifndef _PARISC_PDC_H
#define _PARISC_PDC_H
-
/*
* PDC return values ...
* All PDC calls return a subset of these errors.
@@ -20,7 +19,6 @@
#define PDC_BUS_POW_WARN -12 /* Call could not complete in allowed power budget */
#define PDC_NOT_NARROW -17 /* Narrow mode not supported */
-
/*
* PDC entry points...
*/
@@ -50,6 +48,12 @@
#define PDC_MODEL_DISPEC 5 /* disable specific option */
#define PDC_MODEL_CPU_ID 6 /* returns cpu-id (only newer machines!) */
#define PDC_MODEL_CAPABILITIES 7 /* returns OS32/OS64-flags */
+/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
+#define PDC_MODEL_IOPDIR_FDC (1 << 2)
+#define PDC_MODEL_NVA_MASK (3 << 4)
+#define PDC_MODEL_NVA_SUPPORTED (0 << 4)
+#define PDC_MODEL_NVA_SLOW (1 << 4)
+#define PDC_MODEL_NVA_UNSUPPORTED (3 << 4)
#define PDC_MODEL_GET_BOOT__OP 8 /* returns boot test options */
#define PDC_MODEL_SET_BOOT__OP 9 /* set boot test options */
@@ -91,7 +95,7 @@
#define PDC_TOD 9 /* time-of-day clock (TOD) */
#define PDC_TOD_READ 0 /* read TOD */
#define PDC_TOD_WRITE 1 /* write TOD */
-#define PDC_TOD_ITIMER 2 /* calibrate Interval Timer (CR16) */
+
#define PDC_STABLE 10 /* stable storage (sprockets) */
#define PDC_STABLE_READ 0
@@ -143,15 +147,6 @@
#define PDC_MEM_RET_PDT_FULL -11
#define PDC_MEM_RET_INVALID_PHYSICAL_LOCATION ~0ULL
-#ifndef __ASSEMBLY__
-typedef struct {
- unsigned long long baseAddr;
- unsigned int pages;
- unsigned int reserved;
-} MemAddrTable_t;
-#endif
-
-
#define PDC_PSW 21 /* Get/Set default System Mask */
#define PDC_PSW_MASK 0 /* Return mask */
#define PDC_PSW_GET_DEFAULTS 1 /* Return defaults */
@@ -274,6 +269,43 @@ typedef struct {
#define PDC_LINK_PCI_ENTRY_POINTS 0 /* list (Arg1) = 0 */
#define PDC_LINK_USB_ENTRY_POINTS 1 /* list (Arg1) = 1 */
+/* cl_class
+ * page 3-33 of IO-Firmware ARS
+ * IODC ENTRY_INIT(Search first) RET[1]
+ */
+#define CL_NULL 0 /* invalid */
+#define CL_RANDOM 1 /* random access (as disk) */
+#define CL_SEQU 2 /* sequential access (as tape) */
+#define CL_DUPLEX 7 /* full-duplex point-to-point (RS-232, Net) */
+#define CL_KEYBD 8 /* half-duplex console (HIL Keyboard) */
+#define CL_DISPL 9 /* half-duplex console (display) */
+#define CL_FC 10 /* FiberChannel access media */
+
+/* IODC ENTRY_INIT() */
+#define ENTRY_INIT_SRCH_FRST 2
+#define ENTRY_INIT_SRCH_NEXT 3
+#define ENTRY_INIT_MOD_DEV 4
+#define ENTRY_INIT_DEV 5
+#define ENTRY_INIT_MOD 6
+#define ENTRY_INIT_MSG 9
+
+/* IODC ENTRY_IO() */
+#define ENTRY_IO_BOOTIN 0
+#define ENTRY_IO_BOOTOUT 1
+#define ENTRY_IO_CIN 2
+#define ENTRY_IO_COUT 3
+#define ENTRY_IO_CLOSE 4
+#define ENTRY_IO_GETMSG 9
+#define ENTRY_IO_BBLOCK_IN 16
+#define ENTRY_IO_BBLOCK_OUT 17
+
+/* IODC ENTRY_SPA() */
+
+/* IODC ENTRY_CONFIG() */
+
+/* IODC ENTRY_TEST() */
+
+/* IODC ENTRY_TLB() */
/* constants for OS (NVM...) */
#define OS_ID_NONE 0 /* Undefined OS ID */
@@ -295,7 +327,13 @@ typedef struct {
#define OSTAT_RUN 6
#define OSTAT_ON 7
-#ifndef __ASSEMBLY__
+/* Page Zero constant offsets used by the HPMC handler */
+#define BOOT_CONSOLE_HPA_OFFSET 0x3c0
+#define BOOT_CONSOLE_SPA_OFFSET 0x3c4
+#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
+
+#if !defined(__ASSEMBLY__)
+#ifdef __KERNEL__
#include <linux/types.h>
@@ -331,14 +369,6 @@ struct pdc_model { /* for PDC_MODEL */
unsigned long curr_key;
};
-/* Values for PDC_MODEL_CAPABILITIES non-equivalent virtual aliasing support */
-
-#define PDC_MODEL_IOPDIR_FDC (1 << 2) /* see sba_iommu.c */
-#define PDC_MODEL_NVA_MASK (3 << 4)
-#define PDC_MODEL_NVA_SUPPORTED (0 << 4)
-#define PDC_MODEL_NVA_SLOW (1 << 4)
-#define PDC_MODEL_NVA_UNSUPPORTED (3 << 4)
-
struct pdc_cache_cf { /* for PDC_CACHE (I/D-caches) */
unsigned long
#ifdef CONFIG_64BIT
@@ -558,15 +588,97 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
__u64 fr[32];
};
-#endif /* __ASSEMBLY__ */
+void pdc_console_init(void); /* in pdc_console.c */
+void pdc_console_restart(void);
+
+void setup_pdc(void); /* in inventory.c */
+
+/* wrapper-functions from pdc.c */
+
+int pdc_add_valid(unsigned long address);
+int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
+int pdc_chassis_disp(unsigned long disp);
+int pdc_chassis_warn(unsigned long *warn);
+int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
+int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
+ void *iodc_data, unsigned int iodc_data_size);
+int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
+ struct pdc_module_path *mod_path, long mod_index);
+int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
+ long mod_index, long addr_index);
+int pdc_model_info(struct pdc_model *model);
+int pdc_model_sysmodel(char *name);
+int pdc_model_cpuid(unsigned long *cpu_id);
+int pdc_model_versions(unsigned long *versions, int id);
+int pdc_model_capabilities(unsigned long *capabilities);
+int pdc_cache_info(struct pdc_cache_info *cache);
+int pdc_spaceid_bits(unsigned long *space_bits);
+#ifndef CONFIG_PA20
+int pdc_btlb_info(struct pdc_btlb_info *btlb);
+int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
+#endif /* !CONFIG_PA20 */
+int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
+
+int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
+int pdc_stable_get_size(unsigned long *size);
+int pdc_stable_verify_contents(void);
+int pdc_stable_initialize(void);
+
+int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
+int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
+
+int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
+int pdc_tod_read(struct pdc_tod *tod);
+int pdc_tod_set(unsigned long sec, unsigned long usec);
+
+#ifdef CONFIG_64BIT
+int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
+ struct pdc_memory_table *tbl, unsigned long entries);
+#endif
+
+void set_firmware_width(void);
+int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
+int pdc_do_reset(void);
+int pdc_soft_power_info(unsigned long *power_reg);
+int pdc_soft_power_button(int sw_control);
+void pdc_io_reset(void);
+void pdc_io_reset_devices(void);
+int pdc_iodc_getc(void);
+void pdc_iodc_putc(unsigned char c);
+void pdc_iodc_outc(unsigned char c);
+void pdc_printf(const char *fmt, ...);
+
+void pdc_emergency_unlock(void);
+int pdc_sti_call(unsigned long func, unsigned long flags,
+ unsigned long inptr, unsigned long outputr,
+ unsigned long glob_cfg);
+
+static inline char * os_id_to_string(u16 os_id) {
+ switch(os_id) {
+ case OS_ID_NONE: return "No OS";
+ case OS_ID_HPUX: return "HP-UX";
+ case OS_ID_MPEXL: return "MPE-iX";
+ case OS_ID_OSF: return "OSF";
+ case OS_ID_HPRT: return "HP-RT";
+ case OS_ID_NOVEL: return "Novell Netware";
+ case OS_ID_LINUX: return "Linux";
+ default: return "Unknown";
+ }
+}
+
+#endif /* __KERNEL__ */
+
+#define PAGE0 ((struct zeropage *)__PAGE_OFFSET)
+
+/* DEFINITION OF THE ZERO-PAGE (PAG0) */
+/* based on work by Jason Eckhardt (jason@equator.com) */
-/* flags of the device_path (see below) */
+/* flags of the device_path */
#define PF_AUTOBOOT 0x80
#define PF_AUTOSEARCH 0x40
#define PF_TIMER 0x0F
-#ifndef __ASSEMBLY__
-
struct device_path { /* page 1-69 */
unsigned char flags; /* flags see above! */
unsigned char bc[6]; /* bus converter routing info */
@@ -586,63 +698,6 @@ struct pz_device {
unsigned short cl_class;/* see below */
} __attribute__((aligned(8))) ;
-#endif /* __ASSEMBLY__ */
-
-/* cl_class
- * page 3-33 of IO-Firmware ARS
- * IODC ENTRY_INIT(Search first) RET[1]
- */
-#define CL_NULL 0 /* invalid */
-#define CL_RANDOM 1 /* random access (as disk) */
-#define CL_SEQU 2 /* sequential access (as tape) */
-#define CL_DUPLEX 7 /* full-duplex point-to-point (RS-232, Net) */
-#define CL_KEYBD 8 /* half-duplex console (HIL Keyboard) */
-#define CL_DISPL 9 /* half-duplex console (display) */
-#define CL_FC 10 /* FiberChannel access media */
-
-#if 0
-/* FIXME: DEVCLASS_* duplicates CL_* (above). Delete DEVCLASS_*? */
-#define DEVCLASS_RANDOM 1
-#define DEVCLASS_SEQU 2
-#define DEVCLASS_DUPLEX 7
-#define DEVCLASS_KEYBD 8
-#define DEVCLASS_DISP 9
-#endif
-
-/* IODC ENTRY_INIT() */
-#define ENTRY_INIT_SRCH_FRST 2
-#define ENTRY_INIT_SRCH_NEXT 3
-#define ENTRY_INIT_MOD_DEV 4
-#define ENTRY_INIT_DEV 5
-#define ENTRY_INIT_MOD 6
-#define ENTRY_INIT_MSG 9
-
-/* IODC ENTRY_IO() */
-#define ENTRY_IO_BOOTIN 0
-#define ENTRY_IO_BOOTOUT 1
-#define ENTRY_IO_CIN 2
-#define ENTRY_IO_COUT 3
-#define ENTRY_IO_CLOSE 4
-#define ENTRY_IO_GETMSG 9
-#define ENTRY_IO_BBLOCK_IN 16
-#define ENTRY_IO_BBLOCK_OUT 17
-
-/* IODC ENTRY_SPA() */
-
-/* IODC ENTRY_CONFIG() */
-
-/* IODC ENTRY_TEST() */
-
-/* IODC ENTRY_TLB() */
-
-
-/* DEFINITION OF THE ZERO-PAGE (PAG0) */
-/* based on work by Jason Eckhardt (jason@equator.com) */
-
-#ifndef __ASSEMBLY__
-
-#define PAGE0 ((struct zeropage *)__PAGE_OFFSET)
-
struct zeropage {
/* [0x000] initialize vectors (VEC) */
unsigned int vec_special; /* must be zero */
@@ -699,93 +754,6 @@ struct zeropage {
__u32 pad608[126];
};
-#endif /* __ASSEMBLY__ */
-
-/* Page Zero constant offsets used by the HPMC handler */
-
-#define BOOT_CONSOLE_HPA_OFFSET 0x3c0
-#define BOOT_CONSOLE_SPA_OFFSET 0x3c4
-#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
-
-#ifndef __ASSEMBLY__
-void pdc_console_init(void); /* in pdc_console.c */
-void pdc_console_restart(void);
-
-void setup_pdc(void); /* in inventory.c */
-
-/* wrapper-functions from pdc.c */
-
-int pdc_add_valid(unsigned long address);
-int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsigned long len);
-int pdc_chassis_disp(unsigned long disp);
-int pdc_chassis_warn(unsigned long *warn);
-int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
-int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
- void *iodc_data, unsigned int iodc_data_size);
-int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
- struct pdc_module_path *mod_path, long mod_index);
-int pdc_system_map_find_addrs(struct pdc_system_map_addr_info *pdc_addr_info,
- long mod_index, long addr_index);
-int pdc_model_info(struct pdc_model *model);
-int pdc_model_sysmodel(char *name);
-int pdc_model_cpuid(unsigned long *cpu_id);
-int pdc_model_versions(unsigned long *versions, int id);
-int pdc_model_capabilities(unsigned long *capabilities);
-int pdc_cache_info(struct pdc_cache_info *cache);
-int pdc_spaceid_bits(unsigned long *space_bits);
-#ifndef CONFIG_PA20
-int pdc_btlb_info(struct pdc_btlb_info *btlb);
-int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
-#endif /* !CONFIG_PA20 */
-int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
-
-int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);
-int pdc_stable_write(unsigned long staddr, void *memaddr, unsigned long count);
-int pdc_stable_get_size(unsigned long *size);
-int pdc_stable_verify_contents(void);
-int pdc_stable_initialize(void);
-
-int pdc_pci_irt_size(unsigned long *num_entries, unsigned long hpa);
-int pdc_pci_irt(unsigned long num_entries, unsigned long hpa, void *tbl);
-
-int pdc_get_initiator(struct hardware_path *, struct pdc_initiator *);
-int pdc_tod_read(struct pdc_tod *tod);
-int pdc_tod_set(unsigned long sec, unsigned long usec);
-
-#ifdef CONFIG_64BIT
-int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
- struct pdc_memory_table *tbl, unsigned long entries);
-#endif
-
-void set_firmware_width(void);
-int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
-int pdc_do_reset(void);
-int pdc_soft_power_info(unsigned long *power_reg);
-int pdc_soft_power_button(int sw_control);
-void pdc_io_reset(void);
-void pdc_io_reset_devices(void);
-int pdc_iodc_getc(void);
-void pdc_iodc_putc(unsigned char c);
-void pdc_iodc_outc(unsigned char c);
-void pdc_printf(const char *fmt, ...);
-
-void pdc_emergency_unlock(void);
-int pdc_sti_call(unsigned long func, unsigned long flags,
- unsigned long inptr, unsigned long outputr,
- unsigned long glob_cfg);
-
-static inline char * os_id_to_string(u16 os_id) {
- switch(os_id) {
- case OS_ID_NONE: return "No OS";
- case OS_ID_HPUX: return "HP-UX";
- case OS_ID_MPEXL: return "MPE-iX";
- case OS_ID_OSF: return "OSF";
- case OS_ID_HPRT: return "HP-RT";
- case OS_ID_NOVEL: return "Novell Netware";
- case OS_ID_LINUX: return "Linux";
- default: return "Unknown";
- }
-}
-#endif /* __ASSEMBLY__ */
+#endif /* !defined(__ASSEMBLY__) */
#endif /* _PARISC_PDC_H */
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h
index e88cacd6372..cd0fa4f7332 100644
--- a/include/asm-parisc/pgtable.h
+++ b/include/asm-parisc/pgtable.h
@@ -11,9 +11,9 @@
*/
#include <linux/mm.h> /* for vm_area_struct */
+#include <linux/bitops.h>
#include <asm/processor.h>
#include <asm/cache.h>
-#include <asm/bitops.h>
/*
* kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel
@@ -49,14 +49,6 @@
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
- /* Note: If you change ISTACK_SIZE, you need to change the corresponding
- * values in vmlinux.lds and vmlinux64.lds (init_istack section). Also,
- * the "order" and size need to agree.
- */
-
-#define ISTACK_SIZE 32768 /* Interrupt Stack Size */
-#define ISTACK_ORDER 3
-
/* This is the size of the initially mapped kernel memory */
#ifdef CONFIG_64BIT
#define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */
@@ -325,27 +317,27 @@ static inline void pgd_clear(pgd_t *pgd) {
* setup: the pgd is never bad, and a pmd always exists (as it's folded
* into the pgd entry)
*/
-extern inline int pgd_none(pgd_t pgd) { return 0; }
-extern inline int pgd_bad(pgd_t pgd) { return 0; }
-extern inline int pgd_present(pgd_t pgd) { return 1; }
-extern inline void pgd_clear(pgd_t * pgdp) { }
+static inline int pgd_none(pgd_t pgd) { return 0; }
+static inline int pgd_bad(pgd_t pgd) { return 0; }
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline void pgd_clear(pgd_t * pgdp) { }
#endif
/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
*/
-extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
-extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
-extern inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
-
-extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
+static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_WRITE; }
+static inline int pte_file(pte_t pte) { return pte_val(pte) & _PAGE_FILE; }
+
+static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_WRITE; return pte; }
+static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; }
+static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; }
/*
* Conversion functions: convert a page and protection to a page entry,
@@ -369,7 +361,7 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
return pte;
}
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
/* Permanent address of a page. On parisc we don't have highmem. */
diff --git a/include/asm-parisc/prefetch.h b/include/asm-parisc/prefetch.h
index 5d021726fa3..c5edc60c059 100644
--- a/include/asm-parisc/prefetch.h
+++ b/include/asm-parisc/prefetch.h
@@ -19,7 +19,7 @@
#ifdef CONFIG_PREFETCH
#define ARCH_HAS_PREFETCH
-extern inline void prefetch(const void *addr)
+static inline void prefetch(const void *addr)
{
__asm__("ldw 0(%0), %%r0" : : "r" (addr));
}
@@ -27,7 +27,7 @@ extern inline void prefetch(const void *addr)
/* LDD is a PA2.0 addition. */
#ifdef CONFIG_PA20
#define ARCH_HAS_PREFETCHW
-extern inline void prefetchw(const void *addr)
+static inline void prefetchw(const void *addr)
{
__asm__("ldd 0(%0), %%r0" : : "r" (addr));
}
diff --git a/include/asm-parisc/rtc.h b/include/asm-parisc/rtc.h
index f4ebff11dcb..099d641a42c 100644
--- a/include/asm-parisc/rtc.h
+++ b/include/asm-parisc/rtc.h
@@ -50,10 +50,10 @@ static inline unsigned int get_rtc_time(struct rtc_time *wtime)
long int days, rem, y;
const unsigned short int *ip;
- if(pdc_tod_read(&tod_data) < 0)
+ memset(wtime, 0, sizeof(*wtime));
+ if (pdc_tod_read(&tod_data) < 0)
return RTC_24H | RTC_BATT_BAD;
-
// most of the remainder of this function is:
// Copyright (C) 1991, 1993, 1997, 1998 Free Software Foundation, Inc.
// This was originally a part of the GNU C Library.
diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h
index e7211c74844..cd3cfdf8228 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/include/asm-parisc/scatterlist.h
@@ -5,7 +5,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h
index b771dcfcfdd..a16271cdc74 100644
--- a/include/asm-parisc/semaphore.h
+++ b/include/asm-parisc/semaphore.h
@@ -54,7 +54,7 @@ struct semaphore {
#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
-extern inline void sema_init (struct semaphore *sem, int val)
+static inline void sema_init (struct semaphore *sem, int val)
{
*sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
}
@@ -82,7 +82,7 @@ asmlinkage void __up(struct semaphore * sem);
* interrupts while we're messing with the semaphore. Sorry.
*/
-extern __inline__ void down(struct semaphore * sem)
+static inline void down(struct semaphore * sem)
{
might_sleep();
spin_lock_irq(&sem->sentry);
@@ -94,7 +94,7 @@ extern __inline__ void down(struct semaphore * sem)
spin_unlock_irq(&sem->sentry);
}
-extern __inline__ int down_interruptible(struct semaphore * sem)
+static inline int down_interruptible(struct semaphore * sem)
{
int ret = 0;
might_sleep();
@@ -112,7 +112,7 @@ extern __inline__ int down_interruptible(struct semaphore * sem)
* down_trylock returns 0 on success, 1 if we failed to get the lock.
* May not sleep, but must preserve irq state
*/
-extern __inline__ int down_trylock(struct semaphore * sem)
+static inline int down_trylock(struct semaphore * sem)
{
unsigned long flags;
int count;
@@ -129,7 +129,7 @@ extern __inline__ int down_trylock(struct semaphore * sem)
* Note! This is subtle. We jump to wake people up only if
* the semaphore was negative (== somebody was waiting on it).
*/
-extern __inline__ void up(struct semaphore * sem)
+static inline void up(struct semaphore * sem)
{
unsigned long flags;
diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h
index 270cf309772..b72ec66db69 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/include/asm-parisc/tlbflush.h
@@ -57,10 +57,6 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
#endif
}
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
-
static inline void flush_tlb_page(struct vm_area_struct *vma,
unsigned long addr)
{
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h
index f74099bdca3..081b4ae6186 100644
--- a/include/asm-parisc/unistd.h
+++ b/include/asm-parisc/unistd.h
@@ -797,8 +797,9 @@
#define __NR_signalfd (__NR_Linux + 302)
#define __NR_timerfd (__NR_Linux + 303)
#define __NR_eventfd (__NR_Linux + 304)
+#define __NR_fallocate (__NR_Linux + 305)
-#define __NR_Linux_syscalls (__NR_eventfd + 1)
+#define __NR_Linux_syscalls (__NR_fallocate + 1)
#define __IGNORE_select /* newselect */
diff --git a/include/asm-powerpc/bitops.h b/include/asm-powerpc/bitops.h
index e85c3e078ba..733b4af7f4f 100644
--- a/include/asm-powerpc/bitops.h
+++ b/include/asm-powerpc/bitops.h
@@ -38,6 +38,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/asm-compat.h>
#include <asm/synch.h>
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h
index 1644e44c875..fd7f5a430f0 100644
--- a/include/asm-powerpc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -69,12 +69,11 @@ static __inline__ unsigned long ide_default_io_base(int index)
#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
#define IDE_ARCH_ACK_INTR 1
-#define ide_ack_intr(hwif) (hwif->hw.ack_intr ? hwif->hw.ack_intr(hwif) : 1)
+#define ide_ack_intr(hwif) ((hwif)->ack_intr ? (hwif)->ack_intr(hwif) : 1)
#endif
#endif /* __powerpc64__ */
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index bf14ab4ef4c..e44cdfc8493 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -522,7 +522,7 @@ static inline void name at \
#else
/*
* Enforce synchronisation of stores vs. spin_unlock
- * (this does it explicitely, though our implementation of spin_unlock
+ * (this does it explicitly, though our implementation of spin_unlock
* does it implicitely too)
*/
static inline void mmiowb(void)
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 870967e4720..4a82fdccee9 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -26,9 +26,9 @@
#include <linux/spinlock.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/bitops.h>
#include <asm/machdep.h>
#include <asm/types.h>
-#include <asm/bitops.h>
#define IOMMU_PAGE_SHIFT 12
#define IOMMU_PAGE_SIZE (ASM_CONST(1) << IOMMU_PAGE_SHIFT)
diff --git a/include/asm-powerpc/mmu_context.h b/include/asm-powerpc/mmu_context.h
index f863ac21409..9102b8bf0ea 100644
--- a/include/asm-powerpc/mmu_context.h
+++ b/include/asm-powerpc/mmu_context.h
@@ -8,7 +8,7 @@
#ifndef CONFIG_PPC64
#include <asm/atomic.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
/*
* On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 568135fe52e..fcb2ebbfddb 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -20,6 +20,11 @@
#include <linux/suspend.h>
+/* Variants of the 5200(B) */
+#define MPC5200_SVR 0x80110010
+#define MPC5200_SVR_MASK 0xfffffff0
+#define MPC5200B_SVR 0x80110020
+#define MPC5200B_SVR_MASK 0xfffffff0
/* ======================================================================== */
/* Structures mapping of some unit register set */
@@ -244,6 +249,7 @@ struct mpc52xx_cdm {
#ifndef __ASSEMBLY__
extern void __iomem * mpc52xx_find_and_map(const char *);
+extern void __iomem * mpc52xx_find_and_map_path(const char *path);
extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
extern void mpc5200_setup_xlb_arbiter(void);
extern void mpc52xx_declare_of_platform_devices(void);
@@ -253,6 +259,9 @@ extern unsigned int mpc52xx_get_irq(void);
extern int __init mpc52xx_add_bridge(struct device_node *node);
+extern void __init mpc52xx_map_wdt(void);
+extern void mpc52xx_restart(char *cmd);
+
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_PM
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 98c6bd5756b..f6dfce025ad 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -121,7 +121,5 @@ struct paca_struct {
extern struct paca_struct paca[];
-void setup_boot_paca(void);
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_PACA_H */
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index b075f619c3b..fcf7d55afe4 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -14,7 +14,10 @@
#include <asm/dma.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-powerpc/tlbflush.h b/include/asm-powerpc/tlbflush.h
index a022f806bb2..b6b036ccee3 100644
--- a/include/asm-powerpc/tlbflush.h
+++ b/include/asm-powerpc/tlbflush.h
@@ -8,7 +8,6 @@
* - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -174,15 +173,5 @@ extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start,
*/
extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t);
-/*
- * This is called in munmap when we have freed up some page-table
- * pages. We don't need to do anything here, there's nothing special
- * about our page-table pages. -- paulus
- */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
#endif /*__KERNEL__ */
#endif /* _ASM_POWERPC_TLBFLUSH_H */
diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h
index a6441a063e5..b2e25d8997b 100644
--- a/include/asm-ppc/mmu_context.h
+++ b/include/asm-ppc/mmu_context.h
@@ -2,8 +2,9 @@
#ifndef __PPC_MMU_CONTEXT_H
#define __PPC_MMU_CONTEXT_H
+#include <linux/bitops.h>
+
#include <asm/atomic.h>
-#include <asm/bitops.h>
#include <asm/mmu.h>
#include <asm/cputable.h>
#include <asm-generic/mm_hooks.h>
diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h
index cc45780421c..51df94c7384 100644
--- a/include/asm-ppc/system.h
+++ b/include/asm-ppc/system.h
@@ -33,6 +33,7 @@
#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define AT_VECTOR_SIZE_ARCH 6 /* entries in ARCH_DLINFO */
#ifdef CONFIG_SMP
#define smp_mb() mb()
#define smp_rmb() rmb()
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h
index d756b34d25f..34d9a6357c3 100644
--- a/include/asm-s390/bitops.h
+++ b/include/asm-s390/bitops.h
@@ -15,6 +15,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
/*
diff --git a/include/asm-s390/cpu.h b/include/asm-s390/cpu.h
new file mode 100644
index 00000000000..352dde194f3
--- /dev/null
+++ b/include/asm-s390/cpu.h
@@ -0,0 +1,25 @@
+/*
+ * include/asm-s390/cpu.h
+ *
+ * Copyright IBM Corp. 2007
+ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
+ */
+
+#ifndef _ASM_S390_CPU_H_
+#define _ASM_S390_CPU_H_
+
+#include <linux/types.h>
+#include <linux/percpu.h>
+#include <linux/spinlock.h>
+
+struct s390_idle_data {
+ spinlock_t lock;
+ unsigned int in_idle;
+ unsigned long long idle_count;
+ unsigned long long idle_enter;
+ unsigned long long idle_time;
+};
+
+DECLARE_PER_CPU(struct s390_idle_data, s390_idle);
+
+#endif /* _ASM_S390_CPU_H_ */
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h
index 501cb9b0631..05b842126b9 100644
--- a/include/asm-s390/mmu_context.h
+++ b/include/asm-s390/mmu_context.h
@@ -21,45 +21,43 @@
#ifndef __s390x__
#define LCTL_OPCODE "lctl"
-#define PGTABLE_BITS (_SEGMENT_TABLE|USER_STD_MASK)
#else
#define LCTL_OPCODE "lctlg"
-#define PGTABLE_BITS (_REGION_TABLE|USER_STD_MASK)
#endif
-static inline void enter_lazy_tlb(struct mm_struct *mm,
- struct task_struct *tsk)
+static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
{
+ pgd_t *pgd = mm->pgd;
+ unsigned long asce_bits;
+
+ /* Calculate asce bits from the first pgd table entry. */
+ asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
+#ifdef CONFIG_64BIT
+ asce_bits |= _ASCE_TYPE_REGION3;
+#endif
+ S390_lowcore.user_asce = asce_bits | __pa(pgd);
+ if (switch_amode) {
+ /* Load primary space page table origin. */
+ pgd_t *shadow_pgd = get_shadow_table(pgd) ? : pgd;
+ S390_lowcore.user_exec_asce = asce_bits | __pa(shadow_pgd);
+ asm volatile(LCTL_OPCODE" 1,1,%0\n"
+ : : "m" (S390_lowcore.user_exec_asce) );
+ } else
+ /* Load home space page table origin. */
+ asm volatile(LCTL_OPCODE" 13,13,%0"
+ : : "m" (S390_lowcore.user_asce) );
}
static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct task_struct *tsk)
{
- pgd_t *shadow_pgd = get_shadow_pgd(next->pgd);
-
- if (prev != next) {
- S390_lowcore.user_asce = (__pa(next->pgd) & PAGE_MASK) |
- PGTABLE_BITS;
- if (shadow_pgd) {
- /* Load primary/secondary space page table origin. */
- S390_lowcore.user_exec_asce =
- (__pa(shadow_pgd) & PAGE_MASK) | PGTABLE_BITS;
- asm volatile(LCTL_OPCODE" 1,1,%0\n"
- LCTL_OPCODE" 7,7,%1"
- : : "m" (S390_lowcore.user_exec_asce),
- "m" (S390_lowcore.user_asce) );
- } else if (switch_amode) {
- /* Load primary space page table origin. */
- asm volatile(LCTL_OPCODE" 1,1,%0"
- : : "m" (S390_lowcore.user_asce) );
- } else
- /* Load home space page table origin. */
- asm volatile(LCTL_OPCODE" 13,13,%0"
- : : "m" (S390_lowcore.user_asce) );
- }
+ if (unlikely(prev == next))
+ return;
cpu_set(smp_processor_id(), next->cpu_vm_mask);
+ update_mm(next, tsk);
}
+#define enter_lazy_tlb(mm,tsk) do { } while (0)
#define deactivate_mm(tsk,mm) do { } while (0)
static inline void activate_mm(struct mm_struct *prev,
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h
index ceec3826a67..584d0ee3c7f 100644
--- a/include/asm-s390/page.h
+++ b/include/asm-s390/page.h
@@ -82,6 +82,7 @@ typedef struct { unsigned long pte; } pte_t;
#ifndef __s390x__
typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pud; } pud_t;
typedef struct {
unsigned long pgd0;
unsigned long pgd1;
@@ -90,6 +91,7 @@ typedef struct {
} pgd_t;
#define pmd_val(x) ((x).pmd)
+#define pud_val(x) ((x).pud)
#define pgd_val(x) ((x).pgd0)
#else /* __s390x__ */
@@ -98,10 +100,12 @@ typedef struct {
unsigned long pmd0;
unsigned long pmd1;
} pmd_t;
+typedef struct { unsigned long pud; } pud_t;
typedef struct { unsigned long pgd; } pgd_t;
#define pmd_val(x) ((x).pmd0)
#define pmd_val1(x) ((x).pmd1)
+#define pud_val(x) ((x).pud)
#define pgd_val(x) ((x).pgd)
#endif /* __s390x__ */
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h
index e45d3c9a4b7..709dd174095 100644
--- a/include/asm-s390/pgalloc.h
+++ b/include/asm-s390/pgalloc.h
@@ -19,140 +19,115 @@
#define check_pgt_cache() do {} while (0)
-/*
- * Page allocation orders.
- */
-#ifndef __s390x__
-# define PTE_ALLOC_ORDER 0
-# define PMD_ALLOC_ORDER 0
-# define PGD_ALLOC_ORDER 1
-#else /* __s390x__ */
-# define PTE_ALLOC_ORDER 0
-# define PMD_ALLOC_ORDER 2
-# define PGD_ALLOC_ORDER 2
-#endif /* __s390x__ */
+unsigned long *crst_table_alloc(struct mm_struct *, int);
+void crst_table_free(unsigned long *);
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
+unsigned long *page_table_alloc(int);
+void page_table_free(unsigned long *);
-static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
{
- pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
- int i;
-
- if (!pgd)
- return NULL;
- if (s390_noexec) {
- pgd_t *shadow_pgd = (pgd_t *)
- __get_free_pages(GFP_KERNEL, PGD_ALLOC_ORDER);
- struct page *page = virt_to_page(pgd);
-
- if (!shadow_pgd) {
- free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
- return NULL;
- }
- page->lru.next = (void *) shadow_pgd;
- }
- for (i = 0; i < PTRS_PER_PGD; i++)
-#ifndef __s390x__
- pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
+ *s = val;
+ n = (n / 256) - 1;
+ asm volatile(
+#ifdef CONFIG_64BIT
+ " mvc 8(248,%0),0(%0)\n"
#else
- pgd_clear(pgd + i);
+ " mvc 4(252,%0),0(%0)\n"
#endif
- return pgd;
+ "0: mvc 256(256,%0),0(%0)\n"
+ " la %0,256(%0)\n"
+ " brct %1,0b\n"
+ : "+a" (s), "+d" (n));
}
-static inline void pgd_free(pgd_t *pgd)
+static inline void crst_table_init(unsigned long *crst, unsigned long entry)
{
- pgd_t *shadow_pgd = get_shadow_pgd(pgd);
-
- if (shadow_pgd)
- free_pages((unsigned long) shadow_pgd, PGD_ALLOC_ORDER);
- free_pages((unsigned long) pgd, PGD_ALLOC_ORDER);
+ clear_table(crst, entry, sizeof(unsigned long)*2048);
+ crst = get_shadow_table(crst);
+ if (crst)
+ clear_table(crst, entry, sizeof(unsigned long)*2048);
}
#ifndef __s390x__
-/*
- * page middle directory allocation/free routines.
- * We use pmd cache only on s390x, so these are dummy routines. This
- * code never triggers because the pgd will always be present.
- */
-#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
-#define pmd_free(x) do { } while (0)
-#define __pmd_free_tlb(tlb,x) do { } while (0)
-#define pgd_populate(mm, pmd, pte) BUG()
-#define pgd_populate_kernel(mm, pmd, pte) BUG()
-#else /* __s390x__ */
-static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
{
- pmd_t *pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
- int i;
-
- if (!pmd)
- return NULL;
- if (s390_noexec) {
- pmd_t *shadow_pmd = (pmd_t *)
- __get_free_pages(GFP_KERNEL, PMD_ALLOC_ORDER);
- struct page *page = virt_to_page(pmd);
-
- if (!shadow_pmd) {
- free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
- return NULL;
- }
- page->lru.next = (void *) shadow_pmd;
- }
- for (i=0; i < PTRS_PER_PMD; i++)
- pmd_clear(pmd + i);
- return pmd;
+ return _SEGMENT_ENTRY_EMPTY;
}
-static inline void pmd_free (pmd_t *pmd)
+#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); })
+#define pud_free(x) do { } while (0)
+
+#define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); })
+#define pmd_free(x) do { } while (0)
+
+#define pgd_populate(mm, pgd, pud) BUG()
+#define pgd_populate_kernel(mm, pgd, pud) BUG()
+
+#define pud_populate(mm, pud, pmd) BUG()
+#define pud_populate_kernel(mm, pud, pmd) BUG()
+
+#else /* __s390x__ */
+
+static inline unsigned long pgd_entry_type(struct mm_struct *mm)
{
- pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+ return _REGION3_ENTRY_EMPTY;
+}
+
+#define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); })
+#define pud_free(x) do { } while (0)
- if (shadow_pmd)
- free_pages((unsigned long) shadow_pmd, PMD_ALLOC_ORDER);
- free_pages((unsigned long) pmd, PMD_ALLOC_ORDER);
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
+{
+ unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+ if (crst)
+ crst_table_init(crst, _SEGMENT_ENTRY_EMPTY);
+ return (pmd_t *) crst;
}
+#define pmd_free(pmd) crst_table_free((unsigned long *) pmd)
-#define __pmd_free_tlb(tlb,pmd) \
- do { \
- tlb_flush_mmu(tlb, 0, 0); \
- pmd_free(pmd); \
- } while (0)
+#define pgd_populate(mm, pgd, pud) BUG()
+#define pgd_populate_kernel(mm, pgd, pud) BUG()
-static inline void
-pgd_populate_kernel(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate_kernel(struct mm_struct *mm,
+ pud_t *pud, pmd_t *pmd)
{
- pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
+ pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
}
-static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
+static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
{
- pgd_t *shadow_pgd = get_shadow_pgd(pgd);
- pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+ pud_t *shadow_pud = get_shadow_table(pud);
+ pmd_t *shadow_pmd = get_shadow_table(pmd);
- if (shadow_pgd && shadow_pmd)
- pgd_populate_kernel(mm, shadow_pgd, shadow_pmd);
- pgd_populate_kernel(mm, pgd, pmd);
+ if (shadow_pud && shadow_pmd)
+ pud_populate_kernel(mm, shadow_pud, shadow_pmd);
+ pud_populate_kernel(mm, pud, pmd);
}
#endif /* __s390x__ */
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ unsigned long *crst = crst_table_alloc(mm, s390_noexec);
+ if (crst)
+ crst_table_init(crst, pgd_entry_type(mm));
+ return (pgd_t *) crst;
+}
+#define pgd_free(pgd) crst_table_free((unsigned long *) pgd)
+
static inline void
pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
{
#ifndef __s390x__
- pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte);
- pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256);
- pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512);
- pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768);
+ pmd_val(pmd[0]) = _SEGMENT_ENTRY + __pa(pte);
+ pmd_val(pmd[1]) = _SEGMENT_ENTRY + __pa(pte+256);
+ pmd_val(pmd[2]) = _SEGMENT_ENTRY + __pa(pte+512);
+ pmd_val(pmd[3]) = _SEGMENT_ENTRY + __pa(pte+768);
#else /* __s390x__ */
- pmd_val(*pmd) = _PMD_ENTRY + __pa(pte);
- pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256);
+ pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
+ pmd_val1(*pmd) = _SEGMENT_ENTRY + __pa(pte+256);
#endif /* __s390x__ */
}
@@ -160,7 +135,7 @@ static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
{
pte_t *pte = (pte_t *)page_to_phys(page);
- pmd_t *shadow_pmd = get_shadow_pmd(pmd);
+ pmd_t *shadow_pmd = get_shadow_table(pmd);
pte_t *shadow_pte = get_shadow_pte(pte);
pmd_populate_kernel(mm, pmd, pte);
@@ -171,67 +146,14 @@ pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
/*
* page table entry allocation/free routines.
*/
-static inline pte_t *
-pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
-{
- pte_t *pte = (pte_t *) __get_free_page(GFP_KERNEL|__GFP_REPEAT);
- int i;
-
- if (!pte)
- return NULL;
- if (s390_noexec) {
- pte_t *shadow_pte = (pte_t *)
- __get_free_page(GFP_KERNEL|__GFP_REPEAT);
- struct page *page = virt_to_page(pte);
-
- if (!shadow_pte) {
- free_page((unsigned long) pte);
- return NULL;
- }
- page->lru.next = (void *) shadow_pte;
- }
- for (i=0; i < PTRS_PER_PTE; i++) {
- pte_clear(mm, vmaddr, pte + i);
- vmaddr += PAGE_SIZE;
- }
- return pte;
-}
-
-static inline struct page *
-pte_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
-{
- pte_t *pte = pte_alloc_one_kernel(mm, vmaddr);
- if (pte)
- return virt_to_page(pte);
- return NULL;
-}
-
-static inline void pte_free_kernel(pte_t *pte)
-{
- pte_t *shadow_pte = get_shadow_pte(pte);
-
- if (shadow_pte)
- free_page((unsigned long) shadow_pte);
- free_page((unsigned long) pte);
-}
-
-static inline void pte_free(struct page *pte)
-{
- struct page *shadow_page = get_shadow_page(pte);
-
- if (shadow_page)
- __free_page(shadow_page);
- __free_page(pte);
-}
-
-#define __pte_free_tlb(tlb, pte) \
-({ \
- struct mmu_gather *__tlb = (tlb); \
- struct page *__pte = (pte); \
- struct page *shadow_page = get_shadow_page(__pte); \
- if (shadow_page) \
- tlb_remove_page(__tlb, shadow_page); \
- tlb_remove_page(__tlb, __pte); \
-})
+#define pte_alloc_one_kernel(mm, vmaddr) \
+ ((pte_t *) page_table_alloc(s390_noexec))
+#define pte_alloc_one(mm, vmaddr) \
+ virt_to_page(page_table_alloc(s390_noexec))
+
+#define pte_free_kernel(pte) \
+ page_table_free((unsigned long *) pte)
+#define pte_free(pte) \
+ page_table_free((unsigned long *) page_to_phys((struct page *) pte))
#endif /* _S390_PGALLOC_H */
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 39bb5192dc3..f2cc25b74ad 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -13,8 +13,6 @@
#ifndef _ASM_S390_PGTABLE_H
#define _ASM_S390_PGTABLE_H
-#include <asm-generic/4level-fixup.h>
-
/*
* The Linux memory management assumes a three-level page table setup. For
* s390 31 bit we "fold" the mid level into the top-level page table, so
@@ -35,9 +33,6 @@
#include <asm/bug.h>
#include <asm/processor.h>
-struct vm_area_struct; /* forward declaration (include/linux/mm.h) */
-struct mm_struct;
-
extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
extern void paging_init(void);
extern void vmem_map_init(void);
@@ -63,14 +58,18 @@ extern char empty_zero_page[PAGE_SIZE];
*/
#ifndef __s390x__
# define PMD_SHIFT 22
+# define PUD_SHIFT 22
# define PGDIR_SHIFT 22
#else /* __s390x__ */
# define PMD_SHIFT 21
+# define PUD_SHIFT 31
# define PGDIR_SHIFT 31
#endif /* __s390x__ */
#define PMD_SIZE (1UL << PMD_SHIFT)
#define PMD_MASK (~(PMD_SIZE-1))
+#define PUD_SIZE (1UL << PUD_SHIFT)
+#define PUD_MASK (~(PUD_SIZE-1))
#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE-1))
@@ -83,10 +82,12 @@ extern char empty_zero_page[PAGE_SIZE];
#ifndef __s390x__
# define PTRS_PER_PTE 1024
# define PTRS_PER_PMD 1
+# define PTRS_PER_PUD 1
# define PTRS_PER_PGD 512
#else /* __s390x__ */
# define PTRS_PER_PTE 512
# define PTRS_PER_PMD 1024
+# define PTRS_PER_PUD 1
# define PTRS_PER_PGD 2048
#endif /* __s390x__ */
@@ -96,6 +97,8 @@ extern char empty_zero_page[PAGE_SIZE];
printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
#define pmd_ERROR(e) \
printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
+#define pud_ERROR(e) \
+ printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
#define pgd_ERROR(e) \
printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
@@ -195,7 +198,7 @@ extern unsigned long vmalloc_end;
* I Segment-Invalid Bit: Segment is not available for address-translation
* TT Type 01
* TF
- * TL Table lenght
+ * TL Table length
*
* The 64 bit regiontable origin of S390 has following format:
* | region table origon | DTTL
@@ -221,6 +224,8 @@ extern unsigned long vmalloc_end;
/* Hardware bits in the page table entry */
#define _PAGE_RO 0x200 /* HW read-only bit */
#define _PAGE_INVALID 0x400 /* HW invalid bit */
+
+/* Software bits in the page table entry */
#define _PAGE_SWT 0x001 /* SW pte type bit t */
#define _PAGE_SWX 0x002 /* SW pte type bit x */
@@ -264,60 +269,75 @@ extern unsigned long vmalloc_end;
#ifndef __s390x__
-/* Bits in the segment table entry */
-#define _PAGE_TABLE_LEN 0xf /* only full page-tables */
-#define _PAGE_TABLE_COM 0x10 /* common page-table */
-#define _PAGE_TABLE_INV 0x20 /* invalid page-table */
-#define _SEG_PRESENT 0x001 /* Software (overlap with PTL) */
-
-/* Bits int the storage key */
-#define _PAGE_CHANGED 0x02 /* HW changed bit */
-#define _PAGE_REFERENCED 0x04 /* HW referenced bit */
-
-#define _USER_SEG_TABLE_LEN 0x7f /* user-segment-table up to 2 GB */
-#define _KERNEL_SEG_TABLE_LEN 0x7f /* kernel-segment-table up to 2 GB */
-
-/*
- * User and Kernel pagetables are identical
- */
-#define _PAGE_TABLE _PAGE_TABLE_LEN
-#define _KERNPG_TABLE _PAGE_TABLE_LEN
-
-/*
- * The Kernel segment-tables includes the User segment-table
- */
+/* Bits in the segment table address-space-control-element */
+#define _ASCE_SPACE_SWITCH 0x80000000UL /* space switch event */
+#define _ASCE_ORIGIN_MASK 0x7ffff000UL /* segment table origin */
+#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */
+#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */
+#define _ASCE_TABLE_LENGTH 0x7f /* 128 x 64 entries = 8k */
-#define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100)
-#define _KERNSEG_TABLE _KERNEL_SEG_TABLE_LEN
+/* Bits in the segment table entry */
+#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */
+#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
+#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */
+#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */
-#define USER_STD_MASK 0x00000080UL
+#define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL)
+#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV)
#else /* __s390x__ */
+/* Bits in the segment/region table address-space-control-element */
+#define _ASCE_ORIGIN ~0xfffUL/* segment table origin */
+#define _ASCE_PRIVATE_SPACE 0x100 /* private space control */
+#define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */
+#define _ASCE_SPACE_SWITCH 0x40 /* space switch event */
+#define _ASCE_REAL_SPACE 0x20 /* real space control */
+#define _ASCE_TYPE_MASK 0x0c /* asce table type mask */
+#define _ASCE_TYPE_REGION1 0x0c /* region first table type */
+#define _ASCE_TYPE_REGION2 0x08 /* region second table type */
+#define _ASCE_TYPE_REGION3 0x04 /* region third table type */
+#define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */
+#define _ASCE_TABLE_LENGTH 0x03 /* region table length */
+
+/* Bits in the region table entry */
+#define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */
+#define _REGION_ENTRY_INV 0x20 /* invalid region table entry */
+#define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */
+#define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */
+#define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */
+#define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */
+#define _REGION_ENTRY_LENGTH 0x03 /* region third length */
+
+#define _REGION1_ENTRY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH)
+#define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV)
+#define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH)
+#define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV)
+#define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH)
+#define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV)
+
/* Bits in the segment table entry */
-#define _PMD_ENTRY_INV 0x20 /* invalid segment table entry */
-#define _PMD_ENTRY 0x00
+#define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */
+#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
+#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
+
+#define _SEGMENT_ENTRY (0)
+#define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV)
-/* Bits in the region third table entry */
-#define _PGD_ENTRY_INV 0x20 /* invalid region table entry */
-#define _PGD_ENTRY 0x07
+#endif /* __s390x__ */
/*
- * User and kernel page directory
+ * A user page table pointer has the space-switch-event bit, the
+ * private-space-control bit and the storage-alteration-event-control
+ * bit set. A kernel page table pointer doesn't need them.
*/
-#define _REGION_THIRD 0x4
-#define _REGION_THIRD_LEN 0x3
-#define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100)
-#define _KERN_REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN)
-
-#define USER_STD_MASK 0x0000000000000080UL
+#define _ASCE_USER_BITS (_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \
+ _ASCE_ALT_EVENT)
-/* Bits in the storage key */
+/* Bits int the storage key */
#define _PAGE_CHANGED 0x02 /* HW changed bit */
#define _PAGE_REFERENCED 0x04 /* HW referenced bit */
-#endif /* __s390x__ */
-
/*
* Page protection definitions.
*/
@@ -358,65 +378,38 @@ extern unsigned long vmalloc_end;
#define __S111 PAGE_EX_RW
#ifndef __s390x__
-# define PMD_SHADOW_SHIFT 1
-# define PGD_SHADOW_SHIFT 1
+# define PxD_SHADOW_SHIFT 1
#else /* __s390x__ */
-# define PMD_SHADOW_SHIFT 2
-# define PGD_SHADOW_SHIFT 2
+# define PxD_SHADOW_SHIFT 2
#endif /* __s390x__ */
static inline struct page *get_shadow_page(struct page *page)
{
- if (s390_noexec && !list_empty(&page->lru))
- return virt_to_page(page->lru.next);
- return NULL;
-}
-
-static inline pte_t *get_shadow_pte(pte_t *ptep)
-{
- unsigned long pteptr = (unsigned long) (ptep);
-
- if (s390_noexec) {
- unsigned long offset = pteptr & (PAGE_SIZE - 1);
- void *addr = (void *) (pteptr ^ offset);
- struct page *page = virt_to_page(addr);
- if (!list_empty(&page->lru))
- return (pte_t *) ((unsigned long) page->lru.next |
- offset);
- }
+ if (s390_noexec && page->index)
+ return virt_to_page((void *)(addr_t) page->index);
return NULL;
}
-static inline pmd_t *get_shadow_pmd(pmd_t *pmdp)
+static inline void *get_shadow_pte(void *table)
{
- unsigned long pmdptr = (unsigned long) (pmdp);
+ unsigned long addr, offset;
+ struct page *page;
- if (s390_noexec) {
- unsigned long offset = pmdptr &
- ((PAGE_SIZE << PMD_SHADOW_SHIFT) - 1);
- void *addr = (void *) (pmdptr ^ offset);
- struct page *page = virt_to_page(addr);
- if (!list_empty(&page->lru))
- return (pmd_t *) ((unsigned long) page->lru.next |
- offset);
- }
- return NULL;
+ addr = (unsigned long) table;
+ offset = addr & (PAGE_SIZE - 1);
+ page = virt_to_page((void *)(addr ^ offset));
+ return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
}
-static inline pgd_t *get_shadow_pgd(pgd_t *pgdp)
+static inline void *get_shadow_table(void *table)
{
- unsigned long pgdptr = (unsigned long) (pgdp);
+ unsigned long addr, offset;
+ struct page *page;
- if (s390_noexec) {
- unsigned long offset = pgdptr &
- ((PAGE_SIZE << PGD_SHADOW_SHIFT) - 1);
- void *addr = (void *) (pgdptr ^ offset);
- struct page *page = virt_to_page(addr);
- if (!list_empty(&page->lru))
- return (pgd_t *) ((unsigned long) page->lru.next |
- offset);
- }
- return NULL;
+ addr = (unsigned long) table;
+ offset = addr & ((PAGE_SIZE << PxD_SHADOW_SHIFT) - 1);
+ page = virt_to_page((void *)(addr ^ offset));
+ return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
}
/*
@@ -424,7 +417,8 @@ static inline pgd_t *get_shadow_pgd(pgd_t *pgdp)
* within a page table are directly modified. Thus, the following
* hook is made available.
*/
-static inline void set_pte(pte_t *pteptr, pte_t pteval)
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *pteptr, pte_t pteval)
{
pte_t *shadow_pte = get_shadow_pte(pteptr);
@@ -437,7 +431,6 @@ static inline void set_pte(pte_t *pteptr, pte_t pteval)
pte_val(*shadow_pte) = _PAGE_TYPE_EMPTY;
}
}
-#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
/*
* pgd/pmd/pte query functions
@@ -448,47 +441,50 @@ static inline int pgd_present(pgd_t pgd) { return 1; }
static inline int pgd_none(pgd_t pgd) { return 0; }
static inline int pgd_bad(pgd_t pgd) { return 0; }
-static inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; }
-static inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; }
-static inline int pmd_bad(pmd_t pmd)
-{
- return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE;
-}
+static inline int pud_present(pud_t pud) { return 1; }
+static inline int pud_none(pud_t pud) { return 0; }
+static inline int pud_bad(pud_t pud) { return 0; }
#else /* __s390x__ */
-static inline int pgd_present(pgd_t pgd)
+static inline int pgd_present(pgd_t pgd) { return 1; }
+static inline int pgd_none(pgd_t pgd) { return 0; }
+static inline int pgd_bad(pgd_t pgd) { return 0; }
+
+static inline int pud_present(pud_t pud)
{
- return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY;
+ return pud_val(pud) & _REGION_ENTRY_ORIGIN;
}
-static inline int pgd_none(pgd_t pgd)
+static inline int pud_none(pud_t pud)
{
- return pgd_val(pgd) & _PGD_ENTRY_INV;
+ return pud_val(pud) & _REGION_ENTRY_INV;
}
-static inline int pgd_bad(pgd_t pgd)
+static inline int pud_bad(pud_t pud)
{
- return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY;
+ unsigned long mask = ~_REGION_ENTRY_ORIGIN & ~_REGION_ENTRY_INV;
+ return (pud_val(pud) & mask) != _REGION3_ENTRY;
}
+#endif /* __s390x__ */
+
static inline int pmd_present(pmd_t pmd)
{
- return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY;
+ return pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN;
}
static inline int pmd_none(pmd_t pmd)
{
- return pmd_val(pmd) & _PMD_ENTRY_INV;
+ return pmd_val(pmd) & _SEGMENT_ENTRY_INV;
}
static inline int pmd_bad(pmd_t pmd)
{
- return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY;
+ unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV;
+ return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY;
}
-#endif /* __s390x__ */
-
static inline int pte_none(pte_t pte)
{
return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT);
@@ -508,7 +504,8 @@ static inline int pte_file(pte_t pte)
return (pte_val(pte) & mask) == _PAGE_TYPE_FILE;
}
-#define pte_same(a,b) (pte_val(a) == pte_val(b))
+#define __HAVE_ARCH_PTE_SAME
+#define pte_same(a,b) (pte_val(a) == pte_val(b))
/*
* query functions pte_write/pte_dirty/pte_young only work if
@@ -543,58 +540,52 @@ static inline int pte_young(pte_t pte)
#ifndef __s390x__
-static inline void pgd_clear(pgd_t * pgdp) { }
+#define pgd_clear(pgd) do { } while (0)
+#define pud_clear(pud) do { } while (0)
static inline void pmd_clear_kernel(pmd_t * pmdp)
{
- pmd_val(pmdp[0]) = _PAGE_TABLE_INV;
- pmd_val(pmdp[1]) = _PAGE_TABLE_INV;
- pmd_val(pmdp[2]) = _PAGE_TABLE_INV;
- pmd_val(pmdp[3]) = _PAGE_TABLE_INV;
-}
-
-static inline void pmd_clear(pmd_t * pmdp)
-{
- pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
-
- pmd_clear_kernel(pmdp);
- if (shadow_pmd)
- pmd_clear_kernel(shadow_pmd);
+ pmd_val(pmdp[0]) = _SEGMENT_ENTRY_EMPTY;
+ pmd_val(pmdp[1]) = _SEGMENT_ENTRY_EMPTY;
+ pmd_val(pmdp[2]) = _SEGMENT_ENTRY_EMPTY;
+ pmd_val(pmdp[3]) = _SEGMENT_ENTRY_EMPTY;
}
#else /* __s390x__ */
-static inline void pgd_clear_kernel(pgd_t * pgdp)
+#define pgd_clear(pgd) do { } while (0)
+
+static inline void pud_clear_kernel(pud_t *pud)
{
- pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY;
+ pud_val(*pud) = _REGION3_ENTRY_EMPTY;
}
-static inline void pgd_clear(pgd_t * pgdp)
+static inline void pud_clear(pud_t * pud)
{
- pgd_t *shadow_pgd = get_shadow_pgd(pgdp);
+ pud_t *shadow = get_shadow_table(pud);
- pgd_clear_kernel(pgdp);
- if (shadow_pgd)
- pgd_clear_kernel(shadow_pgd);
+ pud_clear_kernel(pud);
+ if (shadow)
+ pud_clear_kernel(shadow);
}
static inline void pmd_clear_kernel(pmd_t * pmdp)
{
- pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
- pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY;
+ pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
+ pmd_val1(*pmdp) = _SEGMENT_ENTRY_EMPTY;
}
+#endif /* __s390x__ */
+
static inline void pmd_clear(pmd_t * pmdp)
{
- pmd_t *shadow_pmd = get_shadow_pmd(pmdp);
+ pmd_t *shadow_pmd = get_shadow_table(pmdp);
pmd_clear_kernel(pmdp);
if (shadow_pmd)
pmd_clear_kernel(shadow_pmd);
}
-#endif /* __s390x__ */
-
static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
{
pte_t *shadow_pte = get_shadow_pte(ptep);
@@ -663,24 +654,19 @@ static inline pte_t pte_mkyoung(pte_t pte)
return pte;
}
-static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
{
return 0;
}
-static inline int
-ptep_clear_flush_young(struct vm_area_struct *vma,
- unsigned long address, pte_t *ptep)
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+static inline int ptep_clear_flush_young(struct vm_area_struct *vma,
+ unsigned long address, pte_t *ptep)
{
/* No need to flush TLB; bits are in storage key */
- return ptep_test_and_clear_young(vma, address, ptep);
-}
-
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
- pte_t pte = *ptep;
- pte_clear(mm, addr, ptep);
- return pte;
+ return 0;
}
static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
@@ -709,6 +695,32 @@ static inline void ptep_invalidate(unsigned long address, pte_t *ptep)
__ptep_ipte(address, ptep);
}
+/*
+ * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
+ * both clear the TLB for the unmapped pte. The reason is that
+ * ptep_get_and_clear is used in common code (e.g. change_pte_range)
+ * to modify an active pte. The sequence is
+ * 1) ptep_get_and_clear
+ * 2) set_pte_at
+ * 3) flush_tlb_range
+ * On s390 the tlb needs to get flushed with the modification of the pte
+ * if the pte is active. The only way how this can be implemented is to
+ * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range
+ * is a nop.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define ptep_get_and_clear(__mm, __address, __ptep) \
+({ \
+ pte_t __pte = *(__ptep); \
+ if (atomic_read(&(__mm)->mm_users) > 1 || \
+ (__mm) != current->active_mm) \
+ ptep_invalidate(__address, __ptep); \
+ else \
+ pte_clear((__mm), (__address), (__ptep)); \
+ __pte; \
+})
+
+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
unsigned long address, pte_t *ptep)
{
@@ -717,12 +729,40 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
return pte;
}
-static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+/*
+ * The batched pte unmap code uses ptep_get_and_clear_full to clear the
+ * ptes. Here an optimization is possible. tlb_gather_mmu flushes all
+ * tlbs of an mm if it can guarantee that the ptes of the mm_struct
+ * cannot be accessed while the batched unmap is running. In this case
+ * full==1 and a simple pte_clear is enough. See tlb.h.
+ */
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
+static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
+ unsigned long addr,
+ pte_t *ptep, int full)
{
- pte_t old_pte = *ptep;
- set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
+ pte_t pte = *ptep;
+
+ if (full)
+ pte_clear(mm, addr, ptep);
+ else
+ ptep_invalidate(addr, ptep);
+ return pte;
}
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define ptep_set_wrprotect(__mm, __addr, __ptep) \
+({ \
+ pte_t __pte = *(__ptep); \
+ if (pte_write(__pte)) { \
+ if (atomic_read(&(__mm)->mm_users) > 1 || \
+ (__mm) != current->active_mm) \
+ ptep_invalidate(__addr, __ptep); \
+ set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \
+ } \
+})
+
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
({ \
int __changed = !pte_same(*(__ptep), __entry); \
@@ -740,11 +780,13 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
* should therefore only be called if it is not mapped in any
* address space.
*/
+#define __HAVE_ARCH_PAGE_TEST_DIRTY
static inline int page_test_dirty(struct page *page)
{
return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0;
}
+#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
static inline void page_clear_dirty(struct page *page)
{
page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY);
@@ -753,6 +795,7 @@ static inline void page_clear_dirty(struct page *page)
/*
* Test and clear referenced bit in storage key.
*/
+#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
static inline int page_test_and_clear_young(struct page *page)
{
unsigned long physpage = page_to_phys(page);
@@ -784,63 +827,48 @@ static inline pte_t mk_pte(struct page *page, pgprot_t pgprot)
return mk_pte_phys(physpage, pgprot);
}
-static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
-{
- unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
- return mk_pte_phys(physpage, pgprot);
-}
-
-#ifdef __s390x__
-
-static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t pgprot)
-{
- unsigned long physpage = __pa((pfn) << PAGE_SHIFT);
-
- return __pmd(physpage + pgprot_val(pgprot));
-}
-
-#endif /* __s390x__ */
-
-#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
-#define pte_page(x) pfn_to_page(pte_pfn(x))
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+#define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
-#define pmd_page_vaddr(pmd) (pmd_val(pmd) & PAGE_MASK)
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
-#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
+#ifndef __s390x__
-#define pgd_page_vaddr(pgd) (pgd_val(pgd) & PAGE_MASK)
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pmd) ({ BUG(); 0UL; })
+#define pgd_deref(pmd) ({ BUG(); 0UL; })
-#define pgd_page(pgd) pfn_to_page(pgd_val(pgd) >> PAGE_SHIFT)
+#define pud_offset(pgd, address) ((pud_t *) pgd)
+#define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address))
-/* to find an entry in a page-table-directory */
-#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
-#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+#else /* __s390x__ */
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+#define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN)
+#define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN)
+#define pgd_deref(pgd) ({ BUG(); 0UL; })
-#ifndef __s390x__
+#define pud_offset(pgd, address) ((pud_t *) pgd)
-/* Find an entry in the second-level page table.. */
-static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
{
- return (pmd_t *) dir;
+ pmd_t *pmd = (pmd_t *) pud_deref(*pud);
+ return pmd + pmd_index(address);
}
-#else /* __s390x__ */
+#endif /* __s390x__ */
-/* Find an entry in the second-level page table.. */
-#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
-#define pmd_offset(dir,addr) \
- ((pmd_t *) pgd_page_vaddr(*(dir)) + pmd_index(addr))
+#define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot))
+#define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT)
+#define pte_page(x) pfn_to_page(pte_pfn(x))
-#endif /* __s390x__ */
+#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
-/* Find an entry in the third-level page table.. */
-#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1))
-#define pte_offset_kernel(pmd, address) \
- ((pte_t *) pmd_page_vaddr(*(pmd)) + pte_index(address))
+/* Find an entry in the lowest level page table.. */
+#define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr))
+#define pte_offset_kernel(pmd, address) pte_offset(pmd,address)
#define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address)
#define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address)
#define pte_unmap(pte) do { } while (0)
@@ -930,17 +958,6 @@ extern int remove_shared_memory(unsigned long start, unsigned long size);
#define __HAVE_ARCH_MEMMAP_INIT
extern void memmap_init(unsigned long, int, unsigned long, unsigned long);
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
-#define __HAVE_ARCH_PTEP_SET_WRPROTECT
-#define __HAVE_ARCH_PTE_SAME
-#define __HAVE_ARCH_PAGE_TEST_DIRTY
-#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
-#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
#include <asm-generic/pgtable.h>
#endif /* _S390_PAGE_H */
-
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 3b972d4c6b2..21d40a19355 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -93,7 +93,6 @@ struct thread_struct {
s390_fp_regs fp_regs;
unsigned int acrs[NUM_ACRS];
unsigned long ksp; /* kernel stack pointer */
- unsigned long user_seg; /* HSTD */
mm_segment_t mm_segment;
unsigned long prot_addr; /* address of protection-excep. */
unsigned int error_code; /* error-code of last prog-excep. */
@@ -128,22 +127,9 @@ struct stack_frame {
#define ARCH_MIN_TASKALIGN 8
-#ifndef __s390x__
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE
-#else /* __s390x__ */
-# define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE
-#endif /* __s390x__ */
-
-#define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \
- {0},{0},{0},{0},{0},{0}}}, \
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
- sizeof(init_stack) + (unsigned long) &init_stack, \
- __SWAPPER_PG_DIR, \
- {0}, \
- 0,0,0, \
- (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \
- 0, 0 \
-}
+#define INIT_THREAD { \
+ .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \
+}
/*
* Do necessary setup to start up a new thread.
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h
index a43b3afc5e2..29ec8e28c8d 100644
--- a/include/asm-s390/scatterlist.h
+++ b/include/asm-s390/scatterlist.h
@@ -2,7 +2,10 @@
#define _ASMS390_SCATTERLIST_H
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
};
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h
index 51bd957b85b..618693cfc10 100644
--- a/include/asm-s390/tlb.h
+++ b/include/asm-s390/tlb.h
@@ -2,19 +2,130 @@
#define _S390_TLB_H
/*
- * s390 doesn't need any special per-pte or
- * per-vma handling..
+ * TLB flushing on s390 is complicated. The following requirement
+ * from the principles of operation is the most arduous:
+ *
+ * "A valid table entry must not be changed while it is attached
+ * to any CPU and may be used for translation by that CPU except to
+ * (1) invalidate the entry by using INVALIDATE PAGE TABLE ENTRY,
+ * or INVALIDATE DAT TABLE ENTRY, (2) alter bits 56-63 of a page
+ * table entry, or (3) make a change by means of a COMPARE AND SWAP
+ * AND PURGE instruction that purges the TLB."
+ *
+ * The modification of a pte of an active mm struct therefore is
+ * a two step process: i) invalidate the pte, ii) store the new pte.
+ * This is true for the page protection bit as well.
+ * The only possible optimization is to flush at the beginning of
+ * a tlb_gather_mmu cycle if the mm_struct is currently not in use.
+ *
+ * Pages used for the page tables is a different story. FIXME: more
*/
-#define tlb_start_vma(tlb, vma) do { } while (0)
-#define tlb_end_vma(tlb, vma) do { } while (0)
-#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <asm/processor.h>
+#include <asm/pgalloc.h>
+#include <asm/smp.h>
+#include <asm/tlbflush.h>
+
+#ifndef CONFIG_SMP
+#define TLB_NR_PTRS 1
+#else
+#define TLB_NR_PTRS 508
+#endif
+
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int fullmm;
+ unsigned int nr_ptes;
+ unsigned int nr_pmds;
+ void *array[TLB_NR_PTRS];
+};
+
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
+ unsigned int full_mm_flush)
+{
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+ tlb->mm = mm;
+ tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) ||
+ (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm);
+ tlb->nr_ptes = 0;
+ tlb->nr_pmds = TLB_NR_PTRS;
+ if (tlb->fullmm)
+ __tlb_flush_mm(mm);
+ return tlb;
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end)
+{
+ if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS))
+ __tlb_flush_mm(tlb->mm);
+ while (tlb->nr_ptes > 0)
+ pte_free(tlb->array[--tlb->nr_ptes]);
+ while (tlb->nr_pmds < TLB_NR_PTRS)
+ pmd_free((pmd_t *) tlb->array[tlb->nr_pmds++]);
+}
+
+static inline void tlb_finish_mmu(struct mmu_gather *tlb,
+ unsigned long start, unsigned long end)
+{
+ tlb_flush_mmu(tlb, start, end);
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+
+ put_cpu_var(mmu_gathers);
+}
/*
- * .. because we flush the whole mm when it
- * fills up.
+ * Release the page cache reference for a pte removed by
+ * tlb_ptep_clear_flush. In both flush modes the tlb fo a page cache page
+ * has already been freed, so just do free_page_and_swap_cache.
*/
-#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ free_page_and_swap_cache(page);
+}
-#include <asm-generic/tlb.h>
+/*
+ * pte_free_tlb frees a pte table and clears the CRSTE for the
+ * page table from the tlb.
+ */
+static inline void pte_free_tlb(struct mmu_gather *tlb, struct page *page)
+{
+ if (!tlb->fullmm) {
+ tlb->array[tlb->nr_ptes++] = page;
+ if (tlb->nr_ptes >= tlb->nr_pmds)
+ tlb_flush_mmu(tlb, 0, 0);
+ } else
+ pte_free(page);
+}
+/*
+ * pmd_free_tlb frees a pmd table and clears the CRSTE for the
+ * segment table entry from the tlb.
+ */
+static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+{
+#ifdef __s390x__
+ if (!tlb->fullmm) {
+ tlb->array[--tlb->nr_pmds] = (struct page *) pmd;
+ if (tlb->nr_ptes >= tlb->nr_pmds)
+ tlb_flush_mmu(tlb, 0, 0);
+ } else
+ pmd_free(pmd);
#endif
+}
+
+#define pud_free_tlb(tlb, pud) do { } while (0)
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0)
+#define tlb_migrate_finish(mm) do { } while (0)
+
+#endif /* _S390_TLB_H */
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h
index 66793f55c8b..a69bd2490d5 100644
--- a/include/asm-s390/tlbflush.h
+++ b/include/asm-s390/tlbflush.h
@@ -6,69 +6,19 @@
#include <asm/pgalloc.h>
/*
- * TLB flushing:
- *
- * - flush_tlb() flushes the current mm struct TLBs
- * - flush_tlb_all() flushes all processes TLBs
- * - flush_tlb_mm(mm) flushes the specified mm context TLB's
- * - flush_tlb_page(vma, vmaddr) flushes one page
- * - flush_tlb_range(vma, start, end) flushes a range of pages
- * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
- */
-
-/*
- * S/390 has three ways of flushing TLBs
- * 'ptlb' does a flush of the local processor
- * 'csp' flushes the TLBs on all PUs of a SMP
- * 'ipte' invalidates a pte in a page table and flushes that out of
- * the TLBs of all PUs of a SMP
+ * Flush all tlb entries on the local cpu.
*/
-
-#define local_flush_tlb() \
-do { asm volatile("ptlb": : :"memory"); } while (0)
-
-#ifndef CONFIG_SMP
-
-/*
- * We always need to flush, since s390 does not flush tlb
- * on each context switch
- */
-
-static inline void flush_tlb(void)
-{
- local_flush_tlb();
-}
-static inline void flush_tlb_all(void)
-{
- local_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm)
+static inline void __tlb_flush_local(void)
{
- local_flush_tlb();
+ asm volatile("ptlb" : : : "memory");
}
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long addr)
-{
- local_flush_tlb();
-}
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- local_flush_tlb();
-}
-
-#define flush_tlb_kernel_range(start, end) \
- local_flush_tlb();
-
-#else
-
-#include <asm/smp.h>
-
-extern void smp_ptlb_all(void);
-static inline void global_flush_tlb(void)
+/*
+ * Flush all tlb entries on all cpus.
+ */
+static inline void __tlb_flush_global(void)
{
+ extern void smp_ptlb_all(void);
register unsigned long reg2 asm("2");
register unsigned long reg3 asm("3");
register unsigned long reg4 asm("4");
@@ -90,72 +40,75 @@ static inline void global_flush_tlb(void)
}
/*
- * We only have to do global flush of tlb if process run since last
- * flush on any other pu than current.
- * If we have threads (mm->count > 1) we always do a global flush,
- * since the process runs on more than one processor at the same time.
+ * Flush all tlb entries of a page table on all cpus.
*/
+static inline void __tlb_flush_idte(pgd_t *pgd)
+{
+ asm volatile(
+ " .insn rrf,0xb98e0000,0,%0,%1,0"
+ : : "a" (2048), "a" (__pa(pgd) & PAGE_MASK) : "cc" );
+}
-static inline void __flush_tlb_mm(struct mm_struct * mm)
+static inline void __tlb_flush_mm(struct mm_struct * mm)
{
cpumask_t local_cpumask;
if (unlikely(cpus_empty(mm->cpu_vm_mask)))
return;
+ /*
+ * If the machine has IDTE we prefer to do a per mm flush
+ * on all cpus instead of doing a local flush if the mm
+ * only ran on the local cpu.
+ */
if (MACHINE_HAS_IDTE) {
- pgd_t *shadow_pgd = get_shadow_pgd(mm->pgd);
+ pgd_t *shadow_pgd = get_shadow_table(mm->pgd);
- if (shadow_pgd) {
- asm volatile(
- " .insn rrf,0xb98e0000,0,%0,%1,0"
- : : "a" (2048),
- "a" (__pa(shadow_pgd) & PAGE_MASK) : "cc" );
- }
- asm volatile(
- " .insn rrf,0xb98e0000,0,%0,%1,0"
- : : "a" (2048), "a" (__pa(mm->pgd)&PAGE_MASK) : "cc");
+ if (shadow_pgd)
+ __tlb_flush_idte(shadow_pgd);
+ __tlb_flush_idte(mm->pgd);
return;
}
preempt_disable();
+ /*
+ * If the process only ran on the local cpu, do a local flush.
+ */
local_cpumask = cpumask_of_cpu(smp_processor_id());
if (cpus_equal(mm->cpu_vm_mask, local_cpumask))
- local_flush_tlb();
+ __tlb_flush_local();
else
- global_flush_tlb();
+ __tlb_flush_global();
preempt_enable();
}
-static inline void flush_tlb(void)
-{
- __flush_tlb_mm(current->mm);
-}
-static inline void flush_tlb_all(void)
-{
- global_flush_tlb();
-}
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- __flush_tlb_mm(mm);
-}
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long addr)
+static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
{
- __flush_tlb_mm(vma->vm_mm);
+ if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm)
+ __tlb_flush_mm(mm);
}
-static inline void flush_tlb_range(struct vm_area_struct *vma,
- unsigned long start, unsigned long end)
-{
- __flush_tlb_mm(vma->vm_mm);
-}
-
-#define flush_tlb_kernel_range(start, end) global_flush_tlb()
-#endif
+/*
+ * TLB flushing:
+ * flush_tlb() - flushes the current mm struct TLBs
+ * flush_tlb_all() - flushes all processes TLBs
+ * flush_tlb_mm(mm) - flushes the specified mm context TLB's
+ * flush_tlb_page(vma, vmaddr) - flushes one page
+ * flush_tlb_range(vma, start, end) - flushes a range of pages
+ * flush_tlb_kernel_range(start, end) - flushes a range of kernel pages
+ */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* S/390 does not keep any page table caches in TLB */
-}
+/*
+ * flush_tlb_mm goes together with ptep_set_wrprotect for the
+ * copy_page_range operation and flush_tlb_range is related to
+ * ptep_get_and_clear for change_protection. ptep_set_wrprotect and
+ * ptep_get_and_clear do not flush the TLBs directly if the mm has
+ * only one user. At the end of the update the flush_tlb_mm and
+ * flush_tlb_range functions need to do the flush.
+ */
+#define flush_tlb() do { } while (0)
+#define flush_tlb_all() do { } while (0)
+#define flush_tlb_mm(mm) __tlb_flush_mm_cond(mm)
+#define flush_tlb_page(vma, addr) do { } while (0)
+#define flush_tlb_range(vma, start, end) __tlb_flush_mm_cond(mm)
+#define flush_tlb_kernel_range(start, end) __tlb_flush_mm(&init_mm)
#endif /* _S390_TLBFLUSH_H */
diff --git a/include/asm-sh/bitops.h b/include/asm-sh/bitops.h
index 9d7021723a2..df805f20b26 100644
--- a/include/asm-sh/bitops.h
+++ b/include/asm-sh/bitops.h
@@ -2,6 +2,11 @@
#define __ASM_SH_BITOPS_H
#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/system.h>
/* For __swab32 */
#include <asm/byteorder.h>
diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h
index b9ae53c3836..a7d0d1856a9 100644
--- a/include/asm-sh/scatterlist.h
+++ b/include/asm-sh/scatterlist.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;/* for highmem, page offset */
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-sh/se7751.h b/include/asm-sh/se7751.h
index 02ca9347f04..b36792ac5d6 100644
--- a/include/asm-sh/se7751.h
+++ b/include/asm-sh/se7751.h
@@ -36,7 +36,7 @@
#define PA_LED 0xba000000 /* LED */
#define PA_BCR 0xbb000000 /* FPGA on the MS7751SE01 */
-#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controller */
#define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */
#define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */
#define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */
diff --git a/include/asm-sh/systemh7751.h b/include/asm-sh/systemh7751.h
index b143bb2a2ca..4161122c84e 100644
--- a/include/asm-sh/systemh7751.h
+++ b/include/asm-sh/systemh7751.h
@@ -36,7 +36,7 @@
#define PA_LED 0xba000000 /* LED */
#define PA_BCR 0xbb000000 /* FPGA on the MS7751SE01 */
-#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controler */
+#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controller */
#define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */
#define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */
#define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */
diff --git a/include/asm-sh/tlbflush.h b/include/asm-sh/tlbflush.h
index 455fb8da441..e0ac97221ae 100644
--- a/include/asm-sh/tlbflush.h
+++ b/include/asm-sh/tlbflush.h
@@ -9,7 +9,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void local_flush_tlb_all(void);
extern void local_flush_tlb_mm(struct mm_struct *mm);
@@ -47,9 +46,4 @@ extern void flush_tlb_one(unsigned long asid, unsigned long page);
#endif /* CONFIG_SMP */
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* Nothing to do */
-}
#endif /* __ASM_SH_TLBFLUSH_H */
diff --git a/include/asm-sh64/bitops.h b/include/asm-sh64/bitops.h
index 444d5ea92ce..600c59efb4c 100644
--- a/include/asm-sh64/bitops.h
+++ b/include/asm-sh64/bitops.h
@@ -13,6 +13,11 @@
*/
#ifdef __KERNEL__
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/system.h>
/* For __swab32 */
diff --git a/include/asm-sh64/ide.h b/include/asm-sh64/ide.h
index c9d84d5f772..b6e31e8b941 100644
--- a/include/asm-sh64/ide.h
+++ b/include/asm-sh64/ide.h
@@ -19,7 +19,6 @@
/* Without this, the initialisation of PCI IDE cards end up calling
* ide_init_hwif_ports, which won't work. */
#ifdef CONFIG_BLK_DEV_IDEPCI
-#define IDE_ARCH_OBSOLETE_INIT 1
#define ide_default_io_ctl(base) (0)
#endif
diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h
index 1c723f2d7a9..5109251970e 100644
--- a/include/asm-sh64/scatterlist.h
+++ b/include/asm-sh64/scatterlist.h
@@ -14,7 +14,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page * page; /* Location for highmem page, if any */
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;/* for highmem, page offset */
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-sh64/system.h b/include/asm-sh64/system.h
index 5ff94644e8c..be2a15ffcc5 100644
--- a/include/asm-sh64/system.h
+++ b/include/asm-sh64/system.h
@@ -62,8 +62,7 @@ extern void __xchg_called_with_bad_pointer(void);
#define smp_read_barrier_depends() do { } while (0)
#endif /* CONFIG_SMP */
-#define set_rmb(var, value) do { (void)xchg(&var, value); } while (0)
-#define set_mb(var, value) set_rmb(var, value)
+#define set_mb(var, value) do { (void)xchg(&var, value); } while (0)
/* Interrupt Control */
#ifndef HARD_CLI
diff --git a/include/asm-sh64/tlbflush.h b/include/asm-sh64/tlbflush.h
index e45beadc29e..16a164a2375 100644
--- a/include/asm-sh64/tlbflush.h
+++ b/include/asm-sh64/tlbflush.h
@@ -20,10 +20,6 @@ extern void flush_tlb_mm(struct mm_struct *mm);
extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end);
extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
index 00bd0a679d7..cb3cefab6e0 100644
--- a/include/asm-sparc/bitops.h
+++ b/include/asm-sparc/bitops.h
@@ -14,6 +14,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask);
extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask);
extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask);
diff --git a/include/asm-sparc/ide.h b/include/asm-sparc/ide.h
index a6d735a1310..404022765fc 100644
--- a/include/asm-sparc/ide.h
+++ b/include/asm-sparc/ide.h
@@ -18,7 +18,6 @@
#undef MAX_HWIFS
#define MAX_HWIFS 2
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#define __ide_insl(data_reg, buffer, wcount) \
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index 4055af90ad7..e08d3d775b0 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -5,7 +5,10 @@
#include <linux/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-sparc/tlbflush.h b/include/asm-sparc/tlbflush.h
index a619da5cfaa..b957e29d2ae 100644
--- a/include/asm-sparc/tlbflush.h
+++ b/include/asm-sparc/tlbflush.h
@@ -13,7 +13,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
#ifdef CONFIG_SMP
@@ -42,11 +41,6 @@ BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
-// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee!
-// extern void flush_tlb_pgtables(struct mm_struct *mm,
-// unsigned long start, unsigned long end);
-#define flush_tlb_pgtables(mm, start, end) do{ }while(0)
-
#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h
index dd4bfe993b6..982ce8992b9 100644
--- a/include/asm-sparc64/bitops.h
+++ b/include/asm-sparc64/bitops.h
@@ -7,6 +7,10 @@
#ifndef _SPARC64_BITOPS_H
#define _SPARC64_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/byteorder.h>
diff --git a/include/asm-sparc64/ide.h b/include/asm-sparc64/ide.h
index 55149cf933c..ac7eb210b94 100644
--- a/include/asm-sparc64/ide.h
+++ b/include/asm-sparc64/ide.h
@@ -24,7 +24,6 @@
# endif
#endif
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#define __ide_insl(data_reg, buffer, wcount) \
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 703c5bbe6c8..6df23f070b1 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -6,7 +6,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index 42c09949526..1c1c5ea5cea 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -26,7 +26,7 @@
* Private routines/data
*/
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/atomic.h>
#include <asm/percpu.h>
diff --git a/include/asm-sparc64/tlbflush.h b/include/asm-sparc64/tlbflush.h
index 3487328570e..fbb675dbe0c 100644
--- a/include/asm-sparc64/tlbflush.h
+++ b/include/asm-sparc64/tlbflush.h
@@ -41,11 +41,4 @@ do { flush_tsb_kernel_range(start,end); \
#endif /* ! CONFIG_SMP */
-static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
- /* We don't use virtual page tables for TLB miss processing
- * any more. Nowadays we use the TSB.
- */
-}
-
#endif /* _SPARC64_TLBFLUSH_H */
diff --git a/include/asm-um/bitops.h b/include/asm-um/bitops.h
index 46d781953d3..e4d38d437b9 100644
--- a/include/asm-um/bitops.h
+++ b/include/asm-um/bitops.h
@@ -1,6 +1,10 @@
#ifndef __UM_BITOPS_H
#define __UM_BITOPS_H
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include "asm/arch/bitops.h"
#endif
diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h
index 9d647c55350..614f2c09117 100644
--- a/include/asm-um/tlbflush.h
+++ b/include/asm-um/tlbflush.h
@@ -17,7 +17,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_kernel_vm() flushes the kernel vm area
* - flush_tlb_range(vma, start, end) flushes a range of pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*/
extern void flush_tlb_all(void);
@@ -29,9 +28,4 @@ extern void flush_tlb_kernel_vm(void);
extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
extern void __flush_tlb_one(unsigned long addr);
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
#endif
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h
index 8eafdb1c08b..f82f5b4a56e 100644
--- a/include/asm-v850/bitops.h
+++ b/include/asm-v850/bitops.h
@@ -13,6 +13,9 @@
#ifndef __V850_BITOPS_H__
#define __V850_BITOPS_H__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
#include <linux/compiler.h> /* unlikely */
#include <asm/byteorder.h> /* swab32 */
diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h
index 56f402920db..02d27b3fb06 100644
--- a/include/asm-v850/scatterlist.h
+++ b/include/asm-v850/scatterlist.h
@@ -17,7 +17,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned offset;
dma_addr_t dma_address;
unsigned length;
diff --git a/include/asm-v850/system.h b/include/asm-v850/system.h
index 0de2481fd99..a34ddfafd56 100644
--- a/include/asm-v850/system.h
+++ b/include/asm-v850/system.h
@@ -66,8 +66,7 @@ static inline int irqs_disabled (void)
#define rmb() mb ()
#define wmb() mb ()
#define read_barrier_depends() ((void)0)
-#define set_rmb(var, value) do { xchg (&var, value); } while (0)
-#define set_mb(var, value) set_rmb (var, value)
+#define set_mb(var, value) do { xchg (&var, value); } while (0)
#define smp_mb() mb ()
#define smp_rmb() rmb ()
diff --git a/include/asm-v850/tlbflush.h b/include/asm-v850/tlbflush.h
index 5f2f85f636e..c44aa64449c 100644
--- a/include/asm-v850/tlbflush.h
+++ b/include/asm-v850/tlbflush.h
@@ -61,10 +61,4 @@ static inline void flush_tlb_kernel_page(unsigned long addr)
BUG ();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- BUG ();
-}
-
#endif /* __V850_TLBFLUSH_H__ */
diff --git a/include/asm-x86/acpi_32.h b/include/asm-x86/acpi_32.h
index 125179adf04..723493e6c85 100644
--- a/include/asm-x86/acpi_32.h
+++ b/include/asm-x86/acpi_32.h
@@ -81,11 +81,7 @@ int __acpi_release_global_lock(unsigned int *lock);
:"=r"(n_hi), "=r"(n_lo) \
:"0"(n_hi), "1"(n_lo))
-#ifdef CONFIG_X86_IO_APIC
-extern void check_acpi_pci(void);
-#else
-static inline void check_acpi_pci(void) { }
-#endif
+extern void early_quirks(void);
#ifdef CONFIG_ACPI
extern int acpi_lapic;
diff --git a/include/asm-x86/bitops_32.h b/include/asm-x86/bitops_32.h
index c96641f7502..3268a341cf4 100644
--- a/include/asm-x86/bitops_32.h
+++ b/include/asm-x86/bitops_32.h
@@ -5,6 +5,10 @@
* Copyright 1992, Linus Torvalds.
*/
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <linux/compiler.h>
#include <asm/alternative.h>
diff --git a/include/asm-x86/bitops_64.h b/include/asm-x86/bitops_64.h
index 525edf2ce5c..dacaa5f1feb 100644
--- a/include/asm-x86/bitops_64.h
+++ b/include/asm-x86/bitops_64.h
@@ -5,6 +5,10 @@
* Copyright 1992, Linus Torvalds.
*/
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/alternative.h>
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
diff --git a/include/asm-x86/bootparam.h b/include/asm-x86/bootparam.h
index ef67b59dbdb..dc031cf4463 100644
--- a/include/asm-x86/bootparam.h
+++ b/include/asm-x86/bootparam.h
@@ -28,8 +28,9 @@ struct setup_header {
u16 kernel_version;
u8 type_of_loader;
u8 loadflags;
-#define LOADED_HIGH 0x01
-#define CAN_USE_HEAP 0x80
+#define LOADED_HIGH (1<<0)
+#define KEEP_SEGMENTS (1<<6)
+#define CAN_USE_HEAP (1<<7)
u16 setup_move_size;
u32 code32_start;
u32 ramdisk_image;
@@ -41,6 +42,10 @@ struct setup_header {
u32 initrd_addr_max;
u32 kernel_alignment;
u8 relocatable_kernel;
+ u8 _pad2[3];
+ u32 cmdline_size;
+ u32 hardware_subarch;
+ u64 hardware_subarch_data;
} __attribute__((packed));
struct sys_desc_table {
diff --git a/include/asm-x86/cacheflush.h b/include/asm-x86/cacheflush.h
index b3d43de44c5..9411a2d3f19 100644
--- a/include/asm-x86/cacheflush.h
+++ b/include/asm-x86/cacheflush.h
@@ -27,6 +27,7 @@
void global_flush_tlb(void);
int change_page_attr(struct page *page, int numpages, pgprot_t prot);
int change_page_attr_addr(unsigned long addr, int numpages, pgprot_t prot);
+void clflush_cache_range(void *addr, int size);
#ifdef CONFIG_DEBUG_PAGEALLOC
/* internal debugging function */
diff --git a/include/asm-x86/compat.h b/include/asm-x86/compat.h
index 53cb96b68a6..66ba7987184 100644
--- a/include/asm-x86/compat.h
+++ b/include/asm-x86/compat.h
@@ -6,6 +6,7 @@
*/
#include <linux/types.h>
#include <linux/sched.h>
+#include <asm/user32.h>
#define COMPAT_USER_HZ 100
@@ -181,6 +182,11 @@ struct compat_shmid64_ds {
};
/*
+ * The type of struct elf_prstatus.pr_reg in compatible core dumps.
+ */
+typedef struct user_regs_struct32 compat_elf_gregset_t;
+
+/*
* A pointer passed in from user mode. This should not
* be used for syscall parameters, just declare them
* as pointers because the syscall entry code will have
diff --git a/include/asm-x86/desc_64.h b/include/asm-x86/desc_64.h
index ac991b5ca0f..7d9c938e69f 100644
--- a/include/asm-x86/desc_64.h
+++ b/include/asm-x86/desc_64.h
@@ -20,6 +20,16 @@ extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
#define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8))
#define clear_LDT() asm volatile("lldt %w0"::"r" (0))
+static inline unsigned long __store_tr(void)
+{
+ unsigned long tr;
+
+ asm volatile ("str %w0":"=r" (tr));
+ return tr;
+}
+
+#define store_tr(tr) (tr) = __store_tr()
+
/*
* This is the ldt that every process will get unless we need
* something other than this.
@@ -31,6 +41,16 @@ extern struct desc_ptr cpu_gdt_descr[];
/* the cpu gdt accessor */
#define cpu_gdt(_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address)
+static inline void load_gdt(const struct desc_ptr *ptr)
+{
+ asm volatile("lgdt %w0"::"m" (*ptr));
+}
+
+static inline void store_gdt(struct desc_ptr *ptr)
+{
+ asm("sgdt %w0":"=m" (*ptr));
+}
+
static inline void _set_gate(void *adr, unsigned type, unsigned long func, unsigned dpl, unsigned ist)
{
struct gate_struct s;
@@ -71,6 +91,16 @@ static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
}
+static inline void load_idt(const struct desc_ptr *ptr)
+{
+ asm volatile("lidt %w0"::"m" (*ptr));
+}
+
+static inline void store_idt(struct desc_ptr *dtr)
+{
+ asm("sidt %w0":"=m" (*dtr));
+}
+
static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type,
unsigned size)
{
diff --git a/include/asm-x86/device.h b/include/asm-x86/device.h
index d9ee5e52e91..87a715367a1 100644
--- a/include/asm-x86/device.h
+++ b/include/asm-x86/device.h
@@ -5,6 +5,9 @@ struct dev_archdata {
#ifdef CONFIG_ACPI
void *acpi_handle;
#endif
+#ifdef CONFIG_DMAR
+ void *iommu; /* hook for IOMMU specific extension */
+#endif
};
#endif /* _ASM_X86_DEVICE_H */
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 6a2d26cb5da..55f01bd9e55 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -45,9 +45,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
WARN_ON(nents == 0 || sglist[0].length == 0);
for_each_sg(sglist, sg, nents, i) {
- BUG_ON(!sg->page);
+ BUG_ON(!sg_page(sg));
- sg->dma_address = page_to_phys(sg->page) + sg->offset;
+ sg->dma_address = sg_phys(sg);
}
flush_write_buffers();
diff --git a/include/asm-x86/geode.h b/include/asm-x86/geode.h
index d94898831ba..771af336734 100644
--- a/include/asm-x86/geode.h
+++ b/include/asm-x86/geode.h
@@ -38,6 +38,8 @@ extern int geode_get_dev_base(unsigned int dev);
#define MSR_LBAR_ACPI 0x5140000E
#define MSR_LBAR_PMS 0x5140000F
+#define MSR_DIVIL_SOFT_RESET 0x51400017
+
#define MSR_PIC_YSEL_LOW 0x51400020
#define MSR_PIC_YSEL_HIGH 0x51400021
#define MSR_PIC_ZSEL_LOW 0x51400022
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index d4ab6db050b..b1f3c1ea55d 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -3,12 +3,6 @@
#ifdef CONFIG_HPET_TIMER
-/*
- * Documentation on HPET can be found at:
- * http://www.intel.com/ial/home/sp/pcmmspec.htm
- * ftp://download.intel.com/ial/home/sp/mmts098.pdf
- */
-
#define HPET_MMAP_SIZE 1024
#define HPET_ID 0x000
@@ -64,6 +58,7 @@
/* hpet memory map physical address */
extern unsigned long hpet_address;
extern unsigned long force_hpet_address;
+extern int hpet_force_user;
extern int is_hpet_enabled(void);
extern int hpet_enable(void);
extern unsigned long hpet_readl(unsigned long a);
diff --git a/include/asm-x86/ide.h b/include/asm-x86/ide.h
index e7817a3d657..42130adf9c7 100644
--- a/include/asm-x86/ide.h
+++ b/include/asm-x86/ide.h
@@ -62,7 +62,6 @@ static __inline__ unsigned long ide_default_io_base(int index)
}
}
-#define IDE_ARCH_OBSOLETE_INIT
#define ide_default_io_ctl(base) ((base) + 0x206) /* obsolete */
#ifdef CONFIG_BLK_DEV_IDEPCI
diff --git a/include/asm-x86/io_apic_64.h b/include/asm-x86/io_apic_64.h
index d9f2e54324d..e2c13675ee4 100644
--- a/include/asm-x86/io_apic_64.h
+++ b/include/asm-x86/io_apic_64.h
@@ -133,4 +133,6 @@ void enable_NMI_through_LVT0 (void * dummy);
extern spinlock_t i8259A_lock;
+extern int timer_over_8254;
+
#endif
diff --git a/include/asm-x86/ipi.h b/include/asm-x86/ipi.h
index a7c75ea408a..6d011bd6067 100644
--- a/include/asm-x86/ipi.h
+++ b/include/asm-x86/ipi.h
@@ -119,7 +119,7 @@ static inline void send_IPI_mask_sequence(cpumask_t mask, int vector)
*/
local_irq_save(flags);
for_each_cpu_mask(query_cpu, mask) {
- __send_IPI_dest_field(x86_cpu_to_apicid[query_cpu],
+ __send_IPI_dest_field(per_cpu(x86_cpu_to_apicid, query_cpu),
vector, APIC_DEST_PHYSICAL);
}
local_irq_restore(flags);
diff --git a/include/asm-x86/irq_32.h b/include/asm-x86/irq_32.h
index 36f310632c4..aca9c96e8e6 100644
--- a/include/asm-x86/irq_32.h
+++ b/include/asm-x86/irq_32.h
@@ -45,4 +45,7 @@ unsigned int do_IRQ(struct pt_regs *regs);
void init_IRQ(void);
void __init native_init_IRQ(void);
+/* Interrupt vector management */
+extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
+
#endif /* _ASM_IRQ_H */
diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h
index a02eb299134..a4944732be0 100644
--- a/include/asm-x86/msr-index.h
+++ b/include/asm-x86/msr-index.h
@@ -73,8 +73,32 @@
#define MSR_P6_EVNTSEL0 0x00000186
#define MSR_P6_EVNTSEL1 0x00000187
-/* K7/K8 MSRs. Not complete. See the architecture manual for a more
+/* AMD64 MSRs. Not complete. See the architecture manual for a more
complete list. */
+
+#define MSR_AMD64_IBSFETCHCTL 0xc0011030
+#define MSR_AMD64_IBSFETCHLINAD 0xc0011031
+#define MSR_AMD64_IBSFETCHPHYSAD 0xc0011032
+#define MSR_AMD64_IBSOPCTL 0xc0011033
+#define MSR_AMD64_IBSOPRIP 0xc0011034
+#define MSR_AMD64_IBSOPDATA 0xc0011035
+#define MSR_AMD64_IBSOPDATA2 0xc0011036
+#define MSR_AMD64_IBSOPDATA3 0xc0011037
+#define MSR_AMD64_IBSDCLINAD 0xc0011038
+#define MSR_AMD64_IBSDCPHYSAD 0xc0011039
+#define MSR_AMD64_IBSCTL 0xc001103a
+
+/* K8 MSRs */
+#define MSR_K8_TOP_MEM1 0xc001001a
+#define MSR_K8_TOP_MEM2 0xc001001d
+#define MSR_K8_SYSCFG 0xc0010010
+#define MSR_K8_HWCR 0xc0010015
+#define MSR_K8_ENABLE_C1E 0xc0010055
+#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */
+#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */
+#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */
+
+/* K7 MSRs */
#define MSR_K7_EVNTSEL0 0xc0010000
#define MSR_K7_PERFCTR0 0xc0010004
#define MSR_K7_EVNTSEL1 0xc0010001
@@ -83,20 +107,10 @@
#define MSR_K7_PERFCTR2 0xc0010006
#define MSR_K7_EVNTSEL3 0xc0010003
#define MSR_K7_PERFCTR3 0xc0010007
-#define MSR_K8_TOP_MEM1 0xc001001a
#define MSR_K7_CLK_CTL 0xc001001b
-#define MSR_K8_TOP_MEM2 0xc001001d
-#define MSR_K8_SYSCFG 0xc0010010
-
-#define K8_MTRRFIXRANGE_DRAM_ENABLE 0x00040000 /* MtrrFixDramEn bit */
-#define K8_MTRRFIXRANGE_DRAM_MODIFY 0x00080000 /* MtrrFixDramModEn bit */
-#define K8_MTRR_RDMEM_WRMEM_MASK 0x18181818 /* Mask: RdMem|WrMem */
-
#define MSR_K7_HWCR 0xc0010015
-#define MSR_K8_HWCR 0xc0010015
#define MSR_K7_FID_VID_CTL 0xc0010041
#define MSR_K7_FID_VID_STATUS 0xc0010042
-#define MSR_K8_ENABLE_C1E 0xc0010055
/* K6 MSRs */
#define MSR_K6_EFER 0xc0000080
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index acd4b339c49..ed3e70d8d04 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -17,10 +17,7 @@
#include <linux/threads.h>
#include <asm/paravirt.h>
-#ifndef _I386_BITOPS_H
-#include <asm/bitops.h>
-#endif
-
+#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index a79f5355e3b..9b0ff477b39 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -9,7 +9,7 @@
* the x86-64 page table tree.
*/
#include <asm/processor.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <linux/threads.h>
#include <asm/pda.h>
diff --git a/include/asm-x86/processor_32.h b/include/asm-x86/processor_32.h
index 83800e7496e..13976b08683 100644
--- a/include/asm-x86/processor_32.h
+++ b/include/asm-x86/processor_32.h
@@ -79,6 +79,7 @@ struct cpuinfo_x86 {
unsigned char booted_cores; /* number of cores as seen by OS */
__u8 phys_proc_id; /* Physical processor id. */
__u8 cpu_core_id; /* Core id */
+ __u8 cpu_index; /* index into per_cpu list */
#endif
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
@@ -103,14 +104,19 @@ extern struct tss_struct doublefault_tss;
DECLARE_PER_CPU(struct tss_struct, init_tss);
#ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu) per_cpu(cpu_info, cpu)
+#define current_cpu_data cpu_data(smp_processor_id())
#else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu) boot_cpu_data
+#define current_cpu_data boot_cpu_data
#endif
-extern int cpu_llc_id[NR_CPUS];
+/*
+ * the following now lives in the per cpu area:
+ * extern int cpu_llc_id[NR_CPUS];
+ */
+DECLARE_PER_CPU(u8, cpu_llc_id);
extern char ignore_fpu_irq;
void __init cpu_detect(struct cpuinfo_x86 *c);
diff --git a/include/asm-x86/processor_64.h b/include/asm-x86/processor_64.h
index f422becbddd..e4f19970a82 100644
--- a/include/asm-x86/processor_64.h
+++ b/include/asm-x86/processor_64.h
@@ -74,6 +74,7 @@ struct cpuinfo_x86 {
__u8 booted_cores; /* number of cores as seen by OS */
__u8 phys_proc_id; /* Physical Processor id. */
__u8 cpu_core_id; /* Core id. */
+ __u8 cpu_index; /* index into per_cpu list */
#endif
} ____cacheline_aligned;
@@ -88,11 +89,12 @@ struct cpuinfo_x86 {
#define X86_VENDOR_UNKNOWN 0xff
#ifdef CONFIG_SMP
-extern struct cpuinfo_x86 cpu_data[];
-#define current_cpu_data cpu_data[smp_processor_id()]
+DECLARE_PER_CPU(struct cpuinfo_x86, cpu_info);
+#define cpu_data(cpu) per_cpu(cpu_info, cpu)
+#define current_cpu_data cpu_data(smp_processor_id())
#else
-#define cpu_data (&boot_cpu_data)
-#define current_cpu_data boot_cpu_data
+#define cpu_data(cpu) boot_cpu_data
+#define current_cpu_data boot_cpu_data
#endif
extern char ignore_irq13;
@@ -390,12 +392,6 @@ static inline void sync_core(void)
asm volatile("cpuid" : "=a" (tmp) : "0" (1) : "ebx","ecx","edx","memory");
}
-#define ARCH_HAS_PREFETCH
-static inline void prefetch(void *x)
-{
- asm volatile("prefetcht0 (%0)" :: "r" (x));
-}
-
#define ARCH_HAS_PREFETCHW 1
static inline void prefetchw(void *x)
{
diff --git a/include/asm-x86/proto.h b/include/asm-x86/proto.h
index c44a3a93b5a..dabba55f7ed 100644
--- a/include/asm-x86/proto.h
+++ b/include/asm-x86/proto.h
@@ -83,8 +83,6 @@ extern unsigned tsc_khz;
extern int reboot_force;
extern int notsc_setup(char *);
-extern int timer_over_8254;
-
extern int gsi_irq_sharing(int gsi);
extern int force_mwait;
diff --git a/include/asm-x86/ptrace_32.h b/include/asm-x86/ptrace_32.h
index 6002597b9e1..78d063dabe0 100644
--- a/include/asm-x86/ptrace_32.h
+++ b/include/asm-x86/ptrace_32.h
@@ -55,6 +55,8 @@ static inline int v8086_mode(struct pt_regs *regs)
}
#define instruction_pointer(regs) ((regs)->eip)
+#define frame_pointer(regs) ((regs)->ebp)
+#define stack_pointer(regs) ((regs)->esp)
#define regs_return_value(regs) ((regs)->eax)
extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/include/asm-x86/ptrace_64.h b/include/asm-x86/ptrace_64.h
index 7f166ccb060..7bfe61e1b70 100644
--- a/include/asm-x86/ptrace_64.h
+++ b/include/asm-x86/ptrace_64.h
@@ -40,6 +40,8 @@ struct pt_regs {
#define user_mode(regs) (!!((regs)->cs & 3))
#define user_mode_vm(regs) user_mode(regs)
#define instruction_pointer(regs) ((regs)->rip)
+#define frame_pointer(regs) ((regs)->rbp)
+#define stack_pointer(regs) ((regs)->rsp)
#define regs_return_value(regs) ((regs)->rax)
extern unsigned long profile_pc(struct pt_regs *regs);
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index bd5164aa8f6..0e7d997a34b 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index ef3986ba4b7..1847c72befe 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -4,7 +4,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
unsigned int length;
dma_addr_t dma_address;
diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h
index ee46038d126..7056d868452 100644
--- a/include/asm-x86/smp_32.h
+++ b/include/asm-x86/smp_32.h
@@ -11,7 +11,7 @@
#endif
#if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__)
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/mpspec.h>
#include <asm/apic.h>
#ifdef CONFIG_X86_IO_APIC
@@ -39,9 +39,11 @@ extern void lock_ipi_call_lock(void);
extern void unlock_ipi_call_lock(void);
#define MAX_APICID 256
-extern u8 x86_cpu_to_apicid[];
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid);
-#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
extern void set_cpu_sibling_map(int cpu);
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h
index d30e9b684fd..6f0e0273b64 100644
--- a/include/asm-x86/smp_64.h
+++ b/include/asm-x86/smp_64.h
@@ -37,6 +37,8 @@ extern void lock_ipi_call_lock(void);
extern void unlock_ipi_call_lock(void);
extern int smp_num_siblings;
extern void smp_send_reschedule(int cpu);
+extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
+ void *info, int wait);
/*
* cpu_sibling_map and cpu_core_map now live
@@ -47,7 +49,7 @@ extern void smp_send_reschedule(int cpu);
*/
DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
-extern u8 cpu_llc_id[NR_CPUS];
+DECLARE_PER_CPU(u8, cpu_llc_id);
#define SMP_TRAMPOLINE_BASE 0x6000
@@ -84,7 +86,9 @@ static inline int hard_smp_processor_id(void)
* Some lowlevel functions might want to know about
* the real APIC ID <-> CPU # mapping.
*/
-extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */
+extern u8 __initdata x86_cpu_to_apicid_init[];
+extern void *x86_cpu_to_apicid_ptr;
+DECLARE_PER_CPU(u8, x86_cpu_to_apicid); /* physical ID */
extern u8 bios_cpu_apicid[];
static inline int cpu_present_to_apicid(int mps_cpu)
@@ -115,8 +119,9 @@ static __inline int logical_smp_processor_id(void)
}
#ifdef CONFIG_SMP
-#define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu]
+#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
#else
+extern unsigned int boot_cpu_id;
#define cpu_physical_id(cpu) boot_cpu_id
#endif /* !CONFIG_SMP */
#endif
diff --git a/include/asm-x86/system_32.h b/include/asm-x86/system_32.h
index db6283eb5e4..ef8468883ba 100644
--- a/include/asm-x86/system_32.h
+++ b/include/asm-x86/system_32.h
@@ -315,5 +315,6 @@ extern unsigned long arch_align_stack(unsigned long sp);
extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
void default_idle(void);
+void __show_registers(struct pt_regs *, int all);
#endif
diff --git a/include/asm-x86/tlbflush_32.h b/include/asm-x86/tlbflush_32.h
index a50fa674148..2bd5b95e204 100644
--- a/include/asm-x86/tlbflush_32.h
+++ b/include/asm-x86/tlbflush_32.h
@@ -78,7 +78,6 @@
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
* - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus
*
* ..but the i386 has somewhat limited tlb flushing capabilities,
@@ -166,10 +165,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
flush_tlb_all();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* i386 does not keep any page table caches in TLB */
-}
-
#endif /* _I386_TLBFLUSH_H */
diff --git a/include/asm-x86/tlbflush_64.h b/include/asm-x86/tlbflush_64.h
index 888eb4abdd0..7731fd23d57 100644
--- a/include/asm-x86/tlbflush_64.h
+++ b/include/asm-x86/tlbflush_64.h
@@ -31,7 +31,6 @@ static inline void __flush_tlb_all(void)
* - flush_tlb_page(vma, vmaddr) flushes one page
* - flush_tlb_range(vma, start, end) flushes a range of pages
* - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
- * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
*
* x86-64 can only flush individual pages or full VMs. For a range flush
* we always do the full VM. Might be worth trying if for a small
@@ -98,12 +97,4 @@ static inline void flush_tlb_kernel_range(unsigned long start,
flush_tlb_all();
}
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- /* x86_64 does not keep any page table caches in a software TLB.
- The CPUs do in their hardware TLBs, but they are handled
- by the normal TLB flushing algorithms. */
-}
-
#endif /* _X8664_TLBFLUSH_H */
diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h
index ae1074603c4..9040f5a6127 100644
--- a/include/asm-x86/topology_32.h
+++ b/include/asm-x86/topology_32.h
@@ -28,8 +28,8 @@
#define _ASM_I386_TOPOLOGY_H
#ifdef CONFIG_X86_HT
-#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#endif
diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h
index 848c17f9222..a718dda037e 100644
--- a/include/asm-x86/topology_64.h
+++ b/include/asm-x86/topology_64.h
@@ -5,7 +5,7 @@
#ifdef CONFIG_NUMA
#include <asm/mpspec.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
extern cpumask_t cpu_online_map;
@@ -56,8 +56,8 @@ extern int __node_distance(int, int);
#endif
#ifdef CONFIG_SMP
-#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
-#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
+#define topology_physical_package_id(cpu) (cpu_data(cpu).phys_proc_id)
+#define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id)
#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
#define mc_capable() (boot_cpu_data.x86_max_cores > 1)
diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h
index 78db04cf6e4..23261e8f2e5 100644
--- a/include/asm-xtensa/bitops.h
+++ b/include/asm-xtensa/bitops.h
@@ -15,6 +15,10 @@
#ifdef __KERNEL__
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
#include <asm/processor.h>
#include <asm/byteorder.h>
#include <asm/system.h>
diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h
index ca337a29429..810080bb0a2 100644
--- a/include/asm-xtensa/scatterlist.h
+++ b/include/asm-xtensa/scatterlist.h
@@ -14,7 +14,10 @@
#include <asm/types.h>
struct scatterlist {
- struct page *page;
+#ifdef CONFIG_DEBUG_SG
+ unsigned long sg_magic;
+#endif
+ unsigned long page_link;
unsigned int offset;
dma_addr_t dma_address;
unsigned int length;
diff --git a/include/asm-xtensa/tlbflush.h b/include/asm-xtensa/tlbflush.h
index 7c637b3c352..46d240074f7 100644
--- a/include/asm-xtensa/tlbflush.h
+++ b/include/asm-xtensa/tlbflush.h
@@ -41,17 +41,6 @@ extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long);
#define flush_tlb_kernel_range(start,end) flush_tlb_all()
-
-/* This is calld in munmap when we have freed up some page-table pages.
- * We don't need to do anything here, there's nothing special about our
- * page-table pages.
- */
-
-static inline void flush_tlb_pgtables(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
-}
-
/* TLB operations. */
static inline unsigned long itlb_probe(unsigned long addr)
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 7ac8303c847..e3ffd14a3f0 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -47,6 +47,7 @@ header-y += coda_psdev.h
header-y += coff.h
header-y += comstats.h
header-y += const.h
+header-y += cgroupstats.h
header-y += cycx_cfm.h
header-y += dlm_device.h
header-y += dlm_netlink.h
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index bf5e0009de7..8ccedf7a0a5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -189,32 +189,6 @@ extern int ec_transaction(u8 command,
extern int acpi_blacklisted(void);
extern void acpi_bios_year(char *s);
-#define ACPI_CSTATE_LIMIT_DEFINED /* for driver builds */
-#ifdef CONFIG_ACPI
-
-/*
- * Set highest legal C-state
- * 0: C0 okay, but not C1
- * 1: C1 okay, but not C2
- * 2: C2 okay, but not C3 etc.
- */
-
-extern unsigned int max_cstate;
-
-static inline unsigned int acpi_get_cstate_limit(void)
-{
- return max_cstate;
-}
-static inline void acpi_set_cstate_limit(unsigned int new_limit)
-{
- max_cstate = new_limit;
- return;
-}
-#else
-static inline unsigned int acpi_get_cstate_limit(void) { return 0; }
-static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; }
-#endif
-
#ifdef CONFIG_ACPI_NUMA
int acpi_get_pxm(acpi_handle handle);
int acpi_get_node(acpi_handle *handle);
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9ae740936a6..c6878169283 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -63,6 +63,8 @@
#define AUDIT_ADD_RULE 1011 /* Add syscall filtering rule */
#define AUDIT_DEL_RULE 1012 /* Delete syscall filtering rule */
#define AUDIT_LIST_RULES 1013 /* List syscall filtering rules */
+#define AUDIT_TRIM 1014 /* Trim junk from watched tree */
+#define AUDIT_MAKE_EQUIV 1015 /* Append to watched tree */
#define AUDIT_TTY_GET 1016 /* Get TTY auditing status */
#define AUDIT_TTY_SET 1017 /* Set TTY auditing status */
@@ -203,6 +205,7 @@
#define AUDIT_SUCCESS 104 /* exit >= 0; value ignored */
#define AUDIT_WATCH 105
#define AUDIT_PERM 106
+#define AUDIT_DIR 107
#define AUDIT_ARG0 200
#define AUDIT_ARG1 (AUDIT_ARG0+1)
@@ -366,8 +369,8 @@ extern void audit_syscall_entry(int arch,
extern void audit_syscall_exit(int failed, long return_code);
extern void __audit_getname(const char *name);
extern void audit_putname(const char *name);
-extern void __audit_inode(const char *name, const struct inode *inode);
-extern void __audit_inode_child(const char *dname, const struct inode *inode,
+extern void __audit_inode(const char *name, const struct dentry *dentry);
+extern void __audit_inode_child(const char *dname, const struct dentry *dentry,
const struct inode *parent);
extern void __audit_ptrace(struct task_struct *t);
@@ -381,15 +384,15 @@ static inline void audit_getname(const char *name)
if (unlikely(!audit_dummy_context()))
__audit_getname(name);
}
-static inline void audit_inode(const char *name, const struct inode *inode) {
+static inline void audit_inode(const char *name, const struct dentry *dentry) {
if (unlikely(!audit_dummy_context()))
- __audit_inode(name, inode);
+ __audit_inode(name, dentry);
}
static inline void audit_inode_child(const char *dname,
- const struct inode *inode,
+ const struct dentry *dentry,
const struct inode *parent) {
if (unlikely(!audit_dummy_context()))
- __audit_inode_child(dname, inode, parent);
+ __audit_inode_child(dname, dentry, parent);
}
void audit_core_dumps(long signr);
@@ -477,9 +480,9 @@ extern int audit_signals;
#define audit_dummy_context() 1
#define audit_getname(n) do { ; } while (0)
#define audit_putname(n) do { ; } while (0)
-#define __audit_inode(n,i) do { ; } while (0)
+#define __audit_inode(n,d) do { ; } while (0)
#define __audit_inode_child(d,i,p) do { ; } while (0)
-#define audit_inode(n,i) do { ; } while (0)
+#define audit_inode(n,d) do { ; } while (0)
#define audit_inode_child(d,i,p) do { ; } while (0)
#define audit_core_dumps(i) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) do { BUG(); } while (0)
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 64b4641904f..acad1105d94 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -6,6 +6,7 @@
#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/string.h>
+#include <linux/kernel.h>
/*
* bitmaps provide bit arrays that consume one or more unsigned
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index b9fb8ee3308..69c1edb9fe5 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -2,6 +2,14 @@
#define _LINUX_BITOPS_H
#include <asm/types.h>
+#ifdef __KERNEL__
+#define BIT(nr) (1UL << (nr))
+#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
+#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
+#define BITS_PER_BYTE 8
+#endif
+
/*
* Include this here because some architectures need generic_ffs/fls in
* scope
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 7a8d7ade28a..bb017edffd5 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -56,10 +56,8 @@ typedef struct __user_cap_data_struct {
struct vfs_cap_data {
__u32 magic_etc; /* Little endian */
- struct {
- __u32 permitted; /* Little endian */
- __u32 inheritable; /* Little endian */
- } data[1];
+ __u32 permitted; /* Little endian */
+ __u32 inheritable; /* Little endian */
};
#ifdef __KERNEL__
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h
index 2b641b176e7..c6d3e22c062 100644
--- a/include/linux/cdrom.h
+++ b/include/linux/cdrom.h
@@ -2,7 +2,7 @@
* -- <linux/cdrom.h>
* General header file for linux CD-ROM drivers
* Copyright (C) 1992 David Giller, rafetmad@oxy.edu
- * 1994, 1995 Eberhard Moenkeberg, emoenke@gwdg.de
+ * 1994, 1995 Eberhard Mönkeberg, emoenke@gwdg.de
* 1996 David van Leeuwen, david@tm.tno.nl
* 1997, 1998 Erik Andersen, andersee@debian.org
* 1998-2002 Jens Axboe, axboe@suse.de
@@ -76,7 +76,7 @@
(struct cdrom_multisession) */
#define CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
if available (struct cdrom_mcn) */
-#define CDROM_GET_UPC CDROM_GET_MCN /* This one is depricated,
+#define CDROM_GET_UPC CDROM_GET_MCN /* This one is deprecated,
but here anyway for compatibility */
#define CDROMRESET 0x5312 /* hard-reset the drive */
#define CDROMVOLREAD 0x5313 /* Get the drive's volume setting
@@ -506,7 +506,7 @@ struct cdrom_generic_command
#define GPMODE_TO_PROTECT_PAGE 0x1d
#define GPMODE_CAPABILITIES_PAGE 0x2a
#define GPMODE_ALL_PAGES 0x3f
-/* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
+/* Not in Mt. Fuji, but in ATAPI 2.6 -- deprecated now in favor
* of MODE_SENSE_POWER_PAGE */
#define GPMODE_CDROM_PAGE 0x0d
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
new file mode 100644
index 00000000000..87479328d46
--- /dev/null
+++ b/include/linux/cgroup.h
@@ -0,0 +1,327 @@
+#ifndef _LINUX_CGROUP_H
+#define _LINUX_CGROUP_H
+/*
+ * cgroup interface
+ *
+ * Copyright (C) 2003 BULL SA
+ * Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/kref.h>
+#include <linux/cpumask.h>
+#include <linux/nodemask.h>
+#include <linux/rcupdate.h>
+#include <linux/cgroupstats.h>
+
+#ifdef CONFIG_CGROUPS
+
+struct cgroupfs_root;
+struct cgroup_subsys;
+struct inode;
+
+extern int cgroup_init_early(void);
+extern int cgroup_init(void);
+extern void cgroup_init_smp(void);
+extern void cgroup_lock(void);
+extern void cgroup_unlock(void);
+extern void cgroup_fork(struct task_struct *p);
+extern void cgroup_fork_callbacks(struct task_struct *p);
+extern void cgroup_post_fork(struct task_struct *p);
+extern void cgroup_exit(struct task_struct *p, int run_callbacks);
+extern int cgroupstats_build(struct cgroupstats *stats,
+ struct dentry *dentry);
+
+extern struct file_operations proc_cgroup_operations;
+
+/* Define the enumeration of all cgroup subsystems */
+#define SUBSYS(_x) _x ## _subsys_id,
+enum cgroup_subsys_id {
+#include <linux/cgroup_subsys.h>
+ CGROUP_SUBSYS_COUNT
+};
+#undef SUBSYS
+
+/* Per-subsystem/per-cgroup state maintained by the system. */
+struct cgroup_subsys_state {
+ /* The cgroup that this subsystem is attached to. Useful
+ * for subsystems that want to know about the cgroup
+ * hierarchy structure */
+ struct cgroup *cgroup;
+
+ /* State maintained by the cgroup system to allow
+ * subsystems to be "busy". Should be accessed via css_get()
+ * and css_put() */
+
+ atomic_t refcnt;
+
+ unsigned long flags;
+};
+
+/* bits in struct cgroup_subsys_state flags field */
+enum {
+ CSS_ROOT, /* This CSS is the root of the subsystem */
+};
+
+/*
+ * Call css_get() to hold a reference on the cgroup;
+ *
+ */
+
+static inline void css_get(struct cgroup_subsys_state *css)
+{
+ /* We don't need to reference count the root state */
+ if (!test_bit(CSS_ROOT, &css->flags))
+ atomic_inc(&css->refcnt);
+}
+/*
+ * css_put() should be called to release a reference taken by
+ * css_get()
+ */
+
+extern void __css_put(struct cgroup_subsys_state *css);
+static inline void css_put(struct cgroup_subsys_state *css)
+{
+ if (!test_bit(CSS_ROOT, &css->flags))
+ __css_put(css);
+}
+
+struct cgroup {
+ unsigned long flags; /* "unsigned long" so bitops work */
+
+ /* count users of this cgroup. >0 means busy, but doesn't
+ * necessarily indicate the number of tasks in the
+ * cgroup */
+ atomic_t count;
+
+ /*
+ * We link our 'sibling' struct into our parent's 'children'.
+ * Our children link their 'sibling' into our 'children'.
+ */
+ struct list_head sibling; /* my parent's children */
+ struct list_head children; /* my children */
+
+ struct cgroup *parent; /* my parent */
+ struct dentry *dentry; /* cgroup fs entry */
+
+ /* Private pointers for each registered subsystem */
+ struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+ struct cgroupfs_root *root;
+ struct cgroup *top_cgroup;
+
+ /*
+ * List of cg_cgroup_links pointing at css_sets with
+ * tasks in this cgroup. Protected by css_set_lock
+ */
+ struct list_head css_sets;
+
+ /*
+ * Linked list running through all cgroups that can
+ * potentially be reaped by the release agent. Protected by
+ * release_list_lock
+ */
+ struct list_head release_list;
+};
+
+/* A css_set is a structure holding pointers to a set of
+ * cgroup_subsys_state objects. This saves space in the task struct
+ * object and speeds up fork()/exit(), since a single inc/dec and a
+ * list_add()/del() can bump the reference count on the entire
+ * cgroup set for a task.
+ */
+
+struct css_set {
+
+ /* Reference count */
+ struct kref ref;
+
+ /*
+ * List running through all cgroup groups. Protected by
+ * css_set_lock
+ */
+ struct list_head list;
+
+ /*
+ * List running through all tasks using this cgroup
+ * group. Protected by css_set_lock
+ */
+ struct list_head tasks;
+
+ /*
+ * List of cg_cgroup_link objects on link chains from
+ * cgroups referenced from this css_set. Protected by
+ * css_set_lock
+ */
+ struct list_head cg_links;
+
+ /*
+ * Set of subsystem states, one for each subsystem. This array
+ * is immutable after creation apart from the init_css_set
+ * during subsystem registration (at boot time).
+ */
+ struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+
+};
+
+/* struct cftype:
+ *
+ * The files in the cgroup filesystem mostly have a very simple read/write
+ * handling, some common function will take care of it. Nevertheless some cases
+ * (read tasks) are special and therefore I define this structure for every
+ * kind of file.
+ *
+ *
+ * When reading/writing to a file:
+ * - the cgroup to use in file->f_dentry->d_parent->d_fsdata
+ * - the 'cftype' of the file is file->f_dentry->d_fsdata
+ */
+
+#define MAX_CFTYPE_NAME 64
+struct cftype {
+ /* By convention, the name should begin with the name of the
+ * subsystem, followed by a period */
+ char name[MAX_CFTYPE_NAME];
+ int private;
+ int (*open) (struct inode *inode, struct file *file);
+ ssize_t (*read) (struct cgroup *cont, struct cftype *cft,
+ struct file *file,
+ char __user *buf, size_t nbytes, loff_t *ppos);
+ /*
+ * read_uint() is a shortcut for the common case of returning a
+ * single integer. Use it in place of read()
+ */
+ u64 (*read_uint) (struct cgroup *cont, struct cftype *cft);
+ ssize_t (*write) (struct cgroup *cont, struct cftype *cft,
+ struct file *file,
+ const char __user *buf, size_t nbytes, loff_t *ppos);
+
+ /*
+ * write_uint() is a shortcut for the common case of accepting
+ * a single integer (as parsed by simple_strtoull) from
+ * userspace. Use in place of write(); return 0 or error.
+ */
+ int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val);
+
+ int (*release) (struct inode *inode, struct file *file);
+};
+
+/* Add a new file to the given cgroup directory. Should only be
+ * called by subsystems from within a populate() method */
+int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys,
+ const struct cftype *cft);
+
+/* Add a set of new files to the given cgroup directory. Should
+ * only be called by subsystems from within a populate() method */
+int cgroup_add_files(struct cgroup *cont,
+ struct cgroup_subsys *subsys,
+ const struct cftype cft[],
+ int count);
+
+int cgroup_is_removed(const struct cgroup *cont);
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_task_count(const struct cgroup *cont);
+
+/* Return true if the cgroup is a descendant of the current cgroup */
+int cgroup_is_descendant(const struct cgroup *cont);
+
+/* Control Group subsystem type. See Documentation/cgroups.txt for details */
+
+struct cgroup_subsys {
+ struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss,
+ struct cgroup *cont);
+ void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont);
+ int (*can_attach)(struct cgroup_subsys *ss,
+ struct cgroup *cont, struct task_struct *tsk);
+ void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont,
+ struct cgroup *old_cont, struct task_struct *tsk);
+ void (*fork)(struct cgroup_subsys *ss, struct task_struct *task);
+ void (*exit)(struct cgroup_subsys *ss, struct task_struct *task);
+ int (*populate)(struct cgroup_subsys *ss,
+ struct cgroup *cont);
+ void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont);
+ void (*bind)(struct cgroup_subsys *ss, struct cgroup *root);
+ int subsys_id;
+ int active;
+ int early_init;
+#define MAX_CGROUP_TYPE_NAMELEN 32
+ const char *name;
+
+ /* Protected by RCU */
+ struct cgroupfs_root *root;
+
+ struct list_head sibling;
+
+ void *private;
+};
+
+#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys;
+#include <linux/cgroup_subsys.h>
+#undef SUBSYS
+
+static inline struct cgroup_subsys_state *cgroup_subsys_state(
+ struct cgroup *cont, int subsys_id)
+{
+ return cont->subsys[subsys_id];
+}
+
+static inline struct cgroup_subsys_state *task_subsys_state(
+ struct task_struct *task, int subsys_id)
+{
+ return rcu_dereference(task->cgroups->subsys[subsys_id]);
+}
+
+static inline struct cgroup* task_cgroup(struct task_struct *task,
+ int subsys_id)
+{
+ return task_subsys_state(task, subsys_id)->cgroup;
+}
+
+int cgroup_path(const struct cgroup *cont, char *buf, int buflen);
+
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss);
+
+/* A cgroup_iter should be treated as an opaque object */
+struct cgroup_iter {
+ struct list_head *cg_link;
+ struct list_head *task;
+};
+
+/* To iterate across the tasks in a cgroup:
+ *
+ * 1) call cgroup_iter_start to intialize an iterator
+ *
+ * 2) call cgroup_iter_next() to retrieve member tasks until it
+ * returns NULL or until you want to end the iteration
+ *
+ * 3) call cgroup_iter_end() to destroy the iterator.
+ */
+void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it);
+struct task_struct *cgroup_iter_next(struct cgroup *cont,
+ struct cgroup_iter *it);
+void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it);
+
+#else /* !CONFIG_CGROUPS */
+
+static inline int cgroup_init_early(void) { return 0; }
+static inline int cgroup_init(void) { return 0; }
+static inline void cgroup_init_smp(void) {}
+static inline void cgroup_fork(struct task_struct *p) {}
+static inline void cgroup_fork_callbacks(struct task_struct *p) {}
+static inline void cgroup_post_fork(struct task_struct *p) {}
+static inline void cgroup_exit(struct task_struct *p, int callbacks) {}
+
+static inline void cgroup_lock(void) {}
+static inline void cgroup_unlock(void) {}
+static inline int cgroupstats_build(struct cgroupstats *stats,
+ struct dentry *dentry)
+{
+ return -EINVAL;
+}
+
+#endif /* !CONFIG_CGROUPS */
+
+#endif /* _LINUX_CGROUP_H */
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
new file mode 100644
index 00000000000..0b9bfbde816
--- /dev/null
+++ b/include/linux/cgroup_subsys.h
@@ -0,0 +1,38 @@
+/* Add subsystem definitions of the form SUBSYS(<name>) in this
+ * file. Surround each one by a line of comment markers so that
+ * patches don't collide
+ */
+
+/* */
+
+/* */
+
+#ifdef CONFIG_CPUSETS
+SUBSYS(cpuset)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_CPUACCT
+SUBSYS(cpuacct)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_DEBUG
+SUBSYS(debug)
+#endif
+
+/* */
+
+#ifdef CONFIG_CGROUP_NS
+SUBSYS(ns)
+#endif
+
+/* */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+SUBSYS(cpu_cgroup)
+#endif
+
+/* */
diff --git a/include/linux/cgroupstats.h b/include/linux/cgroupstats.h
new file mode 100644
index 00000000000..4f53abf6855
--- /dev/null
+++ b/include/linux/cgroupstats.h
@@ -0,0 +1,70 @@
+/* cgroupstats.h - exporting per-cgroup statistics
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Balbir Singh <balbir@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _LINUX_CGROUPSTATS_H
+#define _LINUX_CGROUPSTATS_H
+
+#include <linux/taskstats.h>
+
+/*
+ * Data shared between user space and kernel space on a per cgroup
+ * basis. This data is shared using taskstats.
+ *
+ * Most of these states are derived by looking at the task->state value
+ * For the nr_io_wait state, a flag in the delay accounting structure
+ * indicates that the task is waiting on IO
+ *
+ * Each member is aligned to a 8 byte boundary.
+ */
+struct cgroupstats {
+ __u64 nr_sleeping; /* Number of tasks sleeping */
+ __u64 nr_running; /* Number of tasks running */
+ __u64 nr_stopped; /* Number of tasks in stopped state */
+ __u64 nr_uninterruptible; /* Number of tasks in uninterruptible */
+ /* state */
+ __u64 nr_io_wait; /* Number of tasks waiting on IO */
+};
+
+/*
+ * Commands sent from userspace
+ * Not versioned. New commands should only be inserted at the enum's end
+ * prior to __CGROUPSTATS_CMD_MAX
+ */
+
+enum {
+ CGROUPSTATS_CMD_UNSPEC = __TASKSTATS_CMD_MAX, /* Reserved */
+ CGROUPSTATS_CMD_GET, /* user->kernel request/get-response */
+ CGROUPSTATS_CMD_NEW, /* kernel->user event */
+ __CGROUPSTATS_CMD_MAX,
+};
+
+#define CGROUPSTATS_CMD_MAX (__CGROUPSTATS_CMD_MAX - 1)
+
+enum {
+ CGROUPSTATS_TYPE_UNSPEC = 0, /* Reserved */
+ CGROUPSTATS_TYPE_CGROUP_STATS, /* contains name + stats */
+ __CGROUPSTATS_TYPE_MAX,
+};
+
+#define CGROUPSTATS_TYPE_MAX (__CGROUPSTATS_TYPE_MAX - 1)
+
+enum {
+ CGROUPSTATS_CMD_ATTR_UNSPEC = 0,
+ CGROUPSTATS_CMD_ATTR_FD,
+ __CGROUPSTATS_CMD_ATTR_MAX,
+};
+
+#define CGROUPSTATS_CMD_ATTR_MAX (__CGROUPSTATS_CMD_ATTR_MAX - 1)
+
+#endif /* _LINUX_CGROUPSTATS_H */
diff --git a/include/linux/cpu_acct.h b/include/linux/cpu_acct.h
new file mode 100644
index 00000000000..6b5fd8a66c8
--- /dev/null
+++ b/include/linux/cpu_acct.h
@@ -0,0 +1,14 @@
+
+#ifndef _LINUX_CPU_ACCT_H
+#define _LINUX_CPU_ACCT_H
+
+#include <linux/cgroup.h>
+#include <asm/cputime.h>
+
+#ifdef CONFIG_CGROUP_CPUACCT
+extern void cpuacct_charge(struct task_struct *, cputime_t cputime);
+#else
+static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {}
+#endif
+
+#endif
diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
new file mode 100644
index 00000000000..16a51546db4
--- /dev/null
+++ b/include/linux/cpuidle.h
@@ -0,0 +1,180 @@
+/*
+ * cpuidle.h - a generic framework for CPU idle power management
+ *
+ * (C) 2007 Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+ * Shaohua Li <shaohua.li@intel.com>
+ * Adam Belay <abelay@novell.com>
+ *
+ * This code is licenced under the GPL.
+ */
+
+#ifndef _LINUX_CPUIDLE_H
+#define _LINUX_CPUIDLE_H
+
+#include <linux/percpu.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/kobject.h>
+#include <linux/completion.h>
+
+#define CPUIDLE_STATE_MAX 8
+#define CPUIDLE_NAME_LEN 16
+
+struct cpuidle_device;
+
+
+/****************************
+ * CPUIDLE DEVICE INTERFACE *
+ ****************************/
+
+struct cpuidle_state {
+ char name[CPUIDLE_NAME_LEN];
+ void *driver_data;
+
+ unsigned int flags;
+ unsigned int exit_latency; /* in US */
+ unsigned int power_usage; /* in mW */
+ unsigned int target_residency; /* in US */
+
+ unsigned int usage;
+ unsigned int time; /* in US */
+
+ int (*enter) (struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+};
+
+/* Idle State Flags */
+#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */
+#define CPUIDLE_FLAG_CHECK_BM (0x02) /* BM activity will exit state */
+#define CPUIDLE_FLAG_SHALLOW (0x10) /* low latency, minimal savings */
+#define CPUIDLE_FLAG_BALANCED (0x20) /* medium latency, moderate savings */
+#define CPUIDLE_FLAG_DEEP (0x40) /* high latency, large savings */
+
+#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000)
+
+/**
+ * cpuidle_get_statedata - retrieves private driver state data
+ * @state: the state
+ */
+static inline void * cpuidle_get_statedata(struct cpuidle_state *state)
+{
+ return state->driver_data;
+}
+
+/**
+ * cpuidle_set_statedata - stores private driver state data
+ * @state: the state
+ * @data: the private data
+ */
+static inline void
+cpuidle_set_statedata(struct cpuidle_state *state, void *data)
+{
+ state->driver_data = data;
+}
+
+struct cpuidle_state_kobj {
+ struct cpuidle_state *state;
+ struct completion kobj_unregister;
+ struct kobject kobj;
+};
+
+struct cpuidle_device {
+ int enabled:1;
+ unsigned int cpu;
+
+ int last_residency;
+ int state_count;
+ struct cpuidle_state states[CPUIDLE_STATE_MAX];
+ struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX];
+ struct cpuidle_state *last_state;
+
+ struct list_head device_list;
+ struct kobject kobj;
+ struct completion kobj_unregister;
+ void *governor_data;
+};
+
+DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
+
+/**
+ * cpuidle_get_last_residency - retrieves the last state's residency time
+ * @dev: the target CPU
+ *
+ * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set
+ */
+static inline int cpuidle_get_last_residency(struct cpuidle_device *dev)
+{
+ return dev->last_residency;
+}
+
+
+/****************************
+ * CPUIDLE DRIVER INTERFACE *
+ ****************************/
+
+struct cpuidle_driver {
+ char name[CPUIDLE_NAME_LEN];
+ struct module *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_driver(struct cpuidle_driver *drv);
+extern void cpuidle_unregister_driver(struct cpuidle_driver *drv);
+extern int cpuidle_register_device(struct cpuidle_device *dev);
+extern void cpuidle_unregister_device(struct cpuidle_device *dev);
+
+extern void cpuidle_pause_and_lock(void);
+extern void cpuidle_resume_and_unlock(void);
+extern int cpuidle_enable_device(struct cpuidle_device *dev);
+extern void cpuidle_disable_device(struct cpuidle_device *dev);
+
+#else
+
+static inline int cpuidle_register_driver(struct cpuidle_driver *drv)
+{return 0;}
+static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { }
+static inline int cpuidle_register_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { }
+
+static inline void cpuidle_pause_and_lock(void) { }
+static inline void cpuidle_resume_and_unlock(void) { }
+static inline int cpuidle_enable_device(struct cpuidle_device *dev)
+{return 0;}
+static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
+
+#endif
+
+/******************************
+ * CPUIDLE GOVERNOR INTERFACE *
+ ******************************/
+
+struct cpuidle_governor {
+ char name[CPUIDLE_NAME_LEN];
+ struct list_head governor_list;
+ unsigned int rating;
+
+ int (*enable) (struct cpuidle_device *dev);
+ void (*disable) (struct cpuidle_device *dev);
+
+ int (*select) (struct cpuidle_device *dev);
+ void (*reflect) (struct cpuidle_device *dev);
+
+ struct module *owner;
+};
+
+#ifdef CONFIG_CPU_IDLE
+
+extern int cpuidle_register_governor(struct cpuidle_governor *gov);
+extern void cpuidle_unregister_governor(struct cpuidle_governor *gov);
+
+#else
+
+static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
+{return 0;}
+static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { }
+
+#endif
+
+#endif /* _LINUX_CPUIDLE_H */
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index ea44d2e768a..ecae585ec3d 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -11,6 +11,7 @@
#include <linux/sched.h>
#include <linux/cpumask.h>
#include <linux/nodemask.h>
+#include <linux/cgroup.h>
#ifdef CONFIG_CPUSETS
@@ -19,9 +20,8 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */
extern int cpuset_init_early(void);
extern int cpuset_init(void);
extern void cpuset_init_smp(void);
-extern void cpuset_fork(struct task_struct *p);
-extern void cpuset_exit(struct task_struct *p);
extern cpumask_t cpuset_cpus_allowed(struct task_struct *p);
+extern cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p);
extern nodemask_t cpuset_mems_allowed(struct task_struct *p);
#define cpuset_current_mems_allowed (current->mems_allowed)
void cpuset_init_current_mems_allowed(void);
@@ -76,18 +76,22 @@ static inline int cpuset_do_slab_mem_spread(void)
extern void cpuset_track_online_nodes(void);
+extern int current_cpuset_is_being_rebound(void);
+
#else /* !CONFIG_CPUSETS */
static inline int cpuset_init_early(void) { return 0; }
static inline int cpuset_init(void) { return 0; }
static inline void cpuset_init_smp(void) {}
-static inline void cpuset_fork(struct task_struct *p) {}
-static inline void cpuset_exit(struct task_struct *p) {}
static inline cpumask_t cpuset_cpus_allowed(struct task_struct *p)
{
return cpu_possible_map;
}
+static inline cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p)
+{
+ return cpu_possible_map;
+}
static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
{
@@ -148,6 +152,11 @@ static inline int cpuset_do_slab_mem_spread(void)
static inline void cpuset_track_online_nodes(void) {}
+static inline int current_cpuset_is_being_rebound(void)
+{
+ return 0;
+}
+
#endif /* !CONFIG_CPUSETS */
#endif /* _LINUX_CPUSET_H */
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index fc32694287e..f3110ebe894 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -6,7 +6,7 @@
* Copyright (c) 2005 Herbert Xu <herbert@gondor.apana.org.au>
*
* Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
- * and Nettle, by Niels Mller.
+ * and Nettle, by Niels Möller.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index aab53df4faf..c2c153f97e8 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -178,6 +178,7 @@ d_iput: no no no yes
#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
extern spinlock_t dcache_lock;
+extern seqlock_t rename_lock;
/**
* d_drop - drop a dentry
diff --git a/include/linux/delayacct.h b/include/linux/delayacct.h
index 55d1ca5e60f..ab94bc08355 100644
--- a/include/linux/delayacct.h
+++ b/include/linux/delayacct.h
@@ -26,6 +26,7 @@
* Used to set current->delays->flags
*/
#define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */
+#define DELAYACCT_PF_BLKIO 0x00000002 /* I am waiting on IO */
#ifdef CONFIG_TASK_DELAY_ACCT
@@ -39,6 +40,14 @@ extern void __delayacct_blkio_end(void);
extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *);
extern __u64 __delayacct_blkio_ticks(struct task_struct *);
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{
+ if (p->delays)
+ return (p->delays->flags & DELAYACCT_PF_BLKIO);
+ else
+ return 0;
+}
+
static inline void delayacct_set_flag(int flag)
{
if (current->delays)
@@ -71,6 +80,7 @@ static inline void delayacct_tsk_free(struct task_struct *tsk)
static inline void delayacct_blkio_start(void)
{
+ delayacct_set_flag(DELAYACCT_PF_BLKIO);
if (current->delays)
__delayacct_blkio_start();
}
@@ -79,6 +89,7 @@ static inline void delayacct_blkio_end(void)
{
if (current->delays)
__delayacct_blkio_end();
+ delayacct_clear_flag(DELAYACCT_PF_BLKIO);
}
static inline int delayacct_add_tsk(struct taskstats *d,
@@ -116,6 +127,8 @@ static inline int delayacct_add_tsk(struct taskstats *d,
{ return 0; }
static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk)
{ return 0; }
+static inline int delayacct_is_task_waiting_on_io(struct task_struct *p)
+{ return 0; }
#endif /* CONFIG_TASK_DELAY_ACCT */
#endif
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 499f5373e21..37c66d1254b 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -183,11 +183,14 @@ int dm_resume(struct mapped_device *md);
*/
uint32_t dm_get_event_nr(struct mapped_device *md);
int dm_wait_event(struct mapped_device *md, int event_nr);
+uint32_t dm_next_uevent_seq(struct mapped_device *md);
+void dm_uevent_add(struct mapped_device *md, struct list_head *elist);
/*
* Info functions.
*/
const char *dm_device_name(struct mapped_device *md);
+int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid);
struct gendisk *dm_disk(struct mapped_device *md);
int dm_suspended(struct mapped_device *md);
int dm_noflush_suspending(struct dm_target *ti);
diff --git a/include/linux/dm-ioctl.h b/include/linux/dm-ioctl.h
index b9348610782..523281c5b7f 100644
--- a/include/linux/dm-ioctl.h
+++ b/include/linux/dm-ioctl.h
@@ -131,6 +131,7 @@ struct dm_ioctl {
char name[DM_NAME_LEN]; /* device name */
char uuid[DM_UUID_LEN]; /* unique identifier for
* the block device */
+ char data[7]; /* padding or data */
};
/*
@@ -285,9 +286,9 @@ typedef char ioctl_struct[308];
#define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 11
+#define DM_VERSION_MINOR 12
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2006-10-12)"
+#define DM_VERSION_EXTRA "-ioctl (2007-10-02)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
new file mode 100644
index 00000000000..ffb6439cb5e
--- /dev/null
+++ b/include/linux/dmar.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2006, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) Ashok Raj <ashok.raj@intel.com>
+ * Copyright (C) Shaohua Li <shaohua.li@intel.com>
+ */
+
+#ifndef __DMAR_H__
+#define __DMAR_H__
+
+#include <linux/acpi.h>
+#include <linux/types.h>
+#include <linux/msi.h>
+
+#ifdef CONFIG_DMAR
+struct intel_iommu;
+
+extern char *dmar_get_fault_reason(u8 fault_reason);
+
+/* Can't use the common MSI interrupt functions
+ * since DMAR is not a pci device
+ */
+extern void dmar_msi_unmask(unsigned int irq);
+extern void dmar_msi_mask(unsigned int irq);
+extern void dmar_msi_read(int irq, struct msi_msg *msg);
+extern void dmar_msi_write(int irq, struct msi_msg *msg);
+extern int dmar_set_interrupt(struct intel_iommu *iommu);
+extern int arch_setup_dmar_msi(unsigned int irq);
+
+/* Intel IOMMU detection and initialization functions */
+extern void detect_intel_iommu(void);
+extern int intel_iommu_init(void);
+
+extern int dmar_table_init(void);
+extern int early_dmar_detect(void);
+
+extern struct list_head dmar_drhd_units;
+extern struct list_head dmar_rmrr_units;
+
+struct dmar_drhd_unit {
+ struct list_head list; /* list of drhd units */
+ u64 reg_base_addr; /* register base address*/
+ struct pci_dev **devices; /* target device array */
+ int devices_cnt; /* target device count */
+ u8 ignored:1; /* ignore drhd */
+ u8 include_all:1;
+ struct intel_iommu *iommu;
+};
+
+struct dmar_rmrr_unit {
+ struct list_head list; /* list of rmrr units */
+ u64 base_address; /* reserved base address*/
+ u64 end_address; /* reserved end address */
+ struct pci_dev **devices; /* target devices */
+ int devices_cnt; /* target device count */
+};
+
+#define for_each_drhd_unit(drhd) \
+ list_for_each_entry(drhd, &dmar_drhd_units, list)
+#define for_each_rmrr_units(rmrr) \
+ list_for_each_entry(rmrr, &dmar_rmrr_units, list)
+#else
+static inline void detect_intel_iommu(void)
+{
+ return;
+}
+static inline int intel_iommu_init(void)
+{
+ return -ENODEV;
+}
+
+#endif /* !CONFIG_DMAR */
+#endif /* __DMAR_H__ */
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 0b9579a4cd4..14813b59580 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -298,7 +298,7 @@ extern int efi_mem_attribute_range (unsigned long phys_addr, unsigned long size,
u64 attr);
extern int __init efi_uart_console_only (void);
extern void efi_initialize_iomem_resources(struct resource *code_resource,
- struct resource *data_resource);
+ struct resource *data_resource, struct resource *bss_resource);
extern unsigned long efi_get_time(void);
extern int efi_set_rtc_mmss(unsigned long nowtime);
extern int is_available_memory(efi_memory_desc_t * md);
diff --git a/include/linux/efs_fs.h b/include/linux/efs_fs.h
index 16cb25cbf7c..dd57fe523e9 100644
--- a/include/linux/efs_fs.h
+++ b/include/linux/efs_fs.h
@@ -35,6 +35,7 @@ static inline struct efs_sb_info *SUPER_INFO(struct super_block *sb)
}
struct statfs;
+struct fid;
extern const struct inode_operations efs_dir_inode_operations;
extern const struct file_operations efs_dir_operations;
@@ -45,7 +46,10 @@ extern efs_block_t efs_map_block(struct inode *, efs_block_t);
extern int efs_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern struct dentry *efs_lookup(struct inode *, struct dentry *, struct nameidata *);
-extern struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp);
+extern struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+extern struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
extern struct dentry *efs_get_parent(struct dentry *);
extern int efs_bmap(struct inode *, int);
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index 8872fe8392d..51d21413881 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -4,9 +4,48 @@
#include <linux/types.h>
struct dentry;
+struct inode;
struct super_block;
struct vfsmount;
+/*
+ * The fileid_type identifies how the file within the filesystem is encoded.
+ * In theory this is freely set and parsed by the filesystem, but we try to
+ * stick to conventions so we can share some generic code and don't confuse
+ * sniffers like ethereal/wireshark.
+ *
+ * The filesystem must not use the value '0' or '0xff'.
+ */
+enum fid_type {
+ /*
+ * The root, or export point, of the filesystem.
+ * (Never actually passed down to the filesystem.
+ */
+ FILEID_ROOT = 0,
+
+ /*
+ * 32bit inode number, 32 bit generation number.
+ */
+ FILEID_INO32_GEN = 1,
+
+ /*
+ * 32bit inode number, 32 bit generation number,
+ * 32 bit parent directory inode number.
+ */
+ FILEID_INO32_GEN_PARENT = 2,
+};
+
+struct fid {
+ union {
+ struct {
+ u32 ino;
+ u32 gen;
+ u32 parent_ino;
+ u32 parent_gen;
+ } i32;
+ __u32 raw[6];
+ };
+};
/**
* struct export_operations - for nfsd to communicate with file systems
@@ -15,43 +54,9 @@ struct vfsmount;
* @get_name: find the name for a given inode in a given directory
* @get_parent: find the parent of a given directory
* @get_dentry: find a dentry for the inode given a file handle sub-fragment
- * @find_exported_dentry:
- * set by the exporting module to a standard helper function.
- *
- * Description:
- * The export_operations structure provides a means for nfsd to communicate
- * with a particular exported file system - particularly enabling nfsd and
- * the filesystem to co-operate when dealing with file handles.
- *
- * export_operations contains two basic operation for dealing with file
- * handles, decode_fh() and encode_fh(), and allows for some other
- * operations to be defined which standard helper routines use to get
- * specific information from the filesystem.
- *
- * nfsd encodes information use to determine which filesystem a filehandle
- * applies to in the initial part of the file handle. The remainder, termed
- * a file handle fragment, is controlled completely by the filesystem. The
- * standard helper routines assume that this fragment will contain one or
- * two sub-fragments, one which identifies the file, and one which may be
- * used to identify the (a) directory containing the file.
*
- * In some situations, nfsd needs to get a dentry which is connected into a
- * specific part of the file tree. To allow for this, it passes the
- * function acceptable() together with a @context which can be used to see
- * if the dentry is acceptable. As there can be multiple dentrys for a
- * given file, the filesystem should check each one for acceptability before
- * looking for the next. As soon as an acceptable one is found, it should
- * be returned.
- *
- * decode_fh:
- * @decode_fh is given a &struct super_block (@sb), a file handle fragment
- * (@fh, @fh_len) and an acceptability testing function (@acceptable,
- * @context). It should return a &struct dentry which refers to the same
- * file that the file handle fragment refers to, and which passes the
- * acceptability test. If it cannot, it should return a %NULL pointer if
- * the file was found but no acceptable &dentries were available, or a
- * %ERR_PTR error code indicating why it couldn't be found (e.g. %ENOENT or
- * %ENOMEM).
+ * See Documentation/filesystems/Exporting for details on how to use
+ * this interface correctly.
*
* encode_fh:
* @encode_fh should store in the file handle fragment @fh (using at most
@@ -63,6 +68,21 @@ struct vfsmount;
* the filehandle fragment. encode_fh() should return the number of bytes
* stored or a negative error code such as %-ENOSPC
*
+ * fh_to_dentry:
+ * @fh_to_dentry is given a &struct super_block (@sb) and a file handle
+ * fragment (@fh, @fh_len). It should return a &struct dentry which refers
+ * to the same file that the file handle fragment refers to. If it cannot,
+ * it should return a %NULL pointer if the file was found but no acceptable
+ * &dentries were available, or an %ERR_PTR error code indicating why it
+ * couldn't be found (e.g. %ENOENT or %ENOMEM). Any suitable dentry can be
+ * returned including, if necessary, a new dentry created with d_alloc_root.
+ * The caller can then find any other extant dentries by following the
+ * d_alias links.
+ *
+ * fh_to_parent:
+ * Same as @fh_to_dentry, except that it returns a pointer to the parent
+ * dentry if it was encoded into the filehandle fragment by @encode_fh.
+ *
* get_name:
* @get_name should find a name for the given @child in the given @parent
* directory. The name should be stored in the @name (with the
@@ -75,52 +95,37 @@ struct vfsmount;
* is also a directory. In the event that it cannot be found, or storage
* space cannot be allocated, a %ERR_PTR should be returned.
*
- * get_dentry:
- * Given a &super_block (@sb) and a pointer to a file-system specific inode
- * identifier, possibly an inode number, (@inump) get_dentry() should find
- * the identified inode and return a dentry for that inode. Any suitable
- * dentry can be returned including, if necessary, a new dentry created with
- * d_alloc_root. The caller can then find any other extant dentrys by
- * following the d_alias links. If a new dentry was created using
- * d_alloc_root, DCACHE_NFSD_DISCONNECTED should be set, and the dentry
- * should be d_rehash()ed.
- *
- * If the inode cannot be found, either a %NULL pointer or an %ERR_PTR code
- * can be returned. The @inump will be whatever was passed to
- * nfsd_find_fh_dentry() in either the @obj or @parent parameters.
- *
* Locking rules:
* get_parent is called with child->d_inode->i_mutex down
* get_name is not (which is possibly inconsistent)
*/
struct export_operations {
- struct dentry *(*decode_fh)(struct super_block *sb, __u32 *fh,
- int fh_len, int fh_type,
- int (*acceptable)(void *context, struct dentry *de),
- void *context);
int (*encode_fh)(struct dentry *de, __u32 *fh, int *max_len,
int connectable);
+ struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+ struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
int (*get_name)(struct dentry *parent, char *name,
struct dentry *child);
struct dentry * (*get_parent)(struct dentry *child);
- struct dentry * (*get_dentry)(struct super_block *sb, void *inump);
-
- /* This is set by the exporting module to a standard helper */
- struct dentry * (*find_exported_dentry)(
- struct super_block *sb, void *obj, void *parent,
- int (*acceptable)(void *context, struct dentry *de),
- void *context);
};
-extern struct dentry *find_exported_dentry(struct super_block *sb, void *obj,
- void *parent, int (*acceptable)(void *context, struct dentry *de),
- void *context);
-
-extern int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
- int connectable);
-extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh,
+extern int exportfs_encode_fh(struct dentry *dentry, struct fid *fid,
+ int *max_len, int connectable);
+extern struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
int fh_len, int fileid_type, int (*acceptable)(void *, struct dentry *),
void *context);
+/*
+ * Generic helpers for filesystems.
+ */
+extern struct dentry *generic_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type,
+ struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+extern struct dentry *generic_fh_to_parent(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type,
+ struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen));
+
#endif /* LINUX_EXPORTFS_H */
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index c77c3bbfe4b..0f6c86c634f 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -561,6 +561,7 @@ enum {
#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
~EXT2_DIR_ROUND)
+#define EXT2_MAX_REC_LEN ((1<<16)-1)
static inline ext2_fsblk_t
ext2_group_first_block_no(struct super_block *sb, unsigned long group_no)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 6a4d170ad9a..b3ec4a496d6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -123,6 +123,7 @@ extern int dir_notify_enable;
#define MS_SLAVE (1<<19) /* change to slave */
#define MS_SHARED (1<<20) /* change to shared */
#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
+#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */
#define MS_ACTIVE (1<<30)
#define MS_NOUSER (1<<31)
@@ -986,7 +987,7 @@ struct super_block {
const struct super_operations *s_op;
struct dquot_operations *dq_op;
struct quotactl_ops *s_qcop;
- struct export_operations *s_export_op;
+ const struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_magic;
struct dentry *s_root;
@@ -1459,7 +1460,8 @@ void unnamed_dev_init(void);
extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);
-extern struct vfsmount *kern_mount(struct file_system_type *);
+extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
+#define kern_mount(type) kern_mount_data(type, NULL)
extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *);
extern void umount_tree(struct vfsmount *, int, struct list_head *);
@@ -1468,6 +1470,8 @@ extern long do_mount(char *, char *, char *, unsigned long, void *);
extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
struct vfsmount *);
+extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
+extern void drop_collected_mounts(struct vfsmount *);
extern int vfs_statfs(struct dentry *, struct kstatfs *);
@@ -1534,7 +1538,7 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
struct file *filp);
-extern long do_sys_open(int fdf, const char __user *filename, int flags,
+extern long do_sys_open(int dfd, const char __user *filename, int flags,
int mode);
extern struct file *filp_open(const char *, int, int);
extern struct file * dentry_open(struct dentry *, struct vfsmount *, int);
@@ -1922,6 +1926,8 @@ extern int vfs_fstat(unsigned int, struct kstat *);
extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long);
+extern void get_filesystem(struct file_system_type *fs);
+extern void put_filesystem(struct file_system_type *fs);
extern struct file_system_type *get_fs_type(const char *name);
extern struct super_block *get_super(struct block_device *);
extern struct super_block *user_get_super(dev_t);
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index dfc4e4f68da..2bd31fa623b 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -41,8 +41,9 @@ static inline void fsnotify_d_move(struct dentry *entry)
*/
static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
const char *old_name, const char *new_name,
- int isdir, struct inode *target, struct inode *source)
+ int isdir, struct inode *target, struct dentry *moved)
{
+ struct inode *source = moved->d_inode;
u32 cookie = inotify_get_cookie();
if (old_dir == new_dir)
@@ -67,7 +68,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
if (source) {
inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL);
}
- audit_inode_child(new_name, source, new_dir);
+ audit_inode_child(new_name, moved, new_dir);
}
/*
@@ -98,7 +99,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name,
dentry->d_inode);
- audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+ audit_inode_child(dentry->d_name.name, dentry, inode);
}
/*
@@ -109,7 +110,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
inode_dir_notify(inode, DN_CREATE);
inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0,
dentry->d_name.name, dentry->d_inode);
- audit_inode_child(dentry->d_name.name, dentry->d_inode, inode);
+ audit_inode_child(dentry->d_name.name, dentry, inode);
}
/*
diff --git a/include/linux/hid.h b/include/linux/hid.h
index edb8024d744..6e35b92b1d2 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -469,8 +469,8 @@ struct hid_device { /* device report descriptor */
/* handler for raw output data, used by hidraw */
int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
- unsigned long pb_pressed_fn[NBITS(KEY_MAX)];
- unsigned long pb_pressed_numlock[NBITS(KEY_MAX)];
+ unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
+ unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)];
#endif
};
diff --git a/include/linux/i8042.h b/include/linux/i8042.h
new file mode 100644
index 00000000000..7907a72403e
--- /dev/null
+++ b/include/linux/i8042.h
@@ -0,0 +1,35 @@
+#ifndef _LINUX_I8042_H
+#define _LINUX_I8042_H
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+
+
+/*
+ * Standard commands.
+ */
+
+#define I8042_CMD_CTL_RCTR 0x0120
+#define I8042_CMD_CTL_WCTR 0x1060
+#define I8042_CMD_CTL_TEST 0x01aa
+
+#define I8042_CMD_KBD_DISABLE 0x00ad
+#define I8042_CMD_KBD_ENABLE 0x00ae
+#define I8042_CMD_KBD_TEST 0x01ab
+#define I8042_CMD_KBD_LOOP 0x11d2
+
+#define I8042_CMD_AUX_DISABLE 0x00a7
+#define I8042_CMD_AUX_ENABLE 0x00a8
+#define I8042_CMD_AUX_TEST 0x01a9
+#define I8042_CMD_AUX_SEND 0x10d4
+#define I8042_CMD_AUX_LOOP 0x11d3
+
+#define I8042_CMD_MUX_PFX 0x0090
+#define I8042_CMD_MUX_SEND 0x1090
+
+int i8042_command(unsigned char *param, int command);
+
+#endif
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 19db0a4ae44..4ed4777bba6 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -192,22 +192,20 @@ typedef unsigned char byte; /* used everywhere */
struct hwif_s;
typedef int (ide_ack_intr_t)(struct hwif_s *);
-#ifndef NO_DMA
-#define NO_DMA 255
-#endif
-
/*
* hwif_chipset_t is used to keep track of the specific hardware
* chipset used by each IDE interface, if known.
*/
-typedef enum { ide_unknown, ide_generic, ide_pci,
+enum { ide_unknown, ide_generic, ide_pci,
ide_cmd640, ide_dtc2278, ide_ali14xx,
ide_qd65xx, ide_umc8672, ide_ht6560b,
ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100, ide_acorn,
ide_au1xxx, ide_forced
-} hwif_chipset_t;
+};
+
+typedef u8 hwif_chipset_t;
/*
* Structure to hold all information about the location of this port
@@ -215,22 +213,16 @@ typedef enum { ide_unknown, ide_generic, ide_pci,
typedef struct hw_regs_s {
unsigned long io_ports[IDE_NR_PORTS]; /* task file registers */
int irq; /* our irq number */
- int dma; /* our dma entry */
ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
hwif_chipset_t chipset;
struct device *dev;
} hw_regs_t;
-/*
- * Register new hardware with ide
- */
-int ide_register_hw(hw_regs_t *, int, struct hwif_s **);
-int ide_register_hw_with_fixup(hw_regs_t *, int, struct hwif_s **,
- void (*)(struct hwif_s *));
+struct hwif_s * ide_find_port(unsigned long);
+
+int ide_register_hw(hw_regs_t *, void (*)(struct hwif_s *), int,
+ struct hwif_s **);
-/*
- * Set up hw_regs_t structure before calling ide_register_hw (optional)
- */
void ide_setup_ports( hw_regs_t *hw,
unsigned long base,
int *offsets,
@@ -268,11 +260,7 @@ static inline void ide_std_init_ports(hw_regs_t *hw,
# define ide_init_default_irq(base) (0)
#endif
-/*
- * ide_init_hwif_ports() is OBSOLETE and will be removed in 2.7 series.
- * New ports shouldn't define IDE_ARCH_OBSOLETE_INIT in <asm/ide.h>.
- */
-#ifdef IDE_ARCH_OBSOLETE_INIT
+#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT
static inline void ide_init_hwif_ports(hw_regs_t *hw,
unsigned long io_addr,
unsigned long ctl_addr,
@@ -302,7 +290,7 @@ static inline void ide_init_hwif_ports(hw_regs_t *hw,
if (io_addr || ctl_addr)
printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__);
}
-#endif /* IDE_ARCH_OBSOLETE_INIT */
+#endif /* CONFIG_IDE_ARCH_OBSOLETE_INIT */
/* Currently only m68k, apus and m8xx need it */
#ifndef IDE_ARCH_ACK_INTR
@@ -363,7 +351,6 @@ typedef union {
* ATA DATA Register Special.
* ATA NSECTOR Count Register().
* ATAPI Byte Count Register.
- * Channel index ordering pairs.
*/
typedef union {
unsigned all :16;
@@ -378,7 +365,7 @@ typedef union {
#error "Please fix <asm/byteorder.h>"
#endif
} b;
-} ata_nsector_t, ata_data_t, atapi_bcount_t, ata_index_t;
+} ata_nsector_t, ata_data_t, atapi_bcount_t;
/*
* ATA-IDE Select Register, aka Device-Head
@@ -657,7 +644,7 @@ typedef struct ide_drive_s {
((1<<ide_pci)|(1<<ide_cmd646)|(1<<ide_ali14xx))
#define IDE_CHIPSET_IS_PCI(c) ((IDE_CHIPSET_PCI_MASK >> (c)) & 1)
-struct ide_pci_device_s;
+struct ide_port_info;
typedef struct hwif_s {
struct hwif_s *next; /* for linked-list in ide_hwgroup_t */
@@ -672,7 +659,6 @@ typedef struct hwif_s {
unsigned long sata_scr[SATA_NR_PORTS];
unsigned long sata_misc[SATA_NR_PORTS];
- hw_regs_t hw; /* Hardware info */
ide_drive_t drives[MAX_DRIVES]; /* drive info */
u8 major; /* our major number */
@@ -681,7 +667,7 @@ typedef struct hwif_s {
u8 straight8; /* Alan's straight 8 check */
u8 bus_state; /* power state of the IDE bus */
- u16 host_flags;
+ u32 host_flags;
u8 pio_mask;
@@ -694,7 +680,9 @@ typedef struct hwif_s {
hwif_chipset_t chipset; /* sub-module for tuning.. */
struct pci_dev *pci_dev; /* for pci chipsets */
- struct ide_pci_device_s *cds; /* chipset device struct */
+ const struct ide_port_info *cds; /* chipset device struct */
+
+ ide_ack_intr_t *ack_intr;
void (*rw_disk)(ide_drive_t *, struct request *);
@@ -725,6 +713,8 @@ typedef struct hwif_s {
u8 (*mdma_filter)(ide_drive_t *);
u8 (*udma_filter)(ide_drive_t *);
+ void (*fixup)(struct hwif_s *);
+
void (*ata_input_data)(ide_drive_t *, void *, u32);
void (*ata_output_data)(ide_drive_t *, void *, u32);
@@ -841,8 +831,6 @@ typedef struct hwgroup_s {
/* for pci chipsets */
struct pci_dev *pci_dev;
- /* chipset device struct */
- struct ide_pci_device_s *cds;
/* current request */
struct request *rq;
@@ -1030,36 +1018,16 @@ extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs);
int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
int uptodate, int nr_sectors);
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and also to start the safety timer.
- */
extern void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
-/*
- * This is used on exit from the driver to designate the next irq handler
- * and start the safety time safely and atomically from the IRQ handler
- * with respect to the command issue (which it also does)
- */
extern void ide_execute_command(ide_drive_t *, task_ioreg_t cmd, ide_handler_t *, unsigned int, ide_expiry_t *);
ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8);
-/*
- * ide_error() takes action based on the error returned by the controller.
- * The caller should return immediately after invoking this.
- *
- * (drive, msg, status)
- */
ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat);
ide_startstop_t __ide_abort(ide_drive_t *, struct request *);
-/*
- * Abort a running command on the controller triggering the abort
- * from a host side, non error situation
- * (drive, msg)
- */
extern ide_startstop_t ide_abort(ide_drive_t *, const char *);
extern void ide_fix_driveid(struct hd_driveid *);
@@ -1075,15 +1043,8 @@ extern void ide_fixstring(u8 *, const int, const int);
int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
-/*
- * Start a reset operation for an IDE interface.
- * The caller should return immediately after invoking this.
- */
extern ide_startstop_t ide_do_reset (ide_drive_t *);
-/*
- * This function is intended to be used prior to invoking ide_do_drive_cmd().
- */
extern void ide_init_drive_cmd (struct request *rq);
/*
@@ -1098,13 +1059,6 @@ typedef enum {
extern int ide_do_drive_cmd(ide_drive_t *, struct request *, ide_action_t);
-/*
- * Clean up after success/failure of an explicit drive cmd.
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_CMD).
- * stat/err are used only when (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASK_MASK).
- *
- * (ide_drive_t *drive, u8 stat, u8 err)
- */
extern void ide_end_drive_cmd(ide_drive_t *, u8, u8);
/*
@@ -1177,10 +1131,6 @@ extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *);
extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout);
-/*
- * ide_stall_queue() can be used by a drive to give excess bandwidth back
- * to the hwgroup by sleeping for timeout jiffies.
- */
extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern int ide_spin_wait_hwgroup(ide_drive_t *);
@@ -1200,8 +1150,8 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o
#define ide_pci_register_driver(d) pci_register_driver(d)
#endif
-void ide_pci_setup_ports(struct pci_dev *, struct ide_pci_device_s *, int, ata_index_t *);
-extern void ide_setup_pci_noise (struct pci_dev *dev, struct ide_pci_device_s *d);
+void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *);
+void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *);
extern void default_hwif_iops(ide_hwif_t *);
extern void default_hwif_mmiops(ide_hwif_t *);
@@ -1261,6 +1211,14 @@ enum {
IDE_HFLAG_SERIALIZE = (1 << 20),
/* use legacy IRQs */
IDE_HFLAG_LEGACY_IRQS = (1 << 21),
+ /* force use of legacy IRQs */
+ IDE_HFLAG_FORCE_LEGACY_IRQS = (1 << 22),
+ /* limit LBA48 requests to 256 sectors */
+ IDE_HFLAG_RQSIZE_256 = (1 << 23),
+ /* use 32-bit I/O ops */
+ IDE_HFLAG_IO_32BIT = (1 << 24),
+ /* unmask IRQs */
+ IDE_HFLAG_UNMASK_IRQS = (1 << 25),
};
#ifdef CONFIG_BLK_DEV_OFFBOARD
@@ -1269,7 +1227,7 @@ enum {
# define IDE_HFLAG_OFF_BOARD 0
#endif
-typedef struct ide_pci_device_s {
+struct ide_port_info {
char *name;
unsigned int (*init_chipset)(struct pci_dev *, const char *);
void (*init_iops)(ide_hwif_t *);
@@ -1277,17 +1235,17 @@ typedef struct ide_pci_device_s {
void (*init_dma)(ide_hwif_t *, unsigned long);
void (*fixup)(ide_hwif_t *);
ide_pci_enablebit_t enablebits[2];
+ hwif_chipset_t chipset;
unsigned int extra;
- struct ide_pci_device_s *next;
u32 host_flags;
u8 pio_mask;
u8 swdma_mask;
u8 mwdma_mask;
u8 udma_mask;
-} ide_pci_device_t;
+};
-extern int ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);
-extern int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, ide_pci_device_t *);
+int ide_setup_pci_device(struct pci_dev *, const struct ide_port_info *);
+int ide_setup_pci_devices(struct pci_dev *, struct pci_dev *, const struct ide_port_info *);
void ide_map_sg(ide_drive_t *, struct request *);
void ide_init_sg_cmd(ide_drive_t *, struct request *);
@@ -1370,8 +1328,7 @@ void ide_unregister_region(struct gendisk *);
void ide_undecoded_slave(ide_hwif_t *);
-int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *));
-extern int probe_hwif_init(ide_hwif_t *);
+int ide_device_add(u8 idx[4]);
static inline void *ide_get_hwifdata (ide_hwif_t * hwif)
{
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d4b2f1c76e1..cae35b6b9ae 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -67,9 +67,6 @@
.posix_timers = LIST_HEAD_INIT(sig.posix_timers), \
.cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
.rlim = INIT_RLIMITS, \
- .pgrp = 0, \
- .tty_old_pgrp = NULL, \
- { .__session = 0}, \
}
extern struct nsproxy init_nsproxy;
@@ -94,15 +91,18 @@ extern struct group_info init_groups;
#define INIT_STRUCT_PID { \
.count = ATOMIC_INIT(1), \
- .nr = 0, \
- /* Don't put this struct pid in pid_hash */ \
- .pid_chain = { .next = NULL, .pprev = NULL }, \
.tasks = { \
{ .first = &init_task.pids[PIDTYPE_PID].node }, \
{ .first = &init_task.pids[PIDTYPE_PGID].node }, \
{ .first = &init_task.pids[PIDTYPE_SID].node }, \
}, \
.rcu = RCU_HEAD_INIT, \
+ .level = 0, \
+ .numbers = { { \
+ .nr = 0, \
+ .ns = &init_pid_ns, \
+ .pid_chain = { .next = NULL, .pprev = NULL }, \
+ }, } \
}
#define INIT_PID_LINK(type) \
diff --git a/include/linux/inotify.h b/include/linux/inotify.h
index d4f48c6402e..742b917e7d1 100644
--- a/include/linux/inotify.h
+++ b/include/linux/inotify.h
@@ -120,6 +120,8 @@ extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *,
u32);
extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
struct inode *, __u32);
+extern __s32 inotify_clone_watch(struct inotify_watch *, struct inotify_watch *);
+extern void inotify_evict_watch(struct inotify_watch *);
extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *);
extern int inotify_rm_wd(struct inotify_handle *, __u32);
extern void inotify_remove_watch_locked(struct inotify_handle *,
diff --git a/include/linux/input.h b/include/linux/input.h
index f30da6fc08e..62268929856 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -98,6 +98,7 @@ struct input_absinfo {
#define EV_PWR 0x16
#define EV_FF_STATUS 0x17
#define EV_MAX 0x1f
+#define EV_CNT (EV_MAX+1)
/*
* Synchronization events.
@@ -567,6 +568,7 @@ struct input_absinfo {
/* We avoid low common keys in module aliases so they don't get huge. */
#define KEY_MIN_INTERESTING KEY_MUTE
#define KEY_MAX 0x1ff
+#define KEY_CNT (KEY_MAX+1)
/*
* Relative axes
@@ -583,6 +585,7 @@ struct input_absinfo {
#define REL_WHEEL 0x08
#define REL_MISC 0x09
#define REL_MAX 0x0f
+#define REL_CNT (REL_MAX+1)
/*
* Absolute axes
@@ -615,6 +618,7 @@ struct input_absinfo {
#define ABS_VOLUME 0x20
#define ABS_MISC 0x28
#define ABS_MAX 0x3f
+#define ABS_CNT (ABS_MAX+1)
/*
* Switch events
@@ -625,6 +629,7 @@ struct input_absinfo {
#define SW_HEADPHONE_INSERT 0x02 /* set = inserted */
#define SW_RADIO 0x03 /* set = radio enabled */
#define SW_MAX 0x0f
+#define SW_CNT (SW_MAX+1)
/*
* Misc events
@@ -636,6 +641,7 @@ struct input_absinfo {
#define MSC_RAW 0x03
#define MSC_SCAN 0x04
#define MSC_MAX 0x07
+#define MSC_CNT (MSC_MAX+1)
/*
* LEDs
@@ -653,6 +659,7 @@ struct input_absinfo {
#define LED_MAIL 0x09
#define LED_CHARGING 0x0a
#define LED_MAX 0x0f
+#define LED_CNT (LED_MAX+1)
/*
* Autorepeat values
@@ -670,6 +677,7 @@ struct input_absinfo {
#define SND_BELL 0x01
#define SND_TONE 0x02
#define SND_MAX 0x07
+#define SND_CNT (SND_MAX+1)
/*
* IDs.
@@ -920,6 +928,7 @@ struct ff_effect {
#define FF_AUTOCENTER 0x61
#define FF_MAX 0x7f
+#define FF_CNT (FF_MAX+1)
#ifdef __KERNEL__
@@ -932,10 +941,6 @@ struct ff_effect {
#include <linux/timer.h>
#include <linux/mod_devicetable.h>
-#define NBITS(x) (((x)/BITS_PER_LONG)+1)
-#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
-#define LONG(x) ((x)/BITS_PER_LONG)
-
/**
* struct input_dev - represents an input device
* @name: name of the device
@@ -1005,28 +1010,30 @@ struct ff_effect {
* @going_away: marks devices that are in a middle of unregistering and
* causes input_open_device*() fail with -ENODEV.
* @dev: driver model's view of this device
+ * @cdev: union for struct device pointer
* @h_list: list of input handles associated with the device. When
* accessing the list dev->mutex must be held
* @node: used to place the device onto input_dev_list
*/
struct input_dev {
-
+ /* private: */
void *private; /* do not use */
+ /* public: */
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
- unsigned long evbit[NBITS(EV_MAX)];
- unsigned long keybit[NBITS(KEY_MAX)];
- unsigned long relbit[NBITS(REL_MAX)];
- unsigned long absbit[NBITS(ABS_MAX)];
- unsigned long mscbit[NBITS(MSC_MAX)];
- unsigned long ledbit[NBITS(LED_MAX)];
- unsigned long sndbit[NBITS(SND_MAX)];
- unsigned long ffbit[NBITS(FF_MAX)];
- unsigned long swbit[NBITS(SW_MAX)];
+ unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
+ unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
+ unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
+ unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
+ unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
+ unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
+ unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
+ unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
+ unsigned long swbit[BITS_TO_LONGS(SW_CNT)];
unsigned int keycodemax;
unsigned int keycodesize;
@@ -1044,10 +1051,10 @@ struct input_dev {
int abs[ABS_MAX + 1];
int rep[REP_MAX + 1];
- unsigned long key[NBITS(KEY_MAX)];
- unsigned long led[NBITS(LED_MAX)];
- unsigned long snd[NBITS(SND_MAX)];
- unsigned long sw[NBITS(SW_MAX)];
+ unsigned long key[BITS_TO_LONGS(KEY_CNT)];
+ unsigned long led[BITS_TO_LONGS(LED_CNT)];
+ unsigned long snd[BITS_TO_LONGS(SND_CNT)];
+ unsigned long sw[BITS_TO_LONGS(SW_CNT)];
int absmax[ABS_MAX + 1];
int absmin[ABS_MAX + 1];
@@ -1291,7 +1298,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
dev->absfuzz[axis] = fuzz;
dev->absflat[axis] = flat;
- dev->absbit[LONG(axis)] |= BIT(axis);
+ dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis);
}
extern struct class input_class;
@@ -1332,7 +1339,7 @@ struct ff_device {
void *private;
- unsigned long ffbit[NBITS(FF_MAX)];
+ unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];
struct mutex mutex;
diff --git a/include/linux/ipc.h b/include/linux/ipc.h
index ee111834091..408696ea518 100644
--- a/include/linux/ipc.h
+++ b/include/linux/ipc.h
@@ -89,6 +89,7 @@ struct kern_ipc_perm
{
spinlock_t lock;
int deleted;
+ int id;
key_t key;
uid_t uid;
gid_t gid;
@@ -110,6 +111,8 @@ struct ipc_namespace {
int msg_ctlmax;
int msg_ctlmnb;
int msg_ctlmni;
+ atomic_t msg_bytes;
+ atomic_t msg_hdrs;
size_t shm_ctlmax;
size_t shm_ctlall;
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index efa292a52e7..56ae438ae51 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -118,7 +118,7 @@ struct ipmi_smi_handlers
/* Enable/disable firmware maintenance mode. Note that this
is *not* the modes defined, this is simply an on/off
setting. The message handler does the mode handling. Note
- that this is called from interupt context, so it cannot
+ that this is called from interrupt context, so it cannot
block. */
void (*set_maintenance_mode)(void *send_info, int enable);
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index a3abf51e488..16e7ed855a1 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -58,7 +58,7 @@
* CONFIG_JBD_DEBUG is on.
*/
#define JBD_EXPENSIVE_CHECKING
-extern int journal_enable_debug;
+extern u8 journal_enable_debug;
#define jbd_debug(n, f, a...) \
do { \
@@ -248,17 +248,7 @@ typedef struct journal_superblock_s
#include <linux/fs.h>
#include <linux/sched.h>
-#define JBD_ASSERTIONS
-#ifdef JBD_ASSERTIONS
-#define J_ASSERT(assert) \
-do { \
- if (!(assert)) { \
- printk (KERN_EMERG \
- "Assertion failure in %s() at %s:%d: \"%s\"\n", \
- __FUNCTION__, __FILE__, __LINE__, # assert); \
- BUG(); \
- } \
-} while (0)
+#define J_ASSERT(assert) BUG_ON(!(assert))
#if defined(CONFIG_BUFFER_DEBUG)
void buffer_assertion_failure(struct buffer_head *bh);
@@ -274,10 +264,6 @@ void buffer_assertion_failure(struct buffer_head *bh);
#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
#endif
-#else
-#define J_ASSERT(assert) do { } while (0)
-#endif /* JBD_ASSERTIONS */
-
#if defined(JBD_PARANOID_IOFAIL)
#define J_EXPECT(expr, why...) J_ASSERT(expr)
#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index ad4b82ce84a..2d9c448d8c5 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -187,6 +187,8 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
extern size_t vmcoreinfo_size;
extern size_t vmcoreinfo_max_size;
+int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
+ unsigned long long *crash_size, unsigned long long *crash_base);
#else /* !CONFIG_KEXEC */
struct pt_regs;
diff --git a/include/linux/keyboard.h b/include/linux/keyboard.h
index 33b5c2e325b..65c2d70853e 100644
--- a/include/linux/keyboard.h
+++ b/include/linux/keyboard.h
@@ -23,10 +23,21 @@
#define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */
#ifdef __KERNEL__
+struct notifier_block;
extern const int NR_TYPES;
extern const int max_vals[];
extern unsigned short *key_maps[MAX_NR_KEYMAPS];
extern unsigned short plain_map[NR_KEYS];
+
+struct keyboard_notifier_param {
+ struct vc_data *vc; /* VC on which the keyboard press was done */
+ int down; /* Pressure of the key? */
+ int shift; /* Current shift mask */
+ unsigned int value; /* keycode, unicode value or keysym */
+};
+
+extern int register_keyboard_notifier(struct notifier_block *nb);
+extern int unregister_keyboard_notifier(struct notifier_block *nb);
#endif
#define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 6c9873f8828..ff203dd0291 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -34,6 +34,12 @@
name:
#endif
+#ifndef WEAK
+#define WEAK(name) \
+ .weak name; \
+ name:
+#endif
+
#define KPROBE_ENTRY(name) \
.pushsection .kprobes.text, "ax"; \
ENTRY(name)
diff --git a/include/linux/list.h b/include/linux/list.h
index b0cf0135fe3..75ce2cb4ff6 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -478,8 +478,7 @@ static inline void list_splice_init_rcu(struct list_head *list,
pos = n, n = pos->next)
/**
- * list_for_each_prev_safe - iterate over a list backwards safe against removal
- of list entry
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index f6279f68a82..4c4d236ded1 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -276,6 +276,14 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name,
(lock)->dep_map.key, sub)
/*
+ * To initialize a lockdep_map statically use this macro.
+ * Note that _name must not be NULL.
+ */
+#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \
+ { .name = (_name), .key = (void *)(_key), }
+
+
+/*
* Acquire a lock.
*
* Values for "read":
diff --git a/include/linux/magic.h b/include/linux/magic.h
index 722d4755060..1fa0c2ce4de 100644
--- a/include/linux/magic.h
+++ b/include/linux/magic.h
@@ -37,6 +37,7 @@
#define SMB_SUPER_MAGIC 0x517B
#define USBDEVICE_SUPER_MAGIC 0x9fa2
+#define CGROUP_SUPER_MAGIC 0x27e0eb
#define FUTEXFS_SUPER_MAGIC 0xBAD1DEA
#define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA
diff --git a/include/linux/marker.h b/include/linux/marker.h
new file mode 100644
index 00000000000..5f36cf946bc
--- /dev/null
+++ b/include/linux/marker.h
@@ -0,0 +1,129 @@
+#ifndef _LINUX_MARKER_H
+#define _LINUX_MARKER_H
+
+/*
+ * Code markup for dynamic and static tracing.
+ *
+ * See Documentation/marker.txt.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+
+struct module;
+struct marker;
+
+/**
+ * marker_probe_func - Type of a marker probe function
+ * @mdata: pointer of type struct marker
+ * @private_data: caller site private data
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Type of marker probe functions. They receive the mdata and need to parse the
+ * format string to recover the variable argument list.
+ */
+typedef void marker_probe_func(const struct marker *mdata,
+ void *private_data, const char *fmt, ...);
+
+struct marker {
+ const char *name; /* Marker name */
+ const char *format; /* Marker format string, describing the
+ * variable argument list.
+ */
+ char state; /* Marker state. */
+ marker_probe_func *call;/* Probe handler function pointer */
+ void *private; /* Private probe data */
+} __attribute__((aligned(8)));
+
+#ifdef CONFIG_MARKERS
+
+/*
+ * Note : the empty asm volatile with read constraint is used here instead of a
+ * "used" attribute to fix a gcc 4.1.x bug.
+ * Make sure the alignment of the structure in the __markers section will
+ * not add unwanted padding between the beginning of the section and the
+ * structure. Force alignment to the same alignment as the section start.
+ */
+#define __trace_mark(name, call_data, format, args...) \
+ do { \
+ static const char __mstrtab_name_##name[] \
+ __attribute__((section("__markers_strings"))) \
+ = #name; \
+ static const char __mstrtab_format_##name[] \
+ __attribute__((section("__markers_strings"))) \
+ = format; \
+ static struct marker __mark_##name \
+ __attribute__((section("__markers"), aligned(8))) = \
+ { __mstrtab_name_##name, __mstrtab_format_##name, \
+ 0, __mark_empty_function, NULL }; \
+ __mark_check_format(format, ## args); \
+ if (unlikely(__mark_##name.state)) { \
+ preempt_disable(); \
+ (*__mark_##name.call) \
+ (&__mark_##name, call_data, \
+ format, ## args); \
+ preempt_enable(); \
+ } \
+ } while (0)
+
+extern void marker_update_probe_range(struct marker *begin,
+ struct marker *end, struct module *probe_module, int *refcount);
+#else /* !CONFIG_MARKERS */
+#define __trace_mark(name, call_data, format, args...) \
+ __mark_check_format(format, ## args)
+static inline void marker_update_probe_range(struct marker *begin,
+ struct marker *end, struct module *probe_module, int *refcount)
+{ }
+#endif /* CONFIG_MARKERS */
+
+/**
+ * trace_mark - Marker
+ * @name: marker name, not quoted.
+ * @format: format string
+ * @args...: variable argument list
+ *
+ * Places a marker.
+ */
+#define trace_mark(name, format, args...) \
+ __trace_mark(name, NULL, format, ## args)
+
+#define MARK_MAX_FORMAT_LEN 1024
+
+/**
+ * MARK_NOARGS - Format string for a marker with no argument.
+ */
+#define MARK_NOARGS " "
+
+/* To be used for string format validity checking with gcc */
+static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...)
+{
+}
+
+extern marker_probe_func __mark_empty_function;
+
+/*
+ * Connect a probe to a marker.
+ * private data pointer must be a valid allocated memory address, or NULL.
+ */
+extern int marker_probe_register(const char *name, const char *format,
+ marker_probe_func *probe, void *private);
+
+/*
+ * Returns the private data given to marker_probe_register.
+ */
+extern void *marker_probe_unregister(const char *name);
+/*
+ * Unregister a marker by providing the registered private data.
+ */
+extern void *marker_probe_unregister_private_data(void *private);
+
+extern int marker_arm(const char *name);
+extern int marker_disarm(const char *name);
+extern void *marker_get_private_data(const char *name);
+
+#endif
diff --git a/include/linux/memory.h b/include/linux/memory.h
index 654ef554487..33f0ff0cf63 100644
--- a/include/linux/memory.h
+++ b/include/linux/memory.h
@@ -41,18 +41,15 @@ struct memory_block {
#define MEM_ONLINE (1<<0) /* exposed to userspace */
#define MEM_GOING_OFFLINE (1<<1) /* exposed to userspace */
#define MEM_OFFLINE (1<<2) /* exposed to userspace */
+#define MEM_GOING_ONLINE (1<<3)
+#define MEM_CANCEL_ONLINE (1<<4)
+#define MEM_CANCEL_OFFLINE (1<<5)
-/*
- * All of these states are currently kernel-internal for notifying
- * kernel components and architectures.
- *
- * For MEM_MAPPING_INVALID, all notifier chains with priority >0
- * are called before pfn_to_page() becomes invalid. The priority=0
- * entry is reserved for the function that actually makes
- * pfn_to_page() stop working. Any notifiers that want to be called
- * after that should have priority <0.
- */
-#define MEM_MAPPING_INVALID (1<<3)
+struct memory_notify {
+ unsigned long start_pfn;
+ unsigned long nr_pages;
+ int status_change_nid;
+};
struct notifier_block;
struct mem_section;
@@ -69,21 +66,31 @@ static inline int register_memory_notifier(struct notifier_block *nb)
static inline void unregister_memory_notifier(struct notifier_block *nb)
{
}
+static inline int memory_notify(unsigned long val, void *v)
+{
+ return 0;
+}
#else
+extern int register_memory_notifier(struct notifier_block *nb);
+extern void unregister_memory_notifier(struct notifier_block *nb);
extern int register_new_memory(struct mem_section *);
extern int unregister_memory_section(struct mem_section *);
extern int memory_dev_init(void);
extern int remove_memory_block(unsigned long, struct mem_section *, int);
-
+extern int memory_notify(unsigned long val, void *v);
#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
+#ifdef CONFIG_MEMORY_HOTPLUG
#define hotplug_memory_notifier(fn, pri) { \
static struct notifier_block fn##_mem_nb = \
{ .notifier_call = fn, .priority = pri }; \
register_memory_notifier(&fn##_mem_nb); \
}
+#else
+#define hotplug_memory_notifier(fn, pri) do { } while (0)
+#endif
#endif /* _LINUX_MEMORY_H_ */
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 38c04d61ee0..59c4865bc85 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -148,14 +148,6 @@ extern void mpol_rebind_task(struct task_struct *tsk,
const nodemask_t *new);
extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
extern void mpol_fix_fork_child_flag(struct task_struct *p);
-#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x))
-
-#ifdef CONFIG_CPUSETS
-#define current_cpuset_is_being_rebound() \
- (cpuset_being_rebound == current->cpuset)
-#else
-#define current_cpuset_is_being_rebound() 0
-#endif
extern struct mempolicy default_policy;
extern struct zonelist *huge_zonelist(struct vm_area_struct *vma,
@@ -173,8 +165,6 @@ static inline void check_highest_zone(enum zone_type k)
int do_migrate_pages(struct mm_struct *mm,
const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags);
-extern void *cpuset_being_rebound; /* Trigger mpol_copy vma rebind */
-
#else
struct mempolicy {};
@@ -248,8 +238,6 @@ static inline void mpol_fix_fork_child_flag(struct task_struct *p)
{
}
-#define set_cpuset_being_rebound(x) do {} while (0)
-
static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma,
unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol)
{
diff --git a/include/linux/module.h b/include/linux/module.h
index 642f325e491..2cbc0b87e32 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -15,6 +15,7 @@
#include <linux/stringify.h>
#include <linux/kobject.h>
#include <linux/moduleparam.h>
+#include <linux/marker.h>
#include <asm/local.h>
#include <asm/module.h>
@@ -354,6 +355,10 @@ struct module
/* The command line arguments (may be mangled). People like
keeping pointers to this stuff */
char *args;
+#ifdef CONFIG_MARKERS
+ struct marker *markers;
+ unsigned int num_markers;
+#endif
};
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
@@ -457,6 +462,8 @@ int unregister_module_notifier(struct notifier_block * nb);
extern void print_modules(void);
+extern void module_update_markers(struct module *probe_module, int *refcount);
+
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
@@ -556,6 +563,11 @@ static inline void print_modules(void)
{
}
+static inline void module_update_markers(struct module *probe_module,
+ int *refcount)
+{
+}
+
#endif /* CONFIG_MODULES */
struct device_driver;
diff --git a/include/linux/msg.h b/include/linux/msg.h
index f1b60740d64..10a3d5a1abf 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -77,7 +77,6 @@ struct msg_msg {
/* one msq_queue structure for each present queue on the system */
struct msg_queue {
struct kern_ipc_perm q_perm;
- int q_id;
time_t q_stime; /* last msgsnd time */
time_t q_rtime; /* last msgrcv time */
time_t q_ctime; /* last change time */
diff --git a/include/linux/net.h b/include/linux/net.h
index c136abce7ef..dd79cdb8c4c 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -313,6 +313,10 @@ static const struct proto_ops name##_ops = { \
#define MODULE_ALIAS_NET_PF_PROTO(pf, proto) \
MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto))
+#define MODULE_ALIAS_NET_PF_PROTO_TYPE(pf, proto, type) \
+ MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto) \
+ "-type-" __stringify(type))
+
#ifdef CONFIG_SYSCTL
#include <linux/sysctl.h>
extern ctl_table net_table[];
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 6f85db3535e..4a3f54e358e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -996,7 +996,7 @@ static inline void netif_stop_subqueue(struct net_device *dev, u16 queue_index)
*
* Check individual transmit queue of a device with multiple transmit queues.
*/
-static inline int netif_subqueue_stopped(const struct net_device *dev,
+static inline int __netif_subqueue_stopped(const struct net_device *dev,
u16 queue_index)
{
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
@@ -1007,6 +1007,11 @@ static inline int netif_subqueue_stopped(const struct net_device *dev,
#endif
}
+static inline int netif_subqueue_stopped(const struct net_device *dev,
+ struct sk_buff *skb)
+{
+ return __netif_subqueue_stopped(dev, skb_get_queue_mapping(skb));
+}
/**
* netif_wake_subqueue - allow sending packets on subqueue
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index c5164c257f7..e82a6ebc725 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -160,6 +160,12 @@ struct nfs_inode {
/* Open contexts for shared mmap writes */
struct list_head open_files;
+ /* Number of in-flight sillydelete RPC calls */
+ atomic_t silly_count;
+ /* List of deferred sillydelete requests */
+ struct hlist_head silly_list;
+ wait_queue_head_t waitqueue;
+
#ifdef CONFIG_NFS_V4
struct nfs4_cached_acl *nfs4_acl;
/* NFSv4 state */
@@ -394,6 +400,8 @@ extern void nfs_release_automount_timer(void);
*/
extern int nfs_async_unlink(struct inode *dir, struct dentry *dentry);
extern void nfs_complete_unlink(struct dentry *dentry, struct inode *);
+extern void nfs_block_sillyrename(struct dentry *dentry);
+extern void nfs_unblock_sillyrename(struct dentry *dentry);
/*
* linux/fs/nfs/write.c
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index fad7ff17e46..0c40cc0b4a3 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -231,5 +231,22 @@ static inline int notifier_to_errno(int ret)
#define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */
#define PM_POST_SUSPEND 0x0004 /* Suspend finished */
+/* Console keyboard events.
+ * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
+ * KBD_KEYSYM. */
+#define KBD_KEYCODE 0x0001 /* Keyboard keycode, called before any other */
+#define KBD_UNBOUND_KEYCODE 0x0002 /* Keyboard keycode which is not bound to any other */
+#define KBD_UNICODE 0x0003 /* Keyboard unicode */
+#define KBD_KEYSYM 0x0004 /* Keyboard keysym */
+#define KBD_POST_KEYSYM 0x0005 /* Called after keyboard keysym interpretation */
+
+extern struct blocking_notifier_head reboot_notifier_list;
+
+/* Virtual Terminal events. */
+#define VT_ALLOCATE 0x0001 /* Console got allocated */
+#define VT_DEALLOCATE 0x0002 /* Console will be deallocated */
+#define VT_WRITE 0x0003 /* A char got output */
+#define VT_UPDATE 0x0004 /* A bigger update occurred */
+
#endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 033a648709b..0e66b57631f 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -32,8 +32,39 @@ struct nsproxy {
};
extern struct nsproxy init_nsproxy;
+/*
+ * the namespaces access rules are:
+ *
+ * 1. only current task is allowed to change tsk->nsproxy pointer or
+ * any pointer on the nsproxy itself
+ *
+ * 2. when accessing (i.e. reading) current task's namespaces - no
+ * precautions should be taken - just dereference the pointers
+ *
+ * 3. the access to other task namespaces is performed like this
+ * rcu_read_lock();
+ * nsproxy = task_nsproxy(tsk);
+ * if (nsproxy != NULL) {
+ * / *
+ * * work with the namespaces here
+ * * e.g. get the reference on one of them
+ * * /
+ * } / *
+ * * NULL task_nsproxy() means that this task is
+ * * almost dead (zombie)
+ * * /
+ * rcu_read_unlock();
+ *
+ */
+
+static inline struct nsproxy *task_nsproxy(struct task_struct *tsk)
+{
+ return rcu_dereference(tsk->nsproxy);
+}
+
int copy_namespaces(unsigned long flags, struct task_struct *tsk);
-void get_task_namespaces(struct task_struct *tsk);
+void exit_task_namespaces(struct task_struct *tsk);
+void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
void free_nsproxy(struct nsproxy *ns);
int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
struct fs_struct *);
@@ -45,14 +76,15 @@ static inline void put_nsproxy(struct nsproxy *ns)
}
}
-static inline void exit_task_namespaces(struct task_struct *p)
+static inline void get_nsproxy(struct nsproxy *ns)
{
- struct nsproxy *ns = p->nsproxy;
- if (ns) {
- task_lock(p);
- p->nsproxy = NULL;
- task_unlock(p);
- put_nsproxy(ns);
- }
+ atomic_inc(&ns->count);
}
+
+#ifdef CONFIG_CGROUP_NS
+int ns_cgroup_clone(struct task_struct *tsk);
+#else
+static inline int ns_cgroup_clone(struct task_struct *tsk) { return 0; }
+#endif
+
#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 6df80e98591..5c39b9270ff 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -16,8 +16,8 @@
* 2 of the License, or (at your option) any later version.
*/
#include <linux/types.h>
+#include <linux/bitops.h>
-#include <asm/bitops.h>
#include <asm/prom.h>
/* flag descriptions */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 768b93359f9..5d2281f661f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -141,6 +141,7 @@ struct pci_dev {
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
u8 revision; /* PCI revision, low byte of class word */
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
+ u8 pcie_type; /* PCI-E device/port type */
u8 rom_base_reg; /* which config register controls the ROM */
u8 pin; /* which interrupt pin this device uses */
@@ -183,6 +184,7 @@ struct pci_dev {
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
unsigned int is_managed:1;
+ unsigned int is_pcie:1;
atomic_t enable_cnt; /* pci_enable_device has been called */
u32 saved_config_space[16]; /* config space saved at suspend time */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index df948b44eda..4e10a074ca5 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1943,6 +1943,7 @@
#define PCI_DEVICE_ID_TIGON3_5720 0x1658
#define PCI_DEVICE_ID_TIGON3_5721 0x1659
#define PCI_DEVICE_ID_TIGON3_5722 0x165a
+#define PCI_DEVICE_ID_TIGON3_5723 0x165b
#define PCI_DEVICE_ID_TIGON3_5705M 0x165d
#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e
#define PCI_DEVICE_ID_TIGON3_5714 0x1668
diff --git a/include/linux/phantom.h b/include/linux/phantom.h
index d3ebbfae690..96f4048a6cc 100644
--- a/include/linux/phantom.h
+++ b/include/linux/phantom.h
@@ -30,7 +30,11 @@ struct phm_regs {
#define PHN_SET_REG _IOW (PH_IOC_MAGIC, 1, struct phm_reg *)
#define PHN_GET_REGS _IOWR(PH_IOC_MAGIC, 2, struct phm_regs *)
#define PHN_SET_REGS _IOW (PH_IOC_MAGIC, 3, struct phm_regs *)
-#define PH_IOC_MAXNR 3
+/* this ioctl tells the driver, that the caller is not OpenHaptics and might
+ * use improved registers update (no more phantom switchoffs when using
+ * libphantom) */
+#define PHN_NOT_OH _IO (PH_IOC_MAGIC, 4)
+#define PH_IOC_MAXNR 4
#define PHN_CONTROL 0x6 /* control byte in iaddr space */
#define PHN_CTL_AMP 0x1 /* switch after torques change */
diff --git a/include/linux/pid.h b/include/linux/pid.h
index 1e0e4e3423a..e29a900a849 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -40,15 +40,28 @@ enum pid_type
* processes.
*/
-struct pid
-{
- atomic_t count;
+
+/*
+ * struct upid is used to get the id of the struct pid, as it is
+ * seen in particular namespace. Later the struct pid is found with
+ * find_pid_ns() using the int nr and struct pid_namespace *ns.
+ */
+
+struct upid {
/* Try to keep pid_chain in the same cacheline as nr for find_pid */
int nr;
+ struct pid_namespace *ns;
struct hlist_node pid_chain;
+};
+
+struct pid
+{
+ atomic_t count;
/* lists of tasks that use this pid */
struct hlist_head tasks[PIDTYPE_MAX];
struct rcu_head rcu;
+ int level;
+ struct upid numbers[1];
};
extern struct pid init_struct_pid;
@@ -83,26 +96,60 @@ extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type));
extern void FASTCALL(transfer_pid(struct task_struct *old,
struct task_struct *new, enum pid_type));
+struct pid_namespace;
+extern struct pid_namespace init_pid_ns;
+
/*
* look up a PID in the hash table. Must be called with the tasklist_lock
* or rcu_read_lock() held.
+ *
+ * find_pid_ns() finds the pid in the namespace specified
+ * find_pid() find the pid by its global id, i.e. in the init namespace
+ * find_vpid() finr the pid by its virtual id, i.e. in the current namespace
+ *
+ * see also find_task_by_pid() set in include/linux/sched.h
*/
-extern struct pid *FASTCALL(find_pid(int nr));
+extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns));
+extern struct pid *find_vpid(int nr);
+extern struct pid *find_pid(int nr);
/*
* Lookup a PID in the hash table, and return with it's count elevated.
*/
extern struct pid *find_get_pid(int nr);
-extern struct pid *find_ge_pid(int nr);
+extern struct pid *find_ge_pid(int nr, struct pid_namespace *);
-extern struct pid *alloc_pid(void);
+extern struct pid *alloc_pid(struct pid_namespace *ns);
extern void FASTCALL(free_pid(struct pid *pid));
+extern void zap_pid_ns_processes(struct pid_namespace *pid_ns);
+
+/*
+ * the helpers to get the pid's id seen from different namespaces
+ *
+ * pid_nr() : global id, i.e. the id seen from the init namespace;
+ * pid_vnr() : virtual id, i.e. the id seen from the namespace this pid
+ * belongs to. this only makes sence when called in the
+ * context of the task that belongs to the same namespace;
+ * pid_nr_ns() : id seen from the ns specified.
+ *
+ * see also task_xid_nr() etc in include/linux/sched.h
+ */
static inline pid_t pid_nr(struct pid *pid)
{
pid_t nr = 0;
if (pid)
- nr = pid->nr;
+ nr = pid->numbers[0].nr;
+ return nr;
+}
+
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns);
+
+static inline pid_t pid_vnr(struct pid *pid)
+{
+ pid_t nr = 0;
+ if (pid)
+ nr = pid->numbers[pid->level].nr;
return nr;
}
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index b9a17e08ff0..0135c76c76c 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -4,7 +4,6 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/threads.h>
-#include <linux/pid.h>
#include <linux/nsproxy.h>
#include <linux/kref.h>
@@ -20,13 +19,21 @@ struct pid_namespace {
struct pidmap pidmap[PIDMAP_ENTRIES];
int last_pid;
struct task_struct *child_reaper;
+ struct kmem_cache *pid_cachep;
+ int level;
+ struct pid_namespace *parent;
+#ifdef CONFIG_PROC_FS
+ struct vfsmount *proc_mnt;
+#endif
};
extern struct pid_namespace init_pid_ns;
-static inline void get_pid_ns(struct pid_namespace *ns)
+static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns)
{
- kref_get(&ns->kref);
+ if (ns != &init_pid_ns)
+ kref_get(&ns->kref);
+ return ns;
}
extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns);
@@ -34,12 +41,19 @@ extern void free_pid_ns(struct kref *kref);
static inline void put_pid_ns(struct pid_namespace *ns)
{
- kref_put(&ns->kref, free_pid_ns);
+ if (ns != &init_pid_ns)
+ kref_put(&ns->kref, free_pid_ns);
}
-static inline struct task_struct *child_reaper(struct task_struct *tsk)
+static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
{
- return init_pid_ns.child_reaper;
+ return tsk->nsproxy->pid_ns;
+}
+
+static inline struct task_struct *task_child_reaper(struct task_struct *tsk)
+{
+ BUG_ON(tsk != current);
+ return tsk->nsproxy->pid_ns->child_reaper;
}
#endif /* _LINUX_PID_NS_H */
diff --git a/include/linux/prefetch.h b/include/linux/prefetch.h
index 1adfe668d03..af7c36a5a52 100644
--- a/include/linux/prefetch.h
+++ b/include/linux/prefetch.h
@@ -34,17 +34,12 @@
*/
-/*
- * These cannot be do{}while(0) macros. See the mental gymnastics in
- * the loop macro.
- */
-
#ifndef ARCH_HAS_PREFETCH
-static inline void prefetch(const void *x) {;}
+#define prefetch(x) __builtin_prefetch(x)
#endif
#ifndef ARCH_HAS_PREFETCHW
-static inline void prefetchw(const void *x) {;}
+#define prefetchw(x) __builtin_prefetch(x,1)
#endif
#ifndef ARCH_HAS_SPINLOCK_PREFETCH
diff --git a/include/linux/prio_heap.h b/include/linux/prio_heap.h
new file mode 100644
index 00000000000..08094350f26
--- /dev/null
+++ b/include/linux/prio_heap.h
@@ -0,0 +1,58 @@
+#ifndef _LINUX_PRIO_HEAP_H
+#define _LINUX_PRIO_HEAP_H
+
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/gfp.h>
+
+/**
+ * struct ptr_heap - simple static-sized priority heap
+ * @ptrs - pointer to data area
+ * @max - max number of elements that can be stored in @ptrs
+ * @size - current number of valid elements in @ptrs (in the range 0..@size-1
+ * @gt: comparison operator, which should implement "greater than"
+ */
+struct ptr_heap {
+ void **ptrs;
+ int max;
+ int size;
+ int (*gt)(void *, void *);
+};
+
+/**
+ * heap_init - initialize an empty heap with a given memory size
+ * @heap: the heap structure to be initialized
+ * @size: amount of memory to use in bytes
+ * @gfp_mask: mask to pass to kmalloc()
+ * @gt: comparison operator, which should implement "greater than"
+ */
+extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+ int (*gt)(void *, void *));
+
+/**
+ * heap_free - release a heap's storage
+ * @heap: the heap structure whose data should be released
+ */
+void heap_free(struct ptr_heap *heap);
+
+/**
+ * heap_insert - insert a value into the heap and return any overflowed value
+ * @heap: the heap to be operated on
+ * @p: the pointer to be inserted
+ *
+ * Attempts to insert the given value into the priority heap. If the
+ * heap is full prior to the insertion, then the resulting heap will
+ * consist of the smallest @max elements of the original heap and the
+ * new element; the greatest element will be removed from the heap and
+ * returned. Note that the returned element will be the new element
+ * (i.e. no change to the heap) if the new element is greater than all
+ * elements currently in the heap.
+ */
+extern void *heap_insert(struct ptr_heap *heap, void *p);
+
+
+
+#endif /* _LINUX_PRIO_HEAP_H */
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 20741f668f7..1ff46167206 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -125,7 +125,8 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
extern struct vfsmount *proc_mnt;
-extern int proc_fill_super(struct super_block *,void *,int);
+struct pid_namespace;
+extern int proc_fill_super(struct super_block *);
extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *);
/*
@@ -142,6 +143,9 @@ extern const struct file_operations proc_kcore_operations;
extern const struct file_operations proc_kmsg_operations;
extern const struct file_operations ppc_htab_operations;
+extern int pid_ns_prepare_proc(struct pid_namespace *ns);
+extern void pid_ns_release_proc(struct pid_namespace *ns);
+
/*
* proc_tty.c
*/
@@ -207,7 +211,9 @@ extern void proc_net_remove(struct net *net, const char *name);
#define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; })
static inline void proc_net_remove(struct net *net, const char *name) {}
-static inline void proc_flush_task(struct task_struct *task) { }
+static inline void proc_flush_task(struct task_struct *task)
+{
+}
static inline struct proc_dir_entry *create_proc_entry(const char *name,
mode_t mode, struct proc_dir_entry *parent) { return NULL; }
@@ -232,6 +238,15 @@ static inline void proc_tty_unregister_driver(struct tty_driver *driver) {};
extern struct proc_dir_entry proc_root;
+static inline int pid_ns_prepare_proc(struct pid_namespace *ns)
+{
+ return 0;
+}
+
+static inline void pid_ns_release_proc(struct pid_namespace *ns)
+{
+}
+
#endif /* CONFIG_PROC_FS */
#if !defined(CONFIG_PROC_KCORE)
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 8dcf237d338..422eab4958a 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -28,6 +28,8 @@
#include <linux/reiserfs_fs_sb.h>
#endif
+struct fid;
+
/*
* include/linux/reiser_fs.h
*
@@ -85,7 +87,7 @@ void reiserfs_warning(struct super_block *s, const char *fmt, ...);
if( !( cond ) ) \
reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at " \
__FILE__ ":%i:%s: " format "\n", \
- in_interrupt() ? -1 : current -> pid, __LINE__ , __FUNCTION__ , ##args )
+ in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args )
#define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args)
@@ -283,6 +285,18 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb)
return sb->s_fs_info;
}
+/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16
+ * which overflows on large file systems. */
+static inline u32 reiserfs_bmap_count(struct super_block *sb)
+{
+ return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1;
+}
+
+static inline int bmap_would_wrap(unsigned bmap_nr)
+{
+ return bmap_nr > ((1LL << 16) - 1);
+}
+
/** this says about version of key of all items (but stat data) the
object consists of */
#define get_inode_item_key_version( inode ) \
@@ -1734,8 +1748,8 @@ int journal_end_sync(struct reiserfs_transaction_handle *, struct super_block *,
int journal_mark_freed(struct reiserfs_transaction_handle *,
struct super_block *, b_blocknr_t blocknr);
int journal_transaction_should_end(struct reiserfs_transaction_handle *, int);
-int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr,
- int searchall, b_blocknr_t * next);
+int reiserfs_in_journal(struct super_block *p_s_sb, unsigned int bmap_nr,
+ int bit_nr, int searchall, b_blocknr_t *next);
int journal_begin(struct reiserfs_transaction_handle *,
struct super_block *p_s_sb, unsigned long);
int journal_join_abort(struct reiserfs_transaction_handle *,
@@ -1743,7 +1757,7 @@ int journal_join_abort(struct reiserfs_transaction_handle *,
void reiserfs_journal_abort(struct super_block *sb, int errno);
void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...);
int reiserfs_allocate_list_bitmaps(struct super_block *s,
- struct reiserfs_list_bitmap *, int);
+ struct reiserfs_list_bitmap *, unsigned int);
void add_save_link(struct reiserfs_transaction_handle *th,
struct inode *inode, int truncate);
@@ -1865,12 +1879,10 @@ void reiserfs_delete_inode(struct inode *inode);
int reiserfs_write_inode(struct inode *inode, int);
int reiserfs_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int create);
-struct dentry *reiserfs_get_dentry(struct super_block *, void *);
-struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
- int len, int fhtype,
- int (*acceptable) (void *contect,
- struct dentry * de),
- void *context);
+struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
+struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
+ int fh_len, int fh_type);
int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
int connectable);
@@ -2041,7 +2053,7 @@ struct buffer_head *get_FEB(struct tree_balance *);
* arguments, such as node, search path, transaction_handle, etc. */
struct __reiserfs_blocknr_hint {
struct inode *inode; /* inode passed to allocator, if we allocate unf. nodes */
- long block; /* file offset, in blocks */
+ sector_t block; /* file offset, in blocks */
struct in_core_key key;
struct treepath *path; /* search path, used by allocator to deternine search_start by
* various ways */
@@ -2099,7 +2111,8 @@ static inline int reiserfs_new_form_blocknrs(struct tree_balance *tb,
static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
*th, struct inode *inode,
b_blocknr_t * new_blocknrs,
- struct treepath *path, long block)
+ struct treepath *path,
+ sector_t block)
{
reiserfs_blocknr_hint_t hint = {
.th = th,
@@ -2116,7 +2129,8 @@ static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle
static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle
*th, struct inode *inode,
b_blocknr_t * new_blocknrs,
- struct treepath *path, long block)
+ struct treepath *path,
+ sector_t block)
{
reiserfs_blocknr_hint_t hint = {
.th = th,
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index ff9e9234f8b..10fa0c83201 100644
--- a/include/linux/reiserfs_fs_sb.h
+++ b/include/linux/reiserfs_fs_sb.h
@@ -265,9 +265,7 @@ enum journal_state_bits {
typedef __u32(*hashf_t) (const signed char *, int);
struct reiserfs_bitmap_info {
- // FIXME: Won't work with block sizes > 8K
- __u16 first_zero_hint;
- __u16 free_count;
+ __u32 free_count;
};
struct proc_dir_entry;
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 2dc7464cce5..42daf5e1526 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -4,47 +4,95 @@
#include <asm/scatterlist.h>
#include <linux/mm.h>
#include <linux/string.h>
+#include <asm/io.h>
+/*
+ * Notes on SG table design.
+ *
+ * Architectures must provide an unsigned long page_link field in the
+ * scatterlist struct. We use that to place the page pointer AND encode
+ * information about the sg table as well. The two lower bits are reserved
+ * for this information.
+ *
+ * If bit 0 is set, then the page_link contains a pointer to the next sg
+ * table list. Otherwise the next entry is at sg + 1.
+ *
+ * If bit 1 is set, then this sg entry is the last element in a list.
+ *
+ * See sg_next().
+ *
+ */
+
+#define SG_MAGIC 0x87654321
+
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg: SG entry
+ * @page: The page
+ *
+ * Description:
+ * Use this function to set an sg entry pointing at a page, never assign
+ * the page directly. We encode sg table information in the lower bits
+ * of the page pointer. See sg_page() for looking up the page belonging
+ * to an sg entry.
+ *
+ **/
+static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+{
+ unsigned long page_link = sg->page_link & 0x3;
+
+#ifdef CONFIG_DEBUG_SG
+ BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+ sg->page_link = page_link | (unsigned long) page;
+}
+
+#define sg_page(sg) ((struct page *) ((sg)->page_link & ~0x3))
+
+/**
+ * sg_set_buf - Set sg entry to point at given data
+ * @sg: SG entry
+ * @buf: Data
+ * @buflen: Data length
+ *
+ **/
static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
unsigned int buflen)
{
- sg->page = virt_to_page(buf);
+ sg_set_page(sg, virt_to_page(buf));
sg->offset = offset_in_page(buf);
sg->length = buflen;
}
-static inline void sg_init_one(struct scatterlist *sg, const void *buf,
- unsigned int buflen)
-{
- memset(sg, 0, sizeof(*sg));
- sg_set_buf(sg, buf, buflen);
-}
-
/*
* We overload the LSB of the page pointer to indicate whether it's
* a valid sg entry, or whether it points to the start of a new scatterlist.
* Those low bits are there for everyone! (thanks mason :-)
*/
-#define sg_is_chain(sg) ((unsigned long) (sg)->page & 0x01)
+#define sg_is_chain(sg) ((sg)->page_link & 0x01)
+#define sg_is_last(sg) ((sg)->page_link & 0x02)
#define sg_chain_ptr(sg) \
- ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
+ ((struct scatterlist *) ((sg)->page_link & ~0x03))
/**
* sg_next - return the next scatterlist entry in a list
* @sg: The current sg entry
*
- * Usually the next entry will be @sg@ + 1, but if this sg element is part
- * of a chained scatterlist, it could jump to the start of a new
- * scatterlist array.
- *
- * Note that the caller must ensure that there are further entries after
- * the current entry, this function will NOT return NULL for an end-of-list.
+ * Description:
+ * Usually the next entry will be @sg@ + 1, but if this sg element is part
+ * of a chained scatterlist, it could jump to the start of a new
+ * scatterlist array.
*
- */
+ **/
static inline struct scatterlist *sg_next(struct scatterlist *sg)
{
- sg++;
+#ifdef CONFIG_DEBUG_SG
+ BUG_ON(sg->sg_magic != SG_MAGIC);
+#endif
+ if (sg_is_last(sg))
+ return NULL;
+ sg++;
if (unlikely(sg_is_chain(sg)))
sg = sg_chain_ptr(sg);
@@ -62,14 +110,15 @@ static inline struct scatterlist *sg_next(struct scatterlist *sg)
* @sgl: First entry in the scatterlist
* @nents: Number of entries in the scatterlist
*
- * Should only be used casually, it (currently) scan the entire list
- * to get the last entry.
+ * Description:
+ * Should only be used casually, it (currently) scan the entire list
+ * to get the last entry.
*
- * Note that the @sgl@ pointer passed in need not be the first one,
- * the important bit is that @nents@ denotes the number of entries that
- * exist from @sgl@.
+ * Note that the @sgl@ pointer passed in need not be the first one,
+ * the important bit is that @nents@ denotes the number of entries that
+ * exist from @sgl@.
*
- */
+ **/
static inline struct scatterlist *sg_last(struct scatterlist *sgl,
unsigned int nents)
{
@@ -83,6 +132,10 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
ret = sg;
#endif
+#ifdef CONFIG_DEBUG_SG
+ BUG_ON(sgl[0].sg_magic != SG_MAGIC);
+ BUG_ON(!sg_is_last(ret));
+#endif
return ret;
}
@@ -92,16 +145,111 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
* @prv_nents: Number of entries in prv
* @sgl: Second scatterlist
*
- * Links @prv@ and @sgl@ together, to form a longer scatterlist.
+ * Description:
+ * Links @prv@ and @sgl@ together, to form a longer scatterlist.
*
- */
+ **/
static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
struct scatterlist *sgl)
{
#ifndef ARCH_HAS_SG_CHAIN
BUG();
#endif
- prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
+ prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+}
+
+/**
+ * sg_mark_end - Mark the end of the scatterlist
+ * @sgl: Scatterlist
+ * @nents: Number of entries in sgl
+ *
+ * Description:
+ * Marks the last entry as the termination point for sg_next()
+ *
+ **/
+static inline void sg_mark_end(struct scatterlist *sgl, unsigned int nents)
+{
+ sgl[nents - 1].page_link = 0x02;
+}
+
+static inline void __sg_mark_end(struct scatterlist *sg)
+{
+ sg->page_link |= 0x02;
+}
+
+/**
+ * sg_init_one - Initialize a single entry sg list
+ * @sg: SG entry
+ * @buf: Virtual address for IO
+ * @buflen: IO length
+ *
+ * Notes:
+ * This should not be used on a single entry that is part of a larger
+ * table. Use sg_init_table() for that.
+ *
+ **/
+static inline void sg_init_one(struct scatterlist *sg, const void *buf,
+ unsigned int buflen)
+{
+ memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+ sg->sg_magic = SG_MAGIC;
+#endif
+ sg_mark_end(sg, 1);
+ sg_set_buf(sg, buf, buflen);
+}
+
+/**
+ * sg_init_table - Initialize SG table
+ * @sgl: The SG table
+ * @nents: Number of entries in table
+ *
+ * Notes:
+ * If this is part of a chained sg table, sg_mark_end() should be
+ * used only on the last table part.
+ *
+ **/
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+ memset(sgl, 0, sizeof(*sgl) * nents);
+ sg_mark_end(sgl, nents);
+#ifdef CONFIG_DEBUG_SG
+ {
+ int i;
+ for (i = 0; i < nents; i++)
+ sgl[i].sg_magic = SG_MAGIC;
+ }
+#endif
+}
+
+/**
+ * sg_phys - Return physical address of an sg entry
+ * @sg: SG entry
+ *
+ * Description:
+ * This calls page_to_phys() on the page in this sg entry, and adds the
+ * sg offset. The caller must know that it is legal to call page_to_phys()
+ * on the sg page.
+ *
+ **/
+static inline unsigned long sg_phys(struct scatterlist *sg)
+{
+ return page_to_phys(sg_page(sg)) + sg->offset;
+}
+
+/**
+ * sg_virt - Return virtual address of an sg entry
+ * @sg: SG entry
+ *
+ * Description:
+ * This calls page_address() on the page in this sg entry, and adds the
+ * sg offset. The caller must know that the sg page has a valid virtual
+ * mapping.
+ *
+ **/
+static inline void *sg_virt(struct scatterlist *sg)
+{
+ return page_address(sg_page(sg)) + sg->offset;
}
#endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 10a83d8d577..13df99fb276 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -25,6 +25,7 @@
#define CLONE_NEWUTS 0x04000000 /* New utsname group? */
#define CLONE_NEWIPC 0x08000000 /* New ipcs */
#define CLONE_NEWUSER 0x10000000 /* New user namespace */
+#define CLONE_NEWPID 0x20000000 /* New pid namespace */
#define CLONE_NEWNET 0x40000000 /* New network namespace */
/*
@@ -428,7 +429,17 @@ struct signal_struct {
cputime_t it_prof_incr, it_virt_incr;
/* job control IDs */
- pid_t pgrp;
+
+ /*
+ * pgrp and session fields are deprecated.
+ * use the task_session_Xnr and task_pgrp_Xnr routines below
+ */
+
+ union {
+ pid_t pgrp __deprecated;
+ pid_t __pgrp;
+ };
+
struct pid *tty_old_pgrp;
union {
@@ -736,6 +747,8 @@ struct sched_domain {
#endif
};
+extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new);
+
#endif /* CONFIG_SMP */
/*
@@ -756,8 +769,6 @@ static inline int above_background_load(void)
}
struct io_context; /* See blkdev.h */
-struct cpuset;
-
#define NGROUPS_SMALL 32
#define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t)))
struct group_info {
@@ -1125,11 +1136,16 @@ struct task_struct {
short il_next;
#endif
#ifdef CONFIG_CPUSETS
- struct cpuset *cpuset;
nodemask_t mems_allowed;
int cpuset_mems_generation;
int cpuset_mem_spread_rotor;
#endif
+#ifdef CONFIG_CGROUPS
+ /* Control Group info protected by css_set_lock */
+ struct css_set *cgroups;
+ /* cg_list protected by css_set_lock and tsk->alloc_lock */
+ struct list_head cg_list;
+#endif
#ifdef CONFIG_FUTEX
struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
@@ -1185,24 +1201,14 @@ static inline int rt_task(struct task_struct *p)
return rt_prio(p->prio);
}
-static inline pid_t process_group(struct task_struct *tsk)
+static inline void set_task_session(struct task_struct *tsk, pid_t session)
{
- return tsk->signal->pgrp;
+ tsk->signal->__session = session;
}
-static inline pid_t signal_session(struct signal_struct *sig)
+static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp)
{
- return sig->__session;
-}
-
-static inline pid_t process_session(struct task_struct *tsk)
-{
- return signal_session(tsk->signal);
-}
-
-static inline void set_signal_session(struct signal_struct *sig, pid_t session)
-{
- sig->__session = session;
+ tsk->signal->__pgrp = pgrp;
}
static inline struct pid *task_pid(struct task_struct *task)
@@ -1225,6 +1231,88 @@ static inline struct pid *task_session(struct task_struct *task)
return task->group_leader->pids[PIDTYPE_SID].pid;
}
+struct pid_namespace;
+
+/*
+ * the helpers to get the task's different pids as they are seen
+ * from various namespaces
+ *
+ * task_xid_nr() : global id, i.e. the id seen from the init namespace;
+ * task_xid_vnr() : virtual id, i.e. the id seen from the namespace the task
+ * belongs to. this only makes sence when called in the
+ * context of the task that belongs to the same namespace;
+ * task_xid_nr_ns() : id seen from the ns specified;
+ *
+ * set_task_vxid() : assigns a virtual id to a task;
+ *
+ * task_ppid_nr_ns() : the parent's id as seen from the namespace specified.
+ * the result depends on the namespace and whether the
+ * task in question is the namespace's init. e.g. for the
+ * namespace's init this will return 0 when called from
+ * the namespace of this init, or appropriate id otherwise.
+ *
+ *
+ * see also pid_nr() etc in include/linux/pid.h
+ */
+
+static inline pid_t task_pid_nr(struct task_struct *tsk)
+{
+ return tsk->pid;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pid_vnr(struct task_struct *tsk)
+{
+ return pid_vnr(task_pid(tsk));
+}
+
+
+static inline pid_t task_tgid_nr(struct task_struct *tsk)
+{
+ return tsk->tgid;
+}
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+ return pid_vnr(task_tgid(tsk));
+}
+
+
+static inline pid_t task_pgrp_nr(struct task_struct *tsk)
+{
+ return tsk->signal->__pgrp;
+}
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_pgrp_vnr(struct task_struct *tsk)
+{
+ return pid_vnr(task_pgrp(tsk));
+}
+
+
+static inline pid_t task_session_nr(struct task_struct *tsk)
+{
+ return tsk->signal->__session;
+}
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
+
+static inline pid_t task_session_vnr(struct task_struct *tsk)
+{
+ return pid_vnr(task_session(tsk));
+}
+
+
+static inline pid_t task_ppid_nr_ns(struct task_struct *tsk,
+ struct pid_namespace *ns)
+{
+ return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns);
+}
+
/**
* pid_alive - check that a task structure is not stale
* @p: Task structure to be checked.
@@ -1239,16 +1327,22 @@ static inline int pid_alive(struct task_struct *p)
}
/**
- * is_init - check if a task structure is init
+ * is_global_init - check if a task structure is init
* @tsk: Task structure to be checked.
*
* Check if a task structure is the first user space task the kernel created.
*/
-static inline int is_init(struct task_struct *tsk)
+static inline int is_global_init(struct task_struct *tsk)
{
return tsk->pid == 1;
}
+/*
+ * is_container_init:
+ * check whether in the task is init in its own pid namespace.
+ */
+extern int is_container_init(struct task_struct *tsk);
+
extern struct pid *cad_pid;
extern void free_task(struct task_struct *tsk);
@@ -1420,8 +1514,32 @@ extern struct task_struct init_task;
extern struct mm_struct init_mm;
-#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr)
-extern struct task_struct *find_task_by_pid_type(int type, int pid);
+extern struct pid_namespace init_pid_ns;
+
+/*
+ * find a task by one of its numerical ids
+ *
+ * find_task_by_pid_type_ns():
+ * it is the most generic call - it finds a task by all id,
+ * type and namespace specified
+ * find_task_by_pid_ns():
+ * finds a task by its pid in the specified namespace
+ * find_task_by_vpid():
+ * finds a task by its virtual pid
+ * find_task_by_pid():
+ * finds a task by its global pid
+ *
+ * see also find_pid() etc in include/linux/pid.h
+ */
+
+extern struct task_struct *find_task_by_pid_type_ns(int type, int pid,
+ struct pid_namespace *ns);
+
+extern struct task_struct *find_task_by_pid(pid_t nr);
+extern struct task_struct *find_task_by_vpid(pid_t nr);
+extern struct task_struct *find_task_by_pid_ns(pid_t nr,
+ struct pid_namespace *ns);
+
extern void __set_special_pids(pid_t session, pid_t pgrp);
/* per-UID process charging. */
@@ -1608,6 +1726,12 @@ static inline int has_group_leader_pid(struct task_struct *p)
return p->pid == p->tgid;
}
+static inline
+int same_thread_group(struct task_struct *p1, struct task_struct *p2)
+{
+ return p1->tgid == p2->tgid;
+}
+
static inline struct task_struct *next_thread(const struct task_struct *p)
{
return list_entry(rcu_dereference(p->thread_group.next),
@@ -1625,7 +1749,8 @@ static inline int thread_group_empty(struct task_struct *p)
/*
* Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring
* subscriptions and synchronises with wait4(). Also used in procfs. Also
- * pins the final release of task.io_context. Also protects ->cpuset.
+ * pins the final release of task.io_context. Also protects ->cpuset and
+ * ->cgroup.subsys[].
*
* Nests both inside and outside of read_lock(&tasklist_lock).
* It must not be nested with write_lock_irq(&tasklist_lock),
diff --git a/include/linux/security.h b/include/linux/security.h
index ff3f857f695..ac050830a87 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -832,9 +832,11 @@ struct request_sock;
* incoming sk_buff @skb has been associated with a particular socket, @sk.
* @sk contains the sock (not socket) associated with the incoming sk_buff.
* @skb contains the incoming network data.
- * @socket_getpeersec:
+ * @socket_getpeersec_stream:
* This hook allows the security module to provide peer socket security
- * state to userspace via getsockopt SO_GETPEERSEC.
+ * state for unix or connected tcp sockets to userspace via getsockopt
+ * SO_GETPEERSEC. For tcp sockets this can be meaningful if the
+ * socket is associated with an ipsec SA.
* @sock is the local socket.
* @optval userspace memory where the security state is to be copied.
* @optlen userspace int where the module should copy the actual length
@@ -843,6 +845,17 @@ struct request_sock;
* by the caller.
* Return 0 if all is well, otherwise, typical getsockopt return
* values.
+ * @socket_getpeersec_dgram:
+ * This hook allows the security module to provide peer socket security
+ * state for udp sockets on a per-packet basis to userspace via
+ * getsockopt SO_GETPEERSEC. The application must first have indicated
+ * the IP_PASSSEC option via getsockopt. It can then retrieve the
+ * security state returned by this hook for a packet via the SCM_SECURITY
+ * ancillary message type.
+ * @skb is the skbuff for the packet being queried
+ * @secdata is a pointer to a buffer in which to copy the security data
+ * @seclen is the maximum length for @secdata
+ * Return 0 on success, error on failure.
* @sk_alloc_security:
* Allocate and attach a security structure to the sk->sk_security field,
* which is used to copy security attributes between local stream sockets.
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 9aaffb0b1d8..c8eaad9e4b7 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -90,7 +90,6 @@ struct sem {
/* One sem_array data structure for each set of semaphores in the system. */
struct sem_array {
struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */
- int sem_id;
time_t sem_otime; /* last semop time */
time_t sem_ctime; /* last change time */
struct sem *sem_base; /* ptr to first semaphore in array */
diff --git a/include/linux/shm.h b/include/linux/shm.h
index bea65d9c93e..eeaed921a1d 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -79,7 +79,6 @@ struct shmid_kernel /* private to the kernel */
{
struct kern_ipc_perm shm_perm;
struct file * shm_file;
- int id;
unsigned long shm_nattch;
unsigned long shm_segsz;
time_t shm_atim;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f93f22b3d2f..fd4e12f2427 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -41,8 +41,7 @@
#define SKB_DATA_ALIGN(X) (((X) + (SMP_CACHE_BYTES - 1)) & \
~(SMP_CACHE_BYTES - 1))
#define SKB_WITH_OVERHEAD(X) \
- (((X) - sizeof(struct skb_shared_info)) & \
- ~(SMP_CACHE_BYTES - 1))
+ ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
#define SKB_MAX_ORDER(X, ORDER) \
SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X))
#define SKB_MAX_HEAD(X) (SKB_MAX_ORDER((X), 0))
@@ -301,8 +300,9 @@ struct sk_buff {
#endif
int iif;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
__u16 queue_mapping;
-
+#endif
#ifdef CONFIG_NET_SCHED
__u16 tc_index; /* traffic control index */
#ifdef CONFIG_NET_CLS_ACT
@@ -1770,6 +1770,15 @@ static inline void skb_set_queue_mapping(struct sk_buff *skb, u16 queue_mapping)
#endif
}
+static inline u16 skb_get_queue_mapping(struct sk_buff *skb)
+{
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ return skb->queue_mapping;
+#else
+ return 0;
+#endif
+}
+
static inline void skb_copy_queue_mapping(struct sk_buff *to, const struct sk_buff *from)
{
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
diff --git a/include/linux/socket.h b/include/linux/socket.h
index f852e1afd65..c22ef1c1afb 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -291,6 +291,7 @@ struct ucred {
#define SOL_TIPC 271
#define SOL_RXRPC 272
#define SOL_PPPOL2TP 273
+#define SOL_BLUETOOTH 274
/* IPX options */
#define IPX_TYPE 1
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9a7252e089b..f4a1395e05f 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -40,6 +40,7 @@ enum tick_nohz_mode {
* @idle_sleeps: Number of idle calls, where the sched tick was stopped
* @idle_entrytime: Time when the idle call was entered
* @idle_sleeptime: Sum of the time slept in idle with sched tick stopped
+ * @sleep_length: Duration of the current idle sleep
*/
struct tick_sched {
struct hrtimer sched_timer;
@@ -52,6 +53,7 @@ struct tick_sched {
unsigned long idle_sleeps;
ktime_t idle_entrytime;
ktime_t idle_sleeptime;
+ ktime_t sleep_length;
unsigned long last_jiffies;
unsigned long next_jiffies;
ktime_t idle_expires;
@@ -100,10 +102,17 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
extern void tick_nohz_stop_sched_tick(void);
extern void tick_nohz_restart_sched_tick(void);
extern void tick_nohz_update_jiffies(void);
+extern ktime_t tick_nohz_get_sleep_length(void);
# else
static inline void tick_nohz_stop_sched_tick(void) { }
static inline void tick_nohz_restart_sched_tick(void) { }
static inline void tick_nohz_update_jiffies(void) { }
+static inline ktime_t tick_nohz_get_sleep_length(void)
+{
+ ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
+
+ return len;
+}
# endif /* !NO_HZ */
#endif
diff --git a/include/linux/types.h b/include/linux/types.h
index 0351bf2fac8..4f0dad21c91 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -3,12 +3,9 @@
#ifdef __KERNEL__
-#define BITS_TO_LONGS(bits) \
- (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
-#define BITS_PER_BYTE 8
#endif
#include <linux/posix_types.h>
diff --git a/include/linux/uinput.h b/include/linux/uinput.h
index a6c1e8eed22..15ddd4483b0 100644
--- a/include/linux/uinput.h
+++ b/include/linux/uinput.h
@@ -162,10 +162,6 @@ struct uinput_ff_erase {
#define UI_FF_UPLOAD 1
#define UI_FF_ERASE 2
-#ifndef NBITS
-#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-#endif /* NBITS */
-
#define UINPUT_MAX_NAME_SIZE 80
struct uinput_user_dev {
char name[UINPUT_MAX_NAME_SIZE];
diff --git a/include/linux/videodev.h b/include/linux/videodev.h
index 8dba97a291f..52e3d5fd5be 100644
--- a/include/linux/videodev.h
+++ b/include/linux/videodev.h
@@ -294,48 +294,6 @@ struct video_code
#define VID_PLAY_RESET 13
#define VID_PLAY_END_MARK 14
-
-
-#define VID_HARDWARE_BT848 1
-#define VID_HARDWARE_QCAM_BW 2
-#define VID_HARDWARE_PMS 3
-#define VID_HARDWARE_QCAM_C 4
-#define VID_HARDWARE_PSEUDO 5
-#define VID_HARDWARE_SAA5249 6
-#define VID_HARDWARE_AZTECH 7
-#define VID_HARDWARE_SF16MI 8
-#define VID_HARDWARE_RTRACK 9
-#define VID_HARDWARE_ZOLTRIX 10
-#define VID_HARDWARE_SAA7146 11
-#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */
-#define VID_HARDWARE_RTRACK2 13
-#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */
-#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */
-#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */
-#define VID_HARDWARE_BROADWAY 17 /* Broadway project */
-#define VID_HARDWARE_GEMTEK 18
-#define VID_HARDWARE_TYPHOON 19
-#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */
-#define VID_HARDWARE_CADET 21 /* Cadet radio */
-#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */
-#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */
-#define VID_HARDWARE_CPIA 24
-#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */
-#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */
-#define VID_HARDWARE_OV511 27
-#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */
-#define VID_HARDWARE_W9966 29
-#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */
-#define VID_HARDWARE_PWC 31 /* Philips webcams */
-#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */
-#define VID_HARDWARE_CPIA2 33
-#define VID_HARDWARE_VICAM 34
-#define VID_HARDWARE_SF16FMR2 35
-#define VID_HARDWARE_W9968CF 36
-#define VID_HARDWARE_SAA7114H 37
-#define VID_HARDWARE_SN9C102 38
-#define VID_HARDWARE_ARV 39
-
#endif /* CONFIG_VIDEO_V4L1_COMPAT */
#endif /* __LINUX_VIDEODEV_H */
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 1f503e94eff..439474f24e3 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -441,94 +441,6 @@ struct v4l2_timecode
#define V4L2_TC_USERBITS_8BITCHARS 0x0008
/* The above is based on SMPTE timecodes */
-#ifdef __KERNEL__
-/*
- * M P E G C O M P R E S S I O N P A R A M E T E R S
- *
- * ### WARNING: This experimental MPEG compression API is obsolete.
- * ### It is replaced by the MPEG controls API.
- * ### This old API will disappear in the near future!
- *
- */
-enum v4l2_bitrate_mode {
- V4L2_BITRATE_NONE = 0, /* not specified */
- V4L2_BITRATE_CBR, /* constant bitrate */
- V4L2_BITRATE_VBR, /* variable bitrate */
-};
-struct v4l2_bitrate {
- /* rates are specified in kbit/sec */
- enum v4l2_bitrate_mode mode;
- __u32 min;
- __u32 target; /* use this one for CBR */
- __u32 max;
-};
-
-enum v4l2_mpeg_streamtype {
- V4L2_MPEG_SS_1, /* MPEG-1 system stream */
- V4L2_MPEG_PS_2, /* MPEG-2 program stream */
- V4L2_MPEG_TS_2, /* MPEG-2 transport stream */
- V4L2_MPEG_PS_DVD, /* MPEG-2 program stream with DVD header fixups */
-};
-enum v4l2_mpeg_audiotype {
- V4L2_MPEG_AU_2_I, /* MPEG-2 layer 1 */
- V4L2_MPEG_AU_2_II, /* MPEG-2 layer 2 */
- V4L2_MPEG_AU_2_III, /* MPEG-2 layer 3 */
- V4L2_MPEG_AC3, /* AC3 */
- V4L2_MPEG_LPCM, /* LPCM */
-};
-enum v4l2_mpeg_videotype {
- V4L2_MPEG_VI_1, /* MPEG-1 */
- V4L2_MPEG_VI_2, /* MPEG-2 */
-};
-enum v4l2_mpeg_aspectratio {
- V4L2_MPEG_ASPECT_SQUARE = 1, /* square pixel */
- V4L2_MPEG_ASPECT_4_3 = 2, /* 4 : 3 */
- V4L2_MPEG_ASPECT_16_9 = 3, /* 16 : 9 */
- V4L2_MPEG_ASPECT_1_221 = 4, /* 1 : 2,21 */
-};
-
-struct v4l2_mpeg_compression {
- /* general */
- enum v4l2_mpeg_streamtype st_type;
- struct v4l2_bitrate st_bitrate;
-
- /* transport streams */
- __u16 ts_pid_pmt;
- __u16 ts_pid_audio;
- __u16 ts_pid_video;
- __u16 ts_pid_pcr;
-
- /* program stream */
- __u16 ps_size;
- __u16 reserved_1; /* align */
-
- /* audio */
- enum v4l2_mpeg_audiotype au_type;
- struct v4l2_bitrate au_bitrate;
- __u32 au_sample_rate;
- __u8 au_pesid;
- __u8 reserved_2[3]; /* align */
-
- /* video */
- enum v4l2_mpeg_videotype vi_type;
- enum v4l2_mpeg_aspectratio vi_aspect_ratio;
- struct v4l2_bitrate vi_bitrate;
- __u32 vi_frame_rate;
- __u16 vi_frames_per_gop;
- __u16 vi_bframes_count;
- __u8 vi_pesid;
- __u8 reserved_3[3]; /* align */
-
- /* misc flags */
- __u32 closed_gops:1;
- __u32 pulldown:1;
- __u32 reserved_4:30; /* align */
-
- /* I don't expect the above being perfect yet ;) */
- __u32 reserved_5[8];
-};
-#endif
-
struct v4l2_jpegcompression
{
int quality;
@@ -1420,10 +1332,6 @@ struct v4l2_chip_ident {
#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc)
#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format)
#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format)
-#ifdef __KERNEL__
-#define VIDIOC_G_MPEGCOMP _IOR ('V', 6, struct v4l2_mpeg_compression)
-#define VIDIOC_S_MPEGCOMP _IOW ('V', 7, struct v4l2_mpeg_compression)
-#endif
#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers)
#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer)
#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer)
diff --git a/include/linux/vt.h b/include/linux/vt.h
index ba806e8711b..02c1c028877 100644
--- a/include/linux/vt.h
+++ b/include/linux/vt.h
@@ -1,6 +1,18 @@
#ifndef _LINUX_VT_H
#define _LINUX_VT_H
+#ifdef __KERNEL__
+struct notifier_block;
+
+struct vt_notifier_param {
+ struct vc_data *vc; /* VC on which the update happened */
+ unsigned int c; /* Printed char */
+};
+
+extern int register_vt_notifier(struct notifier_block *nb);
+extern int unregister_vt_notifier(struct notifier_block *nb);
+#endif
+
/*
* These constants are also useful for user-level apps (e.g., VC
* resizing).
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index ce6badc98f6..7daafdc2514 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -8,6 +8,7 @@
#include <linux/timer.h>
#include <linux/linkage.h>
#include <linux/bitops.h>
+#include <linux/lockdep.h>
#include <asm/atomic.h>
struct workqueue_struct;
@@ -28,6 +29,9 @@ struct work_struct {
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct list_head entry;
work_func_t func;
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map lockdep_map;
+#endif
};
#define WORK_DATA_INIT() ATOMIC_LONG_INIT(0)
@@ -41,10 +45,23 @@ struct execute_work {
struct work_struct work;
};
+#ifdef CONFIG_LOCKDEP
+/*
+ * NB: because we have to copy the lockdep_map, setting _key
+ * here is required, otherwise it could get initialised to the
+ * copy of the lockdep_map!
+ */
+#define __WORK_INIT_LOCKDEP_MAP(n, k) \
+ .lockdep_map = STATIC_LOCKDEP_MAP_INIT(n, k),
+#else
+#define __WORK_INIT_LOCKDEP_MAP(n, k)
+#endif
+
#define __WORK_INITIALIZER(n, f) { \
.data = WORK_DATA_INIT(), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
+ __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \
}
#define __DELAYED_WORK_INITIALIZER(n, f) { \
@@ -76,12 +93,24 @@ struct execute_work {
* assignment of the work data initializer allows the compiler
* to generate better code.
*/
+#ifdef CONFIG_LOCKDEP
+#define INIT_WORK(_work, _func) \
+ do { \
+ static struct lock_class_key __key; \
+ \
+ (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
+ lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\
+ INIT_LIST_HEAD(&(_work)->entry); \
+ PREPARE_WORK((_work), (_func)); \
+ } while (0)
+#else
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
+#endif
#define INIT_DELAYED_WORK(_work, _func) \
do { \
@@ -118,9 +147,23 @@ struct execute_work {
clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))
-extern struct workqueue_struct *__create_workqueue(const char *name,
- int singlethread,
- int freezeable);
+extern struct workqueue_struct *
+__create_workqueue_key(const char *name, int singlethread,
+ int freezeable, struct lock_class_key *key);
+
+#ifdef CONFIG_LOCKDEP
+#define __create_workqueue(name, singlethread, freezeable) \
+({ \
+ static struct lock_class_key __key; \
+ \
+ __create_workqueue_key((name), (singlethread), \
+ (freezeable), &__key); \
+})
+#else
+#define __create_workqueue(name, singlethread, freezeable) \
+ __create_workqueue_key((name), (singlethread), (freezeable), NULL)
+#endif
+
#define create_workqueue(name) __create_workqueue((name), 0, 0)
#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1)
#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0)
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index e75d5e6c4ce..c544c6f9089 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -94,7 +94,6 @@ struct video_device
char name[32];
int type; /* v4l1 */
int type2; /* v4l2 */
- int hardware;
int minor;
int debug; /* Activates debug level*/
@@ -272,10 +271,6 @@ struct video_device
int (*vidioc_s_crop) (struct file *file, void *fh,
struct v4l2_crop *a);
/* Compression ioctls */
- int (*vidioc_g_mpegcomp) (struct file *file, void *fh,
- struct v4l2_mpeg_compression *a);
- int (*vidioc_s_mpegcomp) (struct file *file, void *fh,
- struct v4l2_mpeg_compression *a);
int (*vidioc_g_jpegcomp) (struct file *file, void *fh,
struct v4l2_jpegcompression *a);
int (*vidioc_s_jpegcomp) (struct file *file, void *fh,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 686425a97b0..625346c47ee 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -44,7 +44,7 @@ extern unsigned int p9_debug_level;
do { \
if ((p9_debug_level & level) == level) \
printk(KERN_NOTICE "-- %s (%d): " \
- format , __FUNCTION__, current->pid , ## arg); \
+ format , __FUNCTION__, task_pid_nr(current) , ## arg); \
} while (0)
#define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, \
@@ -59,7 +59,7 @@ do { \
#define P9_EPRINTK(level, format, arg...) \
do { \
printk(level "9p: %s (%d): " \
- format , __FUNCTION__, current->pid , ## arg); \
+ format , __FUNCTION__, task_pid_nr(current), ## arg); \
} while (0)
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ebfb96b4110..a8a9eb6af96 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -200,119 +200,18 @@ enum {
#define HCI_LM_SECURE 0x0020
/* ----- HCI Commands ---- */
-/* OGF & OCF values */
-
-/* Informational Parameters */
-#define OGF_INFO_PARAM 0x04
-
-#define OCF_READ_LOCAL_VERSION 0x0001
-struct hci_rp_read_loc_version {
- __u8 status;
- __u8 hci_ver;
- __le16 hci_rev;
- __u8 lmp_ver;
- __le16 manufacturer;
- __le16 lmp_subver;
-} __attribute__ ((packed));
-
-#define OCF_READ_LOCAL_FEATURES 0x0003
-struct hci_rp_read_local_features {
- __u8 status;
- __u8 features[8];
-} __attribute__ ((packed));
-
-#define OCF_READ_BUFFER_SIZE 0x0005
-struct hci_rp_read_buffer_size {
- __u8 status;
- __le16 acl_mtu;
- __u8 sco_mtu;
- __le16 acl_max_pkt;
- __le16 sco_max_pkt;
-} __attribute__ ((packed));
-
-#define OCF_READ_BD_ADDR 0x0009
-struct hci_rp_read_bd_addr {
- __u8 status;
- bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-/* Host Controller and Baseband */
-#define OGF_HOST_CTL 0x03
-#define OCF_RESET 0x0003
-#define OCF_READ_AUTH_ENABLE 0x001F
-#define OCF_WRITE_AUTH_ENABLE 0x0020
- #define AUTH_DISABLED 0x00
- #define AUTH_ENABLED 0x01
-
-#define OCF_READ_ENCRYPT_MODE 0x0021
-#define OCF_WRITE_ENCRYPT_MODE 0x0022
- #define ENCRYPT_DISABLED 0x00
- #define ENCRYPT_P2P 0x01
- #define ENCRYPT_BOTH 0x02
-
-#define OCF_WRITE_CA_TIMEOUT 0x0016
-#define OCF_WRITE_PG_TIMEOUT 0x0018
-
-#define OCF_WRITE_SCAN_ENABLE 0x001A
- #define SCAN_DISABLED 0x00
- #define SCAN_INQUIRY 0x01
- #define SCAN_PAGE 0x02
-
-#define OCF_SET_EVENT_FLT 0x0005
-struct hci_cp_set_event_flt {
- __u8 flt_type;
- __u8 cond_type;
- __u8 condition[0];
-} __attribute__ ((packed));
-
-/* Filter types */
-#define HCI_FLT_CLEAR_ALL 0x00
-#define HCI_FLT_INQ_RESULT 0x01
-#define HCI_FLT_CONN_SETUP 0x02
-
-/* CONN_SETUP Condition types */
-#define HCI_CONN_SETUP_ALLOW_ALL 0x00
-#define HCI_CONN_SETUP_ALLOW_CLASS 0x01
-#define HCI_CONN_SETUP_ALLOW_BDADDR 0x02
-
-/* CONN_SETUP Conditions */
-#define HCI_CONN_SETUP_AUTO_OFF 0x01
-#define HCI_CONN_SETUP_AUTO_ON 0x02
-
-#define OCF_READ_CLASS_OF_DEV 0x0023
-struct hci_rp_read_dev_class {
- __u8 status;
- __u8 dev_class[3];
-} __attribute__ ((packed));
-
-#define OCF_WRITE_CLASS_OF_DEV 0x0024
-struct hci_cp_write_dev_class {
- __u8 dev_class[3];
-} __attribute__ ((packed));
-
-#define OCF_READ_VOICE_SETTING 0x0025
-struct hci_rp_read_voice_setting {
- __u8 status;
- __le16 voice_setting;
+#define HCI_OP_INQUIRY 0x0401
+struct hci_cp_inquiry {
+ __u8 lap[3];
+ __u8 length;
+ __u8 num_rsp;
} __attribute__ ((packed));
-#define OCF_WRITE_VOICE_SETTING 0x0026
-struct hci_cp_write_voice_setting {
- __le16 voice_setting;
-} __attribute__ ((packed));
+#define HCI_OP_INQUIRY_CANCEL 0x0402
-#define OCF_HOST_BUFFER_SIZE 0x0033
-struct hci_cp_host_buffer_size {
- __le16 acl_mtu;
- __u8 sco_mtu;
- __le16 acl_max_pkt;
- __le16 sco_max_pkt;
-} __attribute__ ((packed));
-
-/* Link Control */
-#define OGF_LINK_CTL 0x01
+#define HCI_OP_EXIT_PERIODIC_INQ 0x0404
-#define OCF_CREATE_CONN 0x0005
+#define HCI_OP_CREATE_CONN 0x0405
struct hci_cp_create_conn {
bdaddr_t bdaddr;
__le16 pkt_type;
@@ -322,105 +221,138 @@ struct hci_cp_create_conn {
__u8 role_switch;
} __attribute__ ((packed));
-#define OCF_CREATE_CONN_CANCEL 0x0008
-struct hci_cp_create_conn_cancel {
- bdaddr_t bdaddr;
-} __attribute__ ((packed));
-
-#define OCF_ACCEPT_CONN_REQ 0x0009
-struct hci_cp_accept_conn_req {
- bdaddr_t bdaddr;
- __u8 role;
-} __attribute__ ((packed));
-
-#define OCF_REJECT_CONN_REQ 0x000a
-struct hci_cp_reject_conn_req {
- bdaddr_t bdaddr;
- __u8 reason;
-} __attribute__ ((packed));
-
-#define OCF_DISCONNECT 0x0006
+#define HCI_OP_DISCONNECT 0x0406
struct hci_cp_disconnect {
__le16 handle;
__u8 reason;
} __attribute__ ((packed));
-#define OCF_ADD_SCO 0x0007
+#define HCI_OP_ADD_SCO 0x0407
struct hci_cp_add_sco {
__le16 handle;
__le16 pkt_type;
} __attribute__ ((packed));
-#define OCF_INQUIRY 0x0001
-struct hci_cp_inquiry {
- __u8 lap[3];
- __u8 length;
- __u8 num_rsp;
+#define HCI_OP_CREATE_CONN_CANCEL 0x0408
+struct hci_cp_create_conn_cancel {
+ bdaddr_t bdaddr;
} __attribute__ ((packed));
-#define OCF_INQUIRY_CANCEL 0x0002
+#define HCI_OP_ACCEPT_CONN_REQ 0x0409
+struct hci_cp_accept_conn_req {
+ bdaddr_t bdaddr;
+ __u8 role;
+} __attribute__ ((packed));
-#define OCF_EXIT_PERIODIC_INQ 0x0004
+#define HCI_OP_REJECT_CONN_REQ 0x040a
+struct hci_cp_reject_conn_req {
+ bdaddr_t bdaddr;
+ __u8 reason;
+} __attribute__ ((packed));
-#define OCF_LINK_KEY_REPLY 0x000B
+#define HCI_OP_LINK_KEY_REPLY 0x040b
struct hci_cp_link_key_reply {
bdaddr_t bdaddr;
__u8 link_key[16];
} __attribute__ ((packed));
-#define OCF_LINK_KEY_NEG_REPLY 0x000C
+#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c
struct hci_cp_link_key_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
-#define OCF_PIN_CODE_REPLY 0x000D
+#define HCI_OP_PIN_CODE_REPLY 0x040d
struct hci_cp_pin_code_reply {
bdaddr_t bdaddr;
__u8 pin_len;
__u8 pin_code[16];
} __attribute__ ((packed));
-#define OCF_PIN_CODE_NEG_REPLY 0x000E
+#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e
struct hci_cp_pin_code_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
-#define OCF_CHANGE_CONN_PTYPE 0x000F
+#define HCI_OP_CHANGE_CONN_PTYPE 0x040f
struct hci_cp_change_conn_ptype {
__le16 handle;
__le16 pkt_type;
} __attribute__ ((packed));
-#define OCF_AUTH_REQUESTED 0x0011
+#define HCI_OP_AUTH_REQUESTED 0x0411
struct hci_cp_auth_requested {
__le16 handle;
} __attribute__ ((packed));
-#define OCF_SET_CONN_ENCRYPT 0x0013
+#define HCI_OP_SET_CONN_ENCRYPT 0x0413
struct hci_cp_set_conn_encrypt {
__le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
-#define OCF_CHANGE_CONN_LINK_KEY 0x0015
+#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415
struct hci_cp_change_conn_link_key {
__le16 handle;
} __attribute__ ((packed));
-#define OCF_READ_REMOTE_FEATURES 0x001B
+#define HCI_OP_REMOTE_NAME_REQ 0x0419
+struct hci_cp_remote_name_req {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+ __u8 pscan_mode;
+ __le16 clock_offset;
+} __attribute__ ((packed));
+
+#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a
+struct hci_cp_remote_name_req_cancel {
+ bdaddr_t bdaddr;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_FEATURES 0x041b
struct hci_cp_read_remote_features {
__le16 handle;
} __attribute__ ((packed));
-#define OCF_READ_REMOTE_VERSION 0x001D
+#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c
+struct hci_cp_read_remote_ext_features {
+ __le16 handle;
+ __u8 page;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_REMOTE_VERSION 0x041d
struct hci_cp_read_remote_version {
__le16 handle;
} __attribute__ ((packed));
-/* Link Policy */
-#define OGF_LINK_POLICY 0x02
+#define HCI_OP_SETUP_SYNC_CONN 0x0428
+struct hci_cp_setup_sync_conn {
+ __le16 handle;
+ __le32 tx_bandwidth;
+ __le32 rx_bandwidth;
+ __le16 max_latency;
+ __le16 voice_setting;
+ __u8 retrans_effort;
+ __le16 pkt_type;
+} __attribute__ ((packed));
-#define OCF_SNIFF_MODE 0x0003
+#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429
+struct hci_cp_accept_sync_conn_req {
+ bdaddr_t bdaddr;
+ __le32 tx_bandwidth;
+ __le32 rx_bandwidth;
+ __le16 max_latency;
+ __le16 content_format;
+ __u8 retrans_effort;
+ __le16 pkt_type;
+} __attribute__ ((packed));
+
+#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a
+struct hci_cp_reject_sync_conn_req {
+ bdaddr_t bdaddr;
+ __u8 reason;
+} __attribute__ ((packed));
+
+#define HCI_OP_SNIFF_MODE 0x0803
struct hci_cp_sniff_mode {
__le16 handle;
__le16 max_interval;
@@ -429,12 +361,12 @@ struct hci_cp_sniff_mode {
__le16 timeout;
} __attribute__ ((packed));
-#define OCF_EXIT_SNIFF_MODE 0x0004
+#define HCI_OP_EXIT_SNIFF_MODE 0x0804
struct hci_cp_exit_sniff_mode {
__le16 handle;
} __attribute__ ((packed));
-#define OCF_ROLE_DISCOVERY 0x0009
+#define HCI_OP_ROLE_DISCOVERY 0x0809
struct hci_cp_role_discovery {
__le16 handle;
} __attribute__ ((packed));
@@ -444,7 +376,13 @@ struct hci_rp_role_discovery {
__u8 role;
} __attribute__ ((packed));
-#define OCF_READ_LINK_POLICY 0x000C
+#define HCI_OP_SWITCH_ROLE 0x080b
+struct hci_cp_switch_role {
+ bdaddr_t bdaddr;
+ __u8 role;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LINK_POLICY 0x080c
struct hci_cp_read_link_policy {
__le16 handle;
} __attribute__ ((packed));
@@ -454,13 +392,7 @@ struct hci_rp_read_link_policy {
__le16 policy;
} __attribute__ ((packed));
-#define OCF_SWITCH_ROLE 0x000B
-struct hci_cp_switch_role {
- bdaddr_t bdaddr;
- __u8 role;
-} __attribute__ ((packed));
-
-#define OCF_WRITE_LINK_POLICY 0x000D
+#define HCI_OP_WRITE_LINK_POLICY 0x080d
struct hci_cp_write_link_policy {
__le16 handle;
__le16 policy;
@@ -470,7 +402,7 @@ struct hci_rp_write_link_policy {
__le16 handle;
} __attribute__ ((packed));
-#define OCF_SNIFF_SUBRATE 0x0011
+#define HCI_OP_SNIFF_SUBRATE 0x0811
struct hci_cp_sniff_subrate {
__le16 handle;
__le16 max_latency;
@@ -478,59 +410,156 @@ struct hci_cp_sniff_subrate {
__le16 min_local_timeout;
} __attribute__ ((packed));
-/* Status params */
-#define OGF_STATUS_PARAM 0x05
+#define HCI_OP_SET_EVENT_MASK 0x0c01
+struct hci_cp_set_event_mask {
+ __u8 mask[8];
+} __attribute__ ((packed));
-/* Testing commands */
-#define OGF_TESTING_CMD 0x3E
+#define HCI_OP_RESET 0x0c03
-/* Vendor specific commands */
-#define OGF_VENDOR_CMD 0x3F
+#define HCI_OP_SET_EVENT_FLT 0x0c05
+struct hci_cp_set_event_flt {
+ __u8 flt_type;
+ __u8 cond_type;
+ __u8 condition[0];
+} __attribute__ ((packed));
-/* ---- HCI Events ---- */
-#define HCI_EV_INQUIRY_COMPLETE 0x01
+/* Filter types */
+#define HCI_FLT_CLEAR_ALL 0x00
+#define HCI_FLT_INQ_RESULT 0x01
+#define HCI_FLT_CONN_SETUP 0x02
-#define HCI_EV_INQUIRY_RESULT 0x02
-struct inquiry_info {
- bdaddr_t bdaddr;
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
+/* CONN_SETUP Condition types */
+#define HCI_CONN_SETUP_ALLOW_ALL 0x00
+#define HCI_CONN_SETUP_ALLOW_CLASS 0x01
+#define HCI_CONN_SETUP_ALLOW_BDADDR 0x02
+
+/* CONN_SETUP Conditions */
+#define HCI_CONN_SETUP_AUTO_OFF 0x01
+#define HCI_CONN_SETUP_AUTO_ON 0x02
+
+#define HCI_OP_WRITE_LOCAL_NAME 0x0c13
+struct hci_cp_write_local_name {
+ __u8 name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_NAME 0x0c14
+struct hci_rp_read_local_name {
+ __u8 status;
+ __u8 name[248];
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_CA_TIMEOUT 0x0c16
+
+#define HCI_OP_WRITE_PG_TIMEOUT 0x0c18
+
+#define HCI_OP_WRITE_SCAN_ENABLE 0x0c1a
+ #define SCAN_DISABLED 0x00
+ #define SCAN_INQUIRY 0x01
+ #define SCAN_PAGE 0x02
+
+#define HCI_OP_READ_AUTH_ENABLE 0x0c1f
+
+#define HCI_OP_WRITE_AUTH_ENABLE 0x0c20
+ #define AUTH_DISABLED 0x00
+ #define AUTH_ENABLED 0x01
+
+#define HCI_OP_READ_ENCRYPT_MODE 0x0c21
+
+#define HCI_OP_WRITE_ENCRYPT_MODE 0x0c22
+ #define ENCRYPT_DISABLED 0x00
+ #define ENCRYPT_P2P 0x01
+ #define ENCRYPT_BOTH 0x02
+
+#define HCI_OP_READ_CLASS_OF_DEV 0x0c23
+struct hci_rp_read_class_of_dev {
+ __u8 status;
__u8 dev_class[3];
- __le16 clock_offset;
} __attribute__ ((packed));
-#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
-struct inquiry_info_with_rssi {
- bdaddr_t bdaddr;
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
+#define HCI_OP_WRITE_CLASS_OF_DEV 0x0c24
+struct hci_cp_write_class_of_dev {
__u8 dev_class[3];
- __le16 clock_offset;
- __s8 rssi;
} __attribute__ ((packed));
-struct inquiry_info_with_rssi_and_pscan_mode {
+
+#define HCI_OP_READ_VOICE_SETTING 0x0c25
+struct hci_rp_read_voice_setting {
+ __u8 status;
+ __le16 voice_setting;
+} __attribute__ ((packed));
+
+#define HCI_OP_WRITE_VOICE_SETTING 0x0c26
+struct hci_cp_write_voice_setting {
+ __le16 voice_setting;
+} __attribute__ ((packed));
+
+#define HCI_OP_HOST_BUFFER_SIZE 0x0c33
+struct hci_cp_host_buffer_size {
+ __le16 acl_mtu;
+ __u8 sco_mtu;
+ __le16 acl_max_pkt;
+ __le16 sco_max_pkt;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_VERSION 0x1001
+struct hci_rp_read_local_version {
+ __u8 status;
+ __u8 hci_ver;
+ __le16 hci_rev;
+ __u8 lmp_ver;
+ __le16 manufacturer;
+ __le16 lmp_subver;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_COMMANDS 0x1002
+struct hci_rp_read_local_commands {
+ __u8 status;
+ __u8 commands[64];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_FEATURES 0x1003
+struct hci_rp_read_local_features {
+ __u8 status;
+ __u8 features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_LOCAL_EXT_FEATURES 0x1004
+struct hci_rp_read_local_ext_features {
+ __u8 status;
+ __u8 page;
+ __u8 max_page;
+ __u8 features[8];
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BUFFER_SIZE 0x1005
+struct hci_rp_read_buffer_size {
+ __u8 status;
+ __le16 acl_mtu;
+ __u8 sco_mtu;
+ __le16 acl_max_pkt;
+ __le16 sco_max_pkt;
+} __attribute__ ((packed));
+
+#define HCI_OP_READ_BD_ADDR 0x1009
+struct hci_rp_read_bd_addr {
+ __u8 status;
bdaddr_t bdaddr;
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
- __u8 dev_class[3];
- __le16 clock_offset;
- __s8 rssi;
} __attribute__ ((packed));
-#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2F
-struct extended_inquiry_info {
+/* ---- HCI Events ---- */
+#define HCI_EV_INQUIRY_COMPLETE 0x01
+
+#define HCI_EV_INQUIRY_RESULT 0x02
+struct inquiry_info {
bdaddr_t bdaddr;
__u8 pscan_rep_mode;
__u8 pscan_period_mode;
+ __u8 pscan_mode;
__u8 dev_class[3];
__le16 clock_offset;
- __s8 rssi;
- __u8 data[240];
} __attribute__ ((packed));
-#define HCI_EV_CONN_COMPLETE 0x03
+#define HCI_EV_CONN_COMPLETE 0x03
struct hci_ev_conn_complete {
__u8 status;
__le16 handle;
@@ -539,40 +568,63 @@ struct hci_ev_conn_complete {
__u8 encr_mode;
} __attribute__ ((packed));
-#define HCI_EV_CONN_REQUEST 0x04
+#define HCI_EV_CONN_REQUEST 0x04
struct hci_ev_conn_request {
bdaddr_t bdaddr;
__u8 dev_class[3];
__u8 link_type;
} __attribute__ ((packed));
-#define HCI_EV_DISCONN_COMPLETE 0x05
+#define HCI_EV_DISCONN_COMPLETE 0x05
struct hci_ev_disconn_complete {
__u8 status;
__le16 handle;
__u8 reason;
} __attribute__ ((packed));
-#define HCI_EV_AUTH_COMPLETE 0x06
+#define HCI_EV_AUTH_COMPLETE 0x06
struct hci_ev_auth_complete {
__u8 status;
__le16 handle;
} __attribute__ ((packed));
-#define HCI_EV_ENCRYPT_CHANGE 0x08
+#define HCI_EV_REMOTE_NAME 0x07
+struct hci_ev_remote_name {
+ __u8 status;
+ bdaddr_t bdaddr;
+ __u8 name[248];
+} __attribute__ ((packed));
+
+#define HCI_EV_ENCRYPT_CHANGE 0x08
struct hci_ev_encrypt_change {
__u8 status;
__le16 handle;
__u8 encrypt;
} __attribute__ ((packed));
-#define HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE 0x09
-struct hci_ev_change_conn_link_key_complete {
+#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09
+struct hci_ev_change_link_key_complete {
+ __u8 status;
+ __le16 handle;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_FEATURES 0x0b
+struct hci_ev_remote_features {
+ __u8 status;
+ __le16 handle;
+ __u8 features[8];
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_VERSION 0x0c
+struct hci_ev_remote_version {
__u8 status;
__le16 handle;
+ __u8 lmp_ver;
+ __le16 manufacturer;
+ __le16 lmp_subver;
} __attribute__ ((packed));
-#define HCI_EV_QOS_SETUP_COMPLETE 0x0D
+#define HCI_EV_QOS_SETUP_COMPLETE 0x0d
struct hci_qos {
__u8 service_type;
__u32 token_rate;
@@ -586,33 +638,33 @@ struct hci_ev_qos_setup_complete {
struct hci_qos qos;
} __attribute__ ((packed));
-#define HCI_EV_CMD_COMPLETE 0x0E
+#define HCI_EV_CMD_COMPLETE 0x0e
struct hci_ev_cmd_complete {
__u8 ncmd;
__le16 opcode;
} __attribute__ ((packed));
-#define HCI_EV_CMD_STATUS 0x0F
+#define HCI_EV_CMD_STATUS 0x0f
struct hci_ev_cmd_status {
__u8 status;
__u8 ncmd;
__le16 opcode;
} __attribute__ ((packed));
-#define HCI_EV_NUM_COMP_PKTS 0x13
-struct hci_ev_num_comp_pkts {
- __u8 num_hndl;
- /* variable length part */
-} __attribute__ ((packed));
-
-#define HCI_EV_ROLE_CHANGE 0x12
+#define HCI_EV_ROLE_CHANGE 0x12
struct hci_ev_role_change {
__u8 status;
bdaddr_t bdaddr;
__u8 role;
} __attribute__ ((packed));
-#define HCI_EV_MODE_CHANGE 0x14
+#define HCI_EV_NUM_COMP_PKTS 0x13
+struct hci_ev_num_comp_pkts {
+ __u8 num_hndl;
+ /* variable length part */
+} __attribute__ ((packed));
+
+#define HCI_EV_MODE_CHANGE 0x14
struct hci_ev_mode_change {
__u8 status;
__le16 handle;
@@ -620,53 +672,88 @@ struct hci_ev_mode_change {
__le16 interval;
} __attribute__ ((packed));
-#define HCI_EV_PIN_CODE_REQ 0x16
+#define HCI_EV_PIN_CODE_REQ 0x16
struct hci_ev_pin_code_req {
bdaddr_t bdaddr;
} __attribute__ ((packed));
-#define HCI_EV_LINK_KEY_REQ 0x17
+#define HCI_EV_LINK_KEY_REQ 0x17
struct hci_ev_link_key_req {
bdaddr_t bdaddr;
} __attribute__ ((packed));
-#define HCI_EV_LINK_KEY_NOTIFY 0x18
+#define HCI_EV_LINK_KEY_NOTIFY 0x18
struct hci_ev_link_key_notify {
bdaddr_t bdaddr;
- __u8 link_key[16];
- __u8 key_type;
+ __u8 link_key[16];
+ __u8 key_type;
} __attribute__ ((packed));
-#define HCI_EV_REMOTE_FEATURES 0x0B
-struct hci_ev_remote_features {
+#define HCI_EV_CLOCK_OFFSET 0x1c
+struct hci_ev_clock_offset {
__u8 status;
__le16 handle;
- __u8 features[8];
+ __le16 clock_offset;
} __attribute__ ((packed));
-#define HCI_EV_REMOTE_VERSION 0x0C
-struct hci_ev_remote_version {
+#define HCI_EV_PSCAN_REP_MODE 0x20
+struct hci_ev_pscan_rep_mode {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+} __attribute__ ((packed));
+
+#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22
+struct inquiry_info_with_rssi {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+ __u8 pscan_period_mode;
+ __u8 dev_class[3];
+ __le16 clock_offset;
+ __s8 rssi;
+} __attribute__ ((packed));
+struct inquiry_info_with_rssi_and_pscan_mode {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+ __u8 pscan_period_mode;
+ __u8 pscan_mode;
+ __u8 dev_class[3];
+ __le16 clock_offset;
+ __s8 rssi;
+} __attribute__ ((packed));
+
+#define HCI_EV_REMOTE_EXT_FEATURES 0x23
+struct hci_ev_remote_ext_features {
__u8 status;
__le16 handle;
- __u8 lmp_ver;
- __le16 manufacturer;
- __le16 lmp_subver;
+ __u8 page;
+ __u8 max_page;
+ __u8 features[8];
} __attribute__ ((packed));
-#define HCI_EV_CLOCK_OFFSET 0x01C
-struct hci_ev_clock_offset {
+#define HCI_EV_SYNC_CONN_COMPLETE 0x2c
+struct hci_ev_sync_conn_complete {
__u8 status;
__le16 handle;
- __le16 clock_offset;
+ bdaddr_t bdaddr;
+ __u8 link_type;
+ __u8 tx_interval;
+ __u8 retrans_window;
+ __le16 rx_pkt_len;
+ __le16 tx_pkt_len;
+ __u8 air_mode;
} __attribute__ ((packed));
-#define HCI_EV_PSCAN_REP_MODE 0x20
-struct hci_ev_pscan_rep_mode {
- bdaddr_t bdaddr;
- __u8 pscan_rep_mode;
+#define HCI_EV_SYNC_CONN_CHANGED 0x2d
+struct hci_ev_sync_conn_changed {
+ __u8 status;
+ __le16 handle;
+ __u8 tx_interval;
+ __u8 retrans_window;
+ __le16 rx_pkt_len;
+ __le16 tx_pkt_len;
} __attribute__ ((packed));
-#define HCI_EV_SNIFF_SUBRATE 0x2E
+#define HCI_EV_SNIFF_SUBRATE 0x2e
struct hci_ev_sniff_subrate {
__u8 status;
__le16 handle;
@@ -676,14 +763,25 @@ struct hci_ev_sniff_subrate {
__le16 max_local_timeout;
} __attribute__ ((packed));
+#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f
+struct extended_inquiry_info {
+ bdaddr_t bdaddr;
+ __u8 pscan_rep_mode;
+ __u8 pscan_period_mode;
+ __u8 dev_class[3];
+ __le16 clock_offset;
+ __s8 rssi;
+ __u8 data[240];
+} __attribute__ ((packed));
+
/* Internal events generated by Bluetooth stack */
-#define HCI_EV_STACK_INTERNAL 0xFD
+#define HCI_EV_STACK_INTERNAL 0xfd
struct hci_ev_stack_internal {
__u16 type;
__u8 data[0];
} __attribute__ ((packed));
-#define HCI_EV_SI_DEVICE 0x01
+#define HCI_EV_SI_DEVICE 0x01
struct hci_ev_si_device {
__u16 event;
__u16 dev_id;
@@ -704,40 +802,40 @@ struct hci_ev_si_security {
#define HCI_SCO_HDR_SIZE 3
struct hci_command_hdr {
- __le16 opcode; /* OCF & OGF */
+ __le16 opcode; /* OCF & OGF */
__u8 plen;
} __attribute__ ((packed));
struct hci_event_hdr {
- __u8 evt;
- __u8 plen;
+ __u8 evt;
+ __u8 plen;
} __attribute__ ((packed));
struct hci_acl_hdr {
- __le16 handle; /* Handle & Flags(PB, BC) */
- __le16 dlen;
+ __le16 handle; /* Handle & Flags(PB, BC) */
+ __le16 dlen;
} __attribute__ ((packed));
struct hci_sco_hdr {
- __le16 handle;
- __u8 dlen;
+ __le16 handle;
+ __u8 dlen;
} __attribute__ ((packed));
#ifdef __KERNEL__
#include <linux/skbuff.h>
static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb)
{
- return (struct hci_event_hdr *)skb->data;
+ return (struct hci_event_hdr *) skb->data;
}
static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb)
{
- return (struct hci_acl_hdr *)skb->data;
+ return (struct hci_acl_hdr *) skb->data;
}
static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb)
{
- return (struct hci_sco_hdr *)skb->data;
+ return (struct hci_sco_hdr *) skb->data;
}
#endif
@@ -771,13 +869,13 @@ struct sockaddr_hci {
struct hci_filter {
unsigned long type_mask;
unsigned long event_mask[2];
- __le16 opcode;
+ __le16 opcode;
};
struct hci_ufilter {
- __u32 type_mask;
- __u32 event_mask[2];
- __le16 opcode;
+ __u32 type_mask;
+ __u32 event_mask[2];
+ __le16 opcode;
};
#define HCI_FLT_TYPE_BITS 31
@@ -825,15 +923,15 @@ struct hci_dev_info {
struct hci_conn_info {
__u16 handle;
bdaddr_t bdaddr;
- __u8 type;
- __u8 out;
- __u16 state;
- __u32 link_mode;
+ __u8 type;
+ __u8 out;
+ __u16 state;
+ __u32 link_mode;
};
struct hci_dev_req {
- __u16 dev_id;
- __u32 dev_opt;
+ __u16 dev_id;
+ __u32 dev_opt;
};
struct hci_dev_list_req {
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8f67c8a7169..ea13baa3851 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -71,7 +71,10 @@ struct hci_dev {
__u16 id;
__u8 type;
bdaddr_t bdaddr;
+ __u8 dev_name[248];
+ __u8 dev_class[3];
__u8 features[8];
+ __u8 commands[64];
__u8 hci_ver;
__u16 hci_rev;
__u16 manufacturer;
@@ -310,10 +313,12 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev,
void hci_acl_connect(struct hci_conn *conn);
void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
void hci_add_sco(struct hci_conn *conn, __u16 handle);
+void hci_setup_sync(struct hci_conn *conn, __u16 handle);
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-int hci_conn_del(struct hci_conn *conn);
-void hci_conn_hash_flush(struct hci_dev *hdev);
+int hci_conn_del(struct hci_conn *conn);
+void hci_conn_hash_flush(struct hci_dev *hdev);
+void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
int hci_conn_auth(struct hci_conn *conn);
@@ -617,11 +622,11 @@ int hci_unregister_cb(struct hci_cb *hcb);
int hci_register_notifier(struct notifier_block *nb);
int hci_unregister_notifier(struct notifier_block *nb);
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param);
int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode);
void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 70e70f5d3dd..73e115bc12d 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -29,7 +29,8 @@
#define L2CAP_DEFAULT_MTU 672
#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-#define L2CAP_CONN_TIMEOUT (HZ * 40)
+#define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */
+#define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */
/* L2CAP socket address */
struct sockaddr_l2 {
@@ -148,6 +149,19 @@ struct l2cap_conf_opt {
#define L2CAP_CONF_MAX_SIZE 22
+struct l2cap_conf_rfc {
+ __u8 mode;
+ __u8 txwin_size;
+ __u8 max_transmit;
+ __le16 retrans_timeout;
+ __le16 monitor_timeout;
+ __le16 max_pdu_size;
+} __attribute__ ((packed));
+
+#define L2CAP_MODE_BASIC 0x00
+#define L2CAP_MODE_RETRANS 0x01
+#define L2CAP_MODE_FLOWCTL 0x02
+
struct l2cap_disconn_req {
__le16 dcid;
__le16 scid;
@@ -160,7 +174,6 @@ struct l2cap_disconn_rsp {
struct l2cap_info_req {
__le16 type;
- __u8 data[0];
} __attribute__ ((packed));
struct l2cap_info_rsp {
@@ -192,6 +205,13 @@ struct l2cap_conn {
unsigned int mtu;
+ __u32 feat_mask;
+
+ __u8 info_state;
+ __u8 info_ident;
+
+ struct timer_list info_timer;
+
spinlock_t lock;
struct sk_buff *rx_skb;
@@ -202,6 +222,9 @@ struct l2cap_conn {
struct l2cap_chan_list chan_list;
};
+#define L2CAP_INFO_CL_MTU_REQ_SENT 0x01
+#define L2CAP_INFO_FEAT_MASK_REQ_SENT 0x02
+
/* ----- L2CAP channel and socket info ----- */
#define l2cap_pi(sk) ((struct l2cap_pinfo *) sk)
@@ -221,7 +244,6 @@ struct l2cap_pinfo {
__u8 conf_len;
__u8 conf_state;
__u8 conf_retry;
- __u16 conf_mtu;
__u8 ident;
@@ -232,10 +254,11 @@ struct l2cap_pinfo {
struct sock *prev_c;
};
-#define L2CAP_CONF_REQ_SENT 0x01
-#define L2CAP_CONF_INPUT_DONE 0x02
-#define L2CAP_CONF_OUTPUT_DONE 0x04
-#define L2CAP_CONF_MAX_RETRIES 2
+#define L2CAP_CONF_REQ_SENT 0x01
+#define L2CAP_CONF_INPUT_DONE 0x02
+#define L2CAP_CONF_OUTPUT_DONE 0x04
+
+#define L2CAP_CONF_MAX_RETRIES 2
void l2cap_load(void);
diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h
index cf80c1af585..32c385dd9e0 100644
--- a/include/net/irda/irttp.h
+++ b/include/net/irda/irttp.h
@@ -56,7 +56,7 @@
/* Receive queue sizes */
/* Minimum of credit that the peer should hold.
- * If the peer has less credits than 9 frames, we will explicitely send
+ * If the peer has less credits than 9 frames, we will explicitly send
* him some credits (through irttp_give_credit() and a specific frame).
* Note that when we give credits it's likely that it won't be sent in
* this LAP window, but in the next one. So, we make sure that the peer
@@ -66,7 +66,7 @@
/* This is the default maximum number of credits held by the peer, so the
* default maximum number of frames he can send us before needing flow
* control answer from us (this may be negociated differently at TSAP setup).
- * We want to minimise the number of times we have to explicitely send some
+ * We want to minimise the number of times we have to explicitly send some
* credit to the peer, hoping we can piggyback it on the return data. In
* particular, it doesn't make sense for us to send credit more than once
* per LAP window.
diff --git a/include/net/scm.h b/include/net/scm.h
index 423cb1d5ac2..06df126103c 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -4,6 +4,8 @@
#include <linux/limits.h>
#include <linux/net.h>
#include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
/* Well, we should have at least one descriptor open
* to accept passed FDs 8)
@@ -54,7 +56,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
struct task_struct *p = current;
scm->creds.uid = p->uid;
scm->creds.gid = p->gid;
- scm->creds.pid = p->tgid;
+ scm->creds.pid = task_tgid_vnr(p);
scm->fp = NULL;
scm->seq = 0;
unix_get_peersec_dgram(sock, scm);
diff --git a/include/video/sstfb.h b/include/video/sstfb.h
index baa163f770a..b52f0738124 100644
--- a/include/video/sstfb.h
+++ b/include/video/sstfb.h
@@ -68,7 +68,6 @@
# define print_var(X,Y...)
#endif
-#define BIT(x) (1ul<<(x))
#define POW2(x) (1ul<<(x))
/*
diff --git a/include/video/tdfx.h b/include/video/tdfx.h
index 05b63c2a5ab..7431d9681e5 100644
--- a/include/video/tdfx.h
+++ b/include/video/tdfx.h
@@ -79,8 +79,6 @@
/* register bitfields (not all, only as needed) */
-#define BIT(x) (1UL << (x))
-
/* COMMAND_2D reg. values */
#define TDFX_ROP_COPY 0xcc /* src */
#define TDFX_ROP_INVERT 0x55 /* NOT dst */
diff --git a/init/Kconfig b/init/Kconfig
index a29a688c47d..b7dffa83792 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -234,6 +234,10 @@ config AUDITSYSCALL
such as SELinux. To use audit's filesystem watch feature, please
ensure that INOTIFY is configured.
+config AUDIT_TREE
+ def_bool y
+ depends on AUDITSYSCALL && INOTIFY
+
config IKCONFIG
tristate "Kernel .config support"
---help---
@@ -270,9 +274,43 @@ config LOG_BUF_SHIFT
13 => 8 KB
12 => 4 KB
+config CGROUPS
+ bool "Control Group support"
+ help
+ This option will let you use process cgroup subsystems
+ such as Cpusets
+
+ Say N if unsure.
+
+config CGROUP_DEBUG
+ bool "Example debug cgroup subsystem"
+ depends on CGROUPS
+ help
+ This option enables a simple cgroup subsystem that
+ exports useful debugging information about the cgroups
+ framework
+
+ Say N if unsure
+
+config CGROUP_NS
+ bool "Namespace cgroup subsystem"
+ depends on CGROUPS
+ help
+ Provides a simple namespace cgroup subsystem to
+ provide hierarchical naming of sets of namespaces,
+ for instance virtual servers and checkpoint/restart
+ jobs.
+
+config CGROUP_CPUACCT
+ bool "Simple CPU accounting cgroup subsystem"
+ depends on CGROUPS
+ help
+ Provides a simple Resource Controller for monitoring the
+ total CPU consumed by the tasks in a cgroup
+
config CPUSETS
bool "Cpuset support"
- depends on SMP
+ depends on SMP && CGROUPS
help
This option will let you create and manage CPUSETs which
allow dynamically partitioning a system into sets of CPUs and
@@ -300,6 +338,16 @@ config FAIR_USER_SCHED
This option will choose userid as the basis for grouping
tasks, thus providing equal CPU bandwidth to each user.
+config FAIR_CGROUP_SCHED
+ bool "Control groups"
+ depends on CGROUPS
+ help
+ This option allows you to create arbitrary task groups
+ using the "cgroup" pseudo filesystem and control
+ the cpu bandwidth allocated to each such task group.
+ Refer to Documentation/cgroups.txt for more information
+ on "cgroup" pseudo filesystem.
+
endchoice
config SYSFS_DEPRECATED
@@ -322,6 +370,11 @@ config SYSFS_DEPRECATED
If you are using a distro that was released in 2006 or later,
it should be safe to say N here.
+config PROC_PID_CPUSET
+ bool "Include legacy /proc/<pid>/cpuset file"
+ depends on CPUSETS
+ default y
+
config RELAY
bool "Kernel->user space relay support (formerly relayfs)"
help
diff --git a/init/main.c b/init/main.c
index 9def935ab13..f605a969ea6 100644
--- a/init/main.c
+++ b/init/main.c
@@ -39,6 +39,7 @@
#include <linux/writeback.h>
#include <linux/cpu.h>
#include <linux/cpuset.h>
+#include <linux/cgroup.h>
#include <linux/efi.h>
#include <linux/tick.h>
#include <linux/interrupt.h>
@@ -69,15 +70,7 @@
/*
* This is one of the first .c files built. Error out early if we have compiler
* trouble.
- *
- * Versions of gcc older than that listed below may actually compile and link
- * okay, but the end product can have subtle run time bugs. To avoid associated
- * bogus bug reports, we flatly refuse to compile with a gcc that is known to be
- * too old from the very beginning.
*/
-#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 2)
-#error Sorry, your GCC is too old. It builds incorrect kernels.
-#endif
#if __GNUC__ == 4 && __GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ == 0
#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
@@ -287,7 +280,7 @@ static int __init unknown_bootoption(char *param, char *val)
return 0;
/*
- * Preemptive maintenance for "why didn't my mispelled command
+ * Preemptive maintenance for "why didn't my misspelled command
* line work?"
*/
if (strchr(param, '.') && (!val || strchr(param, '.') < val)) {
@@ -523,6 +516,7 @@ asmlinkage void __init start_kernel(void)
*/
unwind_init();
lockdep_init();
+ cgroup_init_early();
local_irq_disable();
early_boot_irqs_off();
@@ -640,6 +634,7 @@ asmlinkage void __init start_kernel(void)
#ifdef CONFIG_PROC_FS
proc_root_init();
#endif
+ cgroup_init();
cpuset_init();
taskstats_init_early();
delayacct_init();
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 20f1fed8fa4..bfa274ba9ed 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -29,6 +29,8 @@
#include <linux/audit.h>
#include <linux/signal.h>
#include <linux/mutex.h>
+#include <linux/nsproxy.h>
+#include <linux/pid.h>
#include <net/sock.h>
#include "util.h"
@@ -330,7 +332,8 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data,
(info->notify_owner &&
info->notify.sigev_notify == SIGEV_SIGNAL) ?
info->notify.sigev_signo : 0,
- pid_nr(info->notify_owner));
+ pid_nr_ns(info->notify_owner,
+ current->nsproxy->pid_ns));
spin_unlock(&info->lock);
buffer[sizeof(buffer)-1] = '\0';
slen = strlen(buffer)+1;
@@ -507,7 +510,7 @@ static void __do_notify(struct mqueue_inode_info *info)
sig_i.si_errno = 0;
sig_i.si_code = SI_MESGQ;
sig_i.si_value = info->notify.sigev_value;
- sig_i.si_pid = current->tgid;
+ sig_i.si_pid = task_pid_vnr(current);
sig_i.si_uid = current->uid;
kill_pid_info(info->notify.sigev_signo,
@@ -673,7 +676,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
if (oflag & O_CREAT) {
if (dentry->d_inode) { /* entry already exists */
- audit_inode(name, dentry->d_inode);
+ audit_inode(name, dentry);
error = -EEXIST;
if (oflag & O_EXCL)
goto out;
@@ -686,7 +689,7 @@ asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode,
error = -ENOENT;
if (!dentry->d_inode)
goto out;
- audit_inode(name, dentry->d_inode);
+ audit_inode(name, dentry);
filp = do_open(dentry, oflag);
}
@@ -834,7 +837,7 @@ asmlinkage long sys_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput;
info = MQUEUE_I(inode);
- audit_inode(NULL, inode);
+ audit_inode(NULL, filp->f_path.dentry);
if (unlikely(!(filp->f_mode & FMODE_WRITE)))
goto out_fput;
@@ -918,7 +921,7 @@ asmlinkage ssize_t sys_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
if (unlikely(filp->f_op != &mqueue_file_operations))
goto out_fput;
info = MQUEUE_I(inode);
- audit_inode(NULL, inode);
+ audit_inode(NULL, filp->f_path.dentry);
if (unlikely(!(filp->f_mode & FMODE_READ)))
goto out_fput;
diff --git a/ipc/msg.c b/ipc/msg.c
index a03fcb522ff..fdf3db5731c 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -34,7 +34,7 @@
#include <linux/syscalls.h>
#include <linux/audit.h>
#include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
#include <linux/nsproxy.h>
#include <asm/current.h>
@@ -66,23 +66,15 @@ struct msg_sender {
#define SEARCH_NOTEQUAL 3
#define SEARCH_LESSEQUAL 4
-static atomic_t msg_bytes = ATOMIC_INIT(0);
-static atomic_t msg_hdrs = ATOMIC_INIT(0);
-
static struct ipc_ids init_msg_ids;
#define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS]))
-#define msg_lock(ns, id) ((struct msg_queue*)ipc_lock(&msg_ids(ns), id))
#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-#define msg_rmid(ns, id) ((struct msg_queue*)ipc_rmid(&msg_ids(ns), id))
-#define msg_checkid(ns, msq, msgid) \
- ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid)
-#define msg_buildid(ns, id, seq) \
- ipc_buildid(&msg_ids(ns), id, seq)
-
-static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id);
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg);
+#define msg_buildid(id, seq) ipc_buildid(id, seq)
+
+static void freeque(struct ipc_namespace *, struct msg_queue *);
+static int newque(struct ipc_namespace *, struct ipc_params *);
#ifdef CONFIG_PROC_FS
static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
#endif
@@ -93,7 +85,9 @@ static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
ns->msg_ctlmax = MSGMAX;
ns->msg_ctlmnb = MSGMNB;
ns->msg_ctlmni = MSGMNI;
- ipc_init_ids(ids, ns->msg_ctlmni);
+ atomic_set(&ns->msg_bytes, 0);
+ atomic_set(&ns->msg_hdrs, 0);
+ ipc_init_ids(ids);
}
int msg_init_ns(struct ipc_namespace *ns)
@@ -110,20 +104,25 @@ int msg_init_ns(struct ipc_namespace *ns)
void msg_exit_ns(struct ipc_namespace *ns)
{
- int i;
struct msg_queue *msq;
+ int next_id;
+ int total, in_use;
+
+ down_write(&msg_ids(ns).rw_mutex);
+
+ in_use = msg_ids(ns).in_use;
- mutex_lock(&msg_ids(ns).mutex);
- for (i = 0; i <= msg_ids(ns).max_id; i++) {
- msq = msg_lock(ns, i);
+ for (total = 0, next_id = 0; total < in_use; next_id++) {
+ msq = idr_find(&msg_ids(ns).ipcs_idr, next_id);
if (msq == NULL)
continue;
-
- freeque(ns, msq, i);
+ ipc_lock_by_ptr(&msq->q_perm);
+ freeque(ns, msq);
+ total++;
}
- mutex_unlock(&msg_ids(ns).mutex);
- ipc_fini_ids(ns->ids[IPC_MSG_IDS]);
+ up_write(&msg_ids(ns).rw_mutex);
+
kfree(ns->ids[IPC_MSG_IDS]);
ns->ids[IPC_MSG_IDS] = NULL;
}
@@ -136,10 +135,55 @@ void __init msg_init(void)
IPC_MSG_IDS, sysvipc_msg_proc_show);
}
-static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
+/*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id);
+
+ return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+/*
+ * msg_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id);
+
+ return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id);
+
+ return container_of(ipcp, struct msg_queue, q_perm);
+}
+
+static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
+{
+ ipc_rmid(&msg_ids(ns), &s->q_perm);
+}
+
+/**
+ * newque - Create a new msg queue
+ * @ns: namespace
+ * @params: ptr to the structure that contains the key and msgflg
+ *
+ * Called with msg_ids.rw_mutex held (writer)
+ */
+static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
struct msg_queue *msq;
int id, retval;
+ key_t key = params->key;
+ int msgflg = params->flg;
msq = ipc_rcu_alloc(sizeof(*msq));
if (!msq)
@@ -155,14 +199,17 @@ static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
return retval;
}
+ /*
+ * ipc_addid() locks msq
+ */
id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni);
- if (id == -1) {
+ if (id < 0) {
security_msg_queue_free(msq);
ipc_rcu_putref(msq);
- return -ENOSPC;
+ return id;
}
- msq->q_id = msg_buildid(ns, id, msq->q_perm.seq);
+ msq->q_perm.id = msg_buildid(id, msq->q_perm.seq);
msq->q_stime = msq->q_rtime = 0;
msq->q_ctime = get_seconds();
msq->q_cbytes = msq->q_qnum = 0;
@@ -171,9 +218,10 @@ static int newque (struct ipc_namespace *ns, key_t key, int msgflg)
INIT_LIST_HEAD(&msq->q_messages);
INIT_LIST_HEAD(&msq->q_receivers);
INIT_LIST_HEAD(&msq->q_senders);
+
msg_unlock(msq);
- return msq->q_id;
+ return msq->q_perm.id;
}
static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss)
@@ -224,19 +272,19 @@ static void expunge_all(struct msg_queue *msq, int res)
/*
* freeque() wakes up waiters on the sender and receiver waiting queue,
- * removes the message queue from message queue ID
- * array, and cleans up all the messages associated with this queue.
+ * removes the message queue from message queue ID IDR, and cleans up all the
+ * messages associated with this queue.
*
- * msg_ids.mutex and the spinlock for this message queue is hold
- * before freeque() is called. msg_ids.mutex remains locked on exit.
+ * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
*/
-static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
+static void freeque(struct ipc_namespace *ns, struct msg_queue *msq)
{
struct list_head *tmp;
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
- msq = msg_rmid(ns, id);
+ msg_rmid(ns, msq);
msg_unlock(msq);
tmp = msq->q_messages.next;
@@ -244,49 +292,40 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id)
struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list);
tmp = tmp->next;
- atomic_dec(&msg_hdrs);
+ atomic_dec(&ns->msg_hdrs);
free_msg(msg);
}
- atomic_sub(msq->q_cbytes, &msg_bytes);
+ atomic_sub(msq->q_cbytes, &ns->msg_bytes);
security_msg_queue_free(msq);
ipc_rcu_putref(msq);
}
+/*
+ * Called with msg_ids.rw_mutex and ipcp locked.
+ */
+static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
+{
+ struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
+
+ return security_msg_queue_associate(msq, msgflg);
+}
+
asmlinkage long sys_msgget(key_t key, int msgflg)
{
- struct msg_queue *msq;
- int id, ret = -EPERM;
struct ipc_namespace *ns;
+ struct ipc_ops msg_ops;
+ struct ipc_params msg_params;
ns = current->nsproxy->ipc_ns;
-
- mutex_lock(&msg_ids(ns).mutex);
- if (key == IPC_PRIVATE)
- ret = newque(ns, key, msgflg);
- else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */
- if (!(msgflg & IPC_CREAT))
- ret = -ENOENT;
- else
- ret = newque(ns, key, msgflg);
- } else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) {
- ret = -EEXIST;
- } else {
- msq = msg_lock(ns, id);
- BUG_ON(msq == NULL);
- if (ipcperms(&msq->q_perm, msgflg))
- ret = -EACCES;
- else {
- int qid = msg_buildid(ns, id, msq->q_perm.seq);
-
- ret = security_msg_queue_associate(msq, msgflg);
- if (!ret)
- ret = qid;
- }
- msg_unlock(msq);
- }
- mutex_unlock(&msg_ids(ns).mutex);
- return ret;
+ msg_ops.getnew = newque;
+ msg_ops.associate = msg_security;
+ msg_ops.more_checks = NULL;
+
+ msg_params.key = key;
+ msg_params.flg = msgflg;
+
+ return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
}
static inline unsigned long
@@ -420,23 +459,23 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- mutex_lock(&msg_ids(ns).mutex);
+ down_read(&msg_ids(ns).rw_mutex);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
- msginfo.msgmap = atomic_read(&msg_hdrs);
- msginfo.msgtql = atomic_read(&msg_bytes);
+ msginfo.msgmap = atomic_read(&ns->msg_hdrs);
+ msginfo.msgtql = atomic_read(&ns->msg_bytes);
} else {
msginfo.msgmap = MSGMAP;
msginfo.msgpool = MSGPOOL;
msginfo.msgtql = MSGTQL;
}
- max_id = msg_ids(ns).max_id;
- mutex_unlock(&msg_ids(ns).mutex);
+ max_id = ipc_get_maxid(&msg_ids(ns));
+ up_read(&msg_ids(ns).rw_mutex);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
}
- case MSG_STAT:
+ case MSG_STAT: /* msqid is an index rather than a msg queue id */
case IPC_STAT:
{
struct msqid64_ds tbuf;
@@ -444,21 +483,16 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
if (!buf)
return -EFAULT;
- if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size)
- return -EINVAL;
-
- memset(&tbuf, 0, sizeof(tbuf));
-
- msq = msg_lock(ns, msqid);
- if (msq == NULL)
- return -EINVAL;
if (cmd == MSG_STAT) {
- success_return = msg_buildid(ns, msqid, msq->q_perm.seq);
+ msq = msg_lock(ns, msqid);
+ if (IS_ERR(msq))
+ return PTR_ERR(msq);
+ success_return = msq->q_perm.id;
} else {
- err = -EIDRM;
- if (msg_checkid(ns, msq, msqid))
- goto out_unlock;
+ msq = msg_lock_check(ns, msqid);
+ if (IS_ERR(msq))
+ return PTR_ERR(msq);
success_return = 0;
}
err = -EACCES;
@@ -469,6 +503,8 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
if (err)
goto out_unlock;
+ memset(&tbuf, 0, sizeof(tbuf));
+
kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
tbuf.msg_stime = msq->q_stime;
tbuf.msg_rtime = msq->q_rtime;
@@ -495,15 +531,13 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
return -EINVAL;
}
- mutex_lock(&msg_ids(ns).mutex);
- msq = msg_lock(ns, msqid);
- err = -EINVAL;
- if (msq == NULL)
+ down_write(&msg_ids(ns).rw_mutex);
+ msq = msg_lock_check_down(ns, msqid);
+ if (IS_ERR(msq)) {
+ err = PTR_ERR(msq);
goto out_up;
+ }
- err = -EIDRM;
- if (msg_checkid(ns, msq, msqid))
- goto out_unlock_up;
ipcp = &msq->q_perm;
err = audit_ipc_obj(ipcp);
@@ -552,12 +586,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
break;
}
case IPC_RMID:
- freeque(ns, msq, msqid);
+ freeque(ns, msq);
break;
}
err = 0;
out_up:
- mutex_unlock(&msg_ids(ns).mutex);
+ up_write(&msg_ids(ns).rw_mutex);
return err;
out_unlock_up:
msg_unlock(msq);
@@ -611,7 +645,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg)
msr->r_msg = ERR_PTR(-E2BIG);
} else {
msr->r_msg = NULL;
- msq->q_lrpid = msr->r_tsk->pid;
+ msq->q_lrpid = task_pid_vnr(msr->r_tsk);
msq->q_rtime = get_seconds();
wake_up_process(msr->r_tsk);
smp_mb();
@@ -646,14 +680,11 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
msg->m_type = mtype;
msg->m_ts = msgsz;
- msq = msg_lock(ns, msqid);
- err = -EINVAL;
- if (msq == NULL)
+ msq = msg_lock_check(ns, msqid);
+ if (IS_ERR(msq)) {
+ err = PTR_ERR(msq);
goto out_free;
-
- err= -EIDRM;
- if (msg_checkid(ns, msq, msqid))
- goto out_unlock_free;
+ }
for (;;) {
struct msg_sender s;
@@ -695,7 +726,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
}
}
- msq->q_lspid = current->tgid;
+ msq->q_lspid = task_tgid_vnr(current);
msq->q_stime = get_seconds();
if (!pipelined_send(msq, msg)) {
@@ -703,8 +734,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
list_add_tail(&msg->m_list, &msq->q_messages);
msq->q_cbytes += msgsz;
msq->q_qnum++;
- atomic_add(msgsz, &msg_bytes);
- atomic_inc(&msg_hdrs);
+ atomic_add(msgsz, &ns->msg_bytes);
+ atomic_inc(&ns->msg_hdrs);
}
err = 0;
@@ -760,13 +791,9 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
mode = convert_mode(&msgtyp, msgflg);
ns = current->nsproxy->ipc_ns;
- msq = msg_lock(ns, msqid);
- if (msq == NULL)
- return -EINVAL;
-
- msg = ERR_PTR(-EIDRM);
- if (msg_checkid(ns, msq, msqid))
- goto out_unlock;
+ msq = msg_lock_check(ns, msqid);
+ if (IS_ERR(msq))
+ return PTR_ERR(msq);
for (;;) {
struct msg_receiver msr_d;
@@ -810,10 +837,10 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
list_del(&msg->m_list);
msq->q_qnum--;
msq->q_rtime = get_seconds();
- msq->q_lrpid = current->tgid;
+ msq->q_lrpid = task_tgid_vnr(current);
msq->q_cbytes -= msg->m_ts;
- atomic_sub(msg->m_ts, &msg_bytes);
- atomic_dec(&msg_hdrs);
+ atomic_sub(msg->m_ts, &ns->msg_bytes);
+ atomic_dec(&ns->msg_hdrs);
ss_wakeup(&msq->q_senders, 0);
msg_unlock(msq);
break;
@@ -926,7 +953,7 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
return seq_printf(s,
"%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
msq->q_perm.key,
- msq->q_id,
+ msq->q_perm.id,
msq->q_perm.mode,
msq->q_cbytes,
msq->q_qnum,
diff --git a/ipc/sem.c b/ipc/sem.c
index b676fef6d20..35952c0bae4 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -80,7 +80,7 @@
#include <linux/audit.h>
#include <linux/capability.h>
#include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
#include <linux/nsproxy.h>
#include <asm/uaccess.h>
@@ -88,18 +88,14 @@
#define sem_ids(ns) (*((ns)->ids[IPC_SEM_IDS]))
-#define sem_lock(ns, id) ((struct sem_array*)ipc_lock(&sem_ids(ns), id))
#define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm)
-#define sem_rmid(ns, id) ((struct sem_array*)ipc_rmid(&sem_ids(ns), id))
-#define sem_checkid(ns, sma, semid) \
- ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid)
-#define sem_buildid(ns, id, seq) \
- ipc_buildid(&sem_ids(ns), id, seq)
+#define sem_checkid(sma, semid) ipc_checkid(&sma->sem_perm, semid)
+#define sem_buildid(id, seq) ipc_buildid(id, seq)
static struct ipc_ids init_sem_ids;
-static int newary(struct ipc_namespace *, key_t, int, int);
-static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id);
+static int newary(struct ipc_namespace *, struct ipc_params *);
+static void freeary(struct ipc_namespace *, struct sem_array *);
#ifdef CONFIG_PROC_FS
static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
#endif
@@ -129,7 +125,7 @@ static void __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
ns->sc_semopm = SEMOPM;
ns->sc_semmni = SEMMNI;
ns->used_sems = 0;
- ipc_init_ids(ids, ns->sc_semmni);
+ ipc_init_ids(ids);
}
int sem_init_ns(struct ipc_namespace *ns)
@@ -146,20 +142,24 @@ int sem_init_ns(struct ipc_namespace *ns)
void sem_exit_ns(struct ipc_namespace *ns)
{
- int i;
struct sem_array *sma;
+ int next_id;
+ int total, in_use;
- mutex_lock(&sem_ids(ns).mutex);
- for (i = 0; i <= sem_ids(ns).max_id; i++) {
- sma = sem_lock(ns, i);
+ down_write(&sem_ids(ns).rw_mutex);
+
+ in_use = sem_ids(ns).in_use;
+
+ for (total = 0, next_id = 0; total < in_use; next_id++) {
+ sma = idr_find(&sem_ids(ns).ipcs_idr, next_id);
if (sma == NULL)
continue;
-
- freeary(ns, sma, i);
+ ipc_lock_by_ptr(&sma->sem_perm);
+ freeary(ns, sma);
+ total++;
}
- mutex_unlock(&sem_ids(ns).mutex);
+ up_write(&sem_ids(ns).rw_mutex);
- ipc_fini_ids(ns->ids[IPC_SEM_IDS]);
kfree(ns->ids[IPC_SEM_IDS]);
ns->ids[IPC_SEM_IDS] = NULL;
}
@@ -173,6 +173,42 @@ void __init sem_init (void)
}
/*
+ * This routine is called in the paths where the rw_mutex is held to protect
+ * access to the idr tree.
+ */
+static inline struct sem_array *sem_lock_check_down(struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id);
+
+ return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+/*
+ * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id);
+
+ return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id);
+
+ return container_of(ipcp, struct sem_array, sem_perm);
+}
+
+static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
+{
+ ipc_rmid(&sem_ids(ns), &s->sem_perm);
+}
+
+/*
* Lockless wakeup algorithm:
* Without the check/retry algorithm a lockless wakeup is possible:
* - queue.status is initialized to -EINTR before blocking.
@@ -206,12 +242,23 @@ void __init sem_init (void)
*/
#define IN_WAKEUP 1
-static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
+/**
+ * newary - Create a new semaphore set
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, semflg and nsems
+ *
+ * Called with sem_ids.rw_mutex held (as a writer)
+ */
+
+static int newary(struct ipc_namespace *ns, struct ipc_params *params)
{
int id;
int retval;
struct sem_array *sma;
int size;
+ key_t key = params->key;
+ int nsems = params->u.nsems;
+ int semflg = params->flg;
if (!nsems)
return -EINVAL;
@@ -236,14 +283,14 @@ static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
}
id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
- if(id == -1) {
+ if (id < 0) {
security_sem_free(sma);
ipc_rcu_putref(sma);
- return -ENOSPC;
+ return id;
}
ns->used_sems += nsems;
- sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq);
+ sma->sem_perm.id = sem_buildid(id, sma->sem_perm.seq);
sma->sem_base = (struct sem *) &sma[1];
/* sma->sem_pending = NULL; */
sma->sem_pending_last = &sma->sem_pending;
@@ -252,48 +299,56 @@ static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg)
sma->sem_ctime = get_seconds();
sem_unlock(sma);
- return sma->sem_id;
+ return sma->sem_perm.id;
+}
+
+
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
+{
+ struct sem_array *sma;
+
+ sma = container_of(ipcp, struct sem_array, sem_perm);
+ return security_sem_associate(sma, semflg);
}
-asmlinkage long sys_semget (key_t key, int nsems, int semflg)
+/*
+ * Called with sem_ids.rw_mutex and ipcp locked.
+ */
+static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
+ struct ipc_params *params)
{
- int id, err = -EINVAL;
struct sem_array *sma;
+
+ sma = container_of(ipcp, struct sem_array, sem_perm);
+ if (params->u.nsems > sma->sem_nsems)
+ return -EINVAL;
+
+ return 0;
+}
+
+asmlinkage long sys_semget(key_t key, int nsems, int semflg)
+{
struct ipc_namespace *ns;
+ struct ipc_ops sem_ops;
+ struct ipc_params sem_params;
ns = current->nsproxy->ipc_ns;
if (nsems < 0 || nsems > ns->sc_semmsl)
return -EINVAL;
- mutex_lock(&sem_ids(ns).mutex);
-
- if (key == IPC_PRIVATE) {
- err = newary(ns, key, nsems, semflg);
- } else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) { /* key not used */
- if (!(semflg & IPC_CREAT))
- err = -ENOENT;
- else
- err = newary(ns, key, nsems, semflg);
- } else if (semflg & IPC_CREAT && semflg & IPC_EXCL) {
- err = -EEXIST;
- } else {
- sma = sem_lock(ns, id);
- BUG_ON(sma==NULL);
- if (nsems > sma->sem_nsems)
- err = -EINVAL;
- else if (ipcperms(&sma->sem_perm, semflg))
- err = -EACCES;
- else {
- int semid = sem_buildid(ns, id, sma->sem_perm.seq);
- err = security_sem_associate(sma, semflg);
- if (!err)
- err = semid;
- }
- sem_unlock(sma);
- }
- mutex_unlock(&sem_ids(ns).mutex);
- return err;
+ sem_ops.getnew = newary;
+ sem_ops.associate = sem_security;
+ sem_ops.more_checks = sem_more_checks;
+
+ sem_params.key = key;
+ sem_params.flg = semflg;
+ sem_params.u.nsems = nsems;
+
+ return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
}
/* Manage the doubly linked list sma->sem_pending as a FIFO:
@@ -487,15 +542,14 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.mutex locked and
- * the spinlock for this semaphore set hold. sem_ids.mutex remains locked
- * on exit.
+/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+ * remains locked on exit.
*/
-static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
+static void freeary(struct ipc_namespace *ns, struct sem_array *sma)
{
struct sem_undo *un;
struct sem_queue *q;
- int size;
/* Invalidate the existing undo structures for this semaphore set.
* (They will be freed without any further action in exit_sem()
@@ -518,12 +572,11 @@ static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id)
q = n;
}
- /* Remove the semaphore set from the ID array*/
- sma = sem_rmid(ns, id);
+ /* Remove the semaphore set from the IDR */
+ sem_rmid(ns, sma);
sem_unlock(sma);
ns->used_sems -= sma->sem_nsems;
- size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem);
security_sem_free(sma);
ipc_rcu_putref(sma);
}
@@ -576,7 +629,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- mutex_lock(&sem_ids(ns).mutex);
+ down_read(&sem_ids(ns).rw_mutex);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -584,8 +637,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
seminfo.semusz = SEMUSZ;
seminfo.semaem = SEMAEM;
}
- max_id = sem_ids(ns).max_id;
- mutex_unlock(&sem_ids(ns).mutex);
+ max_id = ipc_get_maxid(&sem_ids(ns));
+ up_read(&sem_ids(ns).rw_mutex);
if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -595,14 +648,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
struct semid64_ds tbuf;
int id;
- if(semid >= sem_ids(ns).entries->size)
- return -EINVAL;
-
- memset(&tbuf,0,sizeof(tbuf));
-
sma = sem_lock(ns, semid);
- if(sma == NULL)
- return -EINVAL;
+ if (IS_ERR(sma))
+ return PTR_ERR(sma);
err = -EACCES;
if (ipcperms (&sma->sem_perm, S_IRUGO))
@@ -612,7 +660,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum,
if (err)
goto out_unlock;
- id = sem_buildid(ns, semid, sma->sem_perm.seq);
+ id = sma->sem_perm.id;
+
+ memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
tbuf.sem_otime = sma->sem_otime;
@@ -642,16 +692,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
ushort* sem_io = fast_sem_io;
int nsems;
- sma = sem_lock(ns, semid);
- if(sma==NULL)
- return -EINVAL;
+ sma = sem_lock_check(ns, semid);
+ if (IS_ERR(sma))
+ return PTR_ERR(sma);
nsems = sma->sem_nsems;
- err=-EIDRM;
- if (sem_checkid(ns,sma,semid))
- goto out_unlock;
-
err = -EACCES;
if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO))
goto out_unlock;
@@ -795,7 +841,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
for (un = sma->undo; un; un = un->id_next)
un->semadj[semnum] = 0;
curr->semval = val;
- curr->sempid = current->tgid;
+ curr->sempid = task_tgid_vnr(current);
sma->sem_ctime = get_seconds();
/* maybe some queued-up processes were waiting for this */
update_queue(sma);
@@ -863,14 +909,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
if(copy_semid_from_user (&setbuf, arg.buf, version))
return -EFAULT;
}
- sma = sem_lock(ns, semid);
- if(sma==NULL)
- return -EINVAL;
+ sma = sem_lock_check_down(ns, semid);
+ if (IS_ERR(sma))
+ return PTR_ERR(sma);
- if (sem_checkid(ns,sma,semid)) {
- err=-EIDRM;
- goto out_unlock;
- }
ipcp = &sma->sem_perm;
err = audit_ipc_obj(ipcp);
@@ -894,7 +936,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum,
switch(cmd){
case IPC_RMID:
- freeary(ns, sma, semid);
+ freeary(ns, sma);
err = 0;
break;
case IPC_SET:
@@ -948,45 +990,15 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg)
return err;
case IPC_RMID:
case IPC_SET:
- mutex_lock(&sem_ids(ns).mutex);
+ down_write(&sem_ids(ns).rw_mutex);
err = semctl_down(ns,semid,semnum,cmd,version,arg);
- mutex_unlock(&sem_ids(ns).mutex);
+ up_write(&sem_ids(ns).rw_mutex);
return err;
default:
return -EINVAL;
}
}
-static inline void lock_semundo(void)
-{
- struct sem_undo_list *undo_list;
-
- undo_list = current->sysvsem.undo_list;
- if (undo_list)
- spin_lock(&undo_list->lock);
-}
-
-/* This code has an interaction with copy_semundo().
- * Consider; two tasks are sharing the undo_list. task1
- * acquires the undo_list lock in lock_semundo(). If task2 now
- * exits before task1 releases the lock (by calling
- * unlock_semundo()), then task1 will never call spin_unlock().
- * This leave the sem_undo_list in a locked state. If task1 now creats task3
- * and once again shares the sem_undo_list, the sem_undo_list will still be
- * locked, and future SEM_UNDO operations will deadlock. This case is
- * dealt with in copy_semundo() by having it reinitialize the spin lock when
- * the refcnt goes from 1 to 2.
- */
-static inline void unlock_semundo(void)
-{
- struct sem_undo_list *undo_list;
-
- undo_list = current->sysvsem.undo_list;
- if (undo_list)
- spin_unlock(&undo_list->lock);
-}
-
-
/* If the task doesn't already have a undo_list, then allocate one
* here. We guarantee there is only one thread using this undo list,
* and current is THE ONE
@@ -1047,22 +1059,17 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
if (error)
return ERR_PTR(error);
- lock_semundo();
+ spin_lock(&ulp->lock);
un = lookup_undo(ulp, semid);
- unlock_semundo();
+ spin_unlock(&ulp->lock);
if (likely(un!=NULL))
goto out;
/* no undo structure around - allocate one. */
- sma = sem_lock(ns, semid);
- un = ERR_PTR(-EINVAL);
- if(sma==NULL)
- goto out;
- un = ERR_PTR(-EIDRM);
- if (sem_checkid(ns,sma,semid)) {
- sem_unlock(sma);
- goto out;
- }
+ sma = sem_lock_check(ns, semid);
+ if (IS_ERR(sma))
+ return ERR_PTR(PTR_ERR(sma));
+
nsems = sma->sem_nsems;
ipc_rcu_getref(sma);
sem_unlock(sma);
@@ -1077,10 +1084,10 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
new->semadj = (short *) &new[1];
new->semid = semid;
- lock_semundo();
+ spin_lock(&ulp->lock);
un = lookup_undo(ulp, semid);
if (un) {
- unlock_semundo();
+ spin_unlock(&ulp->lock);
kfree(new);
ipc_lock_by_ptr(&sma->sem_perm);
ipc_rcu_putref(sma);
@@ -1091,7 +1098,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
ipc_rcu_putref(sma);
if (sma->sem_perm.deleted) {
sem_unlock(sma);
- unlock_semundo();
+ spin_unlock(&ulp->lock);
kfree(new);
un = ERR_PTR(-EIDRM);
goto out;
@@ -1102,7 +1109,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid)
sma->undo = new;
sem_unlock(sma);
un = new;
- unlock_semundo();
+ spin_unlock(&ulp->lock);
out:
return un;
}
@@ -1168,15 +1175,14 @@ retry_undos:
} else
un = NULL;
- sma = sem_lock(ns, semid);
- error=-EINVAL;
- if(sma==NULL)
+ sma = sem_lock_check(ns, semid);
+ if (IS_ERR(sma)) {
+ error = PTR_ERR(sma);
goto out_free;
- error = -EIDRM;
- if (sem_checkid(ns,sma,semid))
- goto out_unlock_free;
+ }
+
/*
- * semid identifies are not unique - find_undo may have
+ * semid identifiers are not unique - find_undo may have
* allocated an undo structure, it was invalidated by an RMID
* and now a new array with received the same id. Check and retry.
*/
@@ -1196,7 +1202,7 @@ retry_undos:
if (error)
goto out_unlock_free;
- error = try_atomic_semop (sma, sops, nsops, un, current->tgid);
+ error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current));
if (error <= 0) {
if (alter && error == 0)
update_queue (sma);
@@ -1211,7 +1217,7 @@ retry_undos:
queue.sops = sops;
queue.nsops = nsops;
queue.undo = un;
- queue.pid = current->tgid;
+ queue.pid = task_tgid_vnr(current);
queue.id = semid;
queue.alter = alter;
if (alter)
@@ -1242,7 +1248,7 @@ retry_undos:
}
sma = sem_lock(ns, semid);
- if(sma==NULL) {
+ if (IS_ERR(sma)) {
BUG_ON(queue.prev != NULL);
error = -EIDRM;
goto out_free;
@@ -1279,10 +1285,6 @@ asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsop
/* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
* parent and child tasks.
- *
- * See the notes above unlock_semundo() regarding the spin_lock_init()
- * in this code. Initialize the undo_list->lock here instead of get_undo_list()
- * because of the reasoning in the comment above unlock_semundo.
*/
int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
@@ -1342,13 +1344,13 @@ void exit_sem(struct task_struct *tsk)
if(semid == -1)
continue;
sma = sem_lock(ns, semid);
- if (sma == NULL)
+ if (IS_ERR(sma))
continue;
if (u->semid == -1)
goto next_entry;
- BUG_ON(sem_checkid(ns,sma,u->semid));
+ BUG_ON(sem_checkid(sma, u->semid));
/* remove u from the sma->undo list */
for (unp = &sma->undo; (un = *unp); unp = &un->id_next) {
@@ -1382,7 +1384,7 @@ found:
semaphore->semval = 0;
if (semaphore->semval > SEMVMX)
semaphore->semval = SEMVMX;
- semaphore->sempid = current->tgid;
+ semaphore->sempid = task_tgid_vnr(current);
}
}
sma->sem_otime = get_seconds();
@@ -1402,7 +1404,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
return seq_printf(s,
"%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n",
sma->sem_perm.key,
- sma->sem_id,
+ sma->sem_perm.id,
sma->sem_perm.mode,
sma->sem_nsems,
sma->sem_perm.uid,
diff --git a/ipc/shm.c b/ipc/shm.c
index 5fc5cf50cf1..3818fae625c 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -35,7 +35,7 @@
#include <linux/capability.h>
#include <linux/ptrace.h>
#include <linux/seq_file.h>
-#include <linux/mutex.h>
+#include <linux/rwsem.h>
#include <linux/nsproxy.h>
#include <linux/mount.h>
@@ -59,17 +59,11 @@ static struct ipc_ids init_shm_ids;
#define shm_ids(ns) (*((ns)->ids[IPC_SHM_IDS]))
-#define shm_lock(ns, id) \
- ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id))
#define shm_unlock(shp) \
ipc_unlock(&(shp)->shm_perm)
-#define shm_get(ns, id) \
- ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id))
-#define shm_buildid(ns, id, seq) \
- ipc_buildid(&shm_ids(ns), id, seq)
+#define shm_buildid(id, seq) ipc_buildid(id, seq)
-static int newseg (struct ipc_namespace *ns, key_t key,
- int shmflg, size_t size);
+static int newseg(struct ipc_namespace *, struct ipc_params *);
static void shm_open(struct vm_area_struct *vma);
static void shm_close(struct vm_area_struct *vma);
static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp);
@@ -84,9 +78,13 @@ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
ns->shm_ctlall = SHMALL;
ns->shm_ctlmni = SHMMNI;
ns->shm_tot = 0;
- ipc_init_ids(ids, 1);
+ ipc_init_ids(ids);
}
+/*
+ * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
+ * Only shm_ids.rw_mutex remains locked on exit.
+ */
static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
if (shp->shm_nattch){
@@ -112,20 +110,24 @@ int shm_init_ns(struct ipc_namespace *ns)
void shm_exit_ns(struct ipc_namespace *ns)
{
- int i;
struct shmid_kernel *shp;
+ int next_id;
+ int total, in_use;
+
+ down_write(&shm_ids(ns).rw_mutex);
- mutex_lock(&shm_ids(ns).mutex);
- for (i = 0; i <= shm_ids(ns).max_id; i++) {
- shp = shm_lock(ns, i);
+ in_use = shm_ids(ns).in_use;
+
+ for (total = 0, next_id = 0; total < in_use; next_id++) {
+ shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
if (shp == NULL)
continue;
-
+ ipc_lock_by_ptr(&shp->shm_perm);
do_shm_rmid(ns, shp);
+ total++;
}
- mutex_unlock(&shm_ids(ns).mutex);
+ up_write(&shm_ids(ns).rw_mutex);
- ipc_fini_ids(ns->ids[IPC_SHM_IDS]);
kfree(ns->ids[IPC_SHM_IDS]);
ns->ids[IPC_SHM_IDS] = NULL;
}
@@ -138,17 +140,49 @@ void __init shm_init (void)
IPC_SHM_IDS, sysvipc_shm_proc_show);
}
-static inline int shm_checkid(struct ipc_namespace *ns,
- struct shmid_kernel *s, int id)
+/*
+ * shm_lock_(check_)down routines are called in the paths where the rw_mutex
+ * is held to protect access to the idr tree.
+ */
+static inline struct shmid_kernel *shm_lock_down(struct ipc_namespace *ns,
+ int id)
{
- if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id))
- return -EIDRM;
- return 0;
+ struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_lock_check_down(
+ struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+/*
+ * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * is not held.
+ */
+static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns,
+ int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
}
-static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id)
+static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
{
- return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id);
+ ipc_rmid(&shm_ids(ns), &s->shm_perm);
}
static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -166,9 +200,9 @@ static void shm_open(struct vm_area_struct *vma)
struct shmid_kernel *shp;
shp = shm_lock(sfd->ns, sfd->id);
- BUG_ON(!shp);
+ BUG_ON(IS_ERR(shp));
shp->shm_atim = get_seconds();
- shp->shm_lprid = current->tgid;
+ shp->shm_lprid = task_tgid_vnr(current);
shp->shm_nattch++;
shm_unlock(shp);
}
@@ -176,15 +210,16 @@ static void shm_open(struct vm_area_struct *vma)
/*
* shm_destroy - free the struct shmid_kernel
*
+ * @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.mutex locked,
+ * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
{
ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT;
- shm_rmid(ns, shp->id);
+ shm_rmid(ns, shp);
shm_unlock(shp);
if (!is_file_hugepages(shp->shm_file))
shmem_lock(shp->shm_file, 0, shp->mlock_user);
@@ -209,11 +244,11 @@ static void shm_close(struct vm_area_struct *vma)
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- mutex_lock(&shm_ids(ns).mutex);
+ down_write(&shm_ids(ns).rw_mutex);
/* remove from the list of attaches of the shm segment */
- shp = shm_lock(ns, sfd->id);
- BUG_ON(!shp);
- shp->shm_lprid = current->tgid;
+ shp = shm_lock_down(ns, sfd->id);
+ BUG_ON(IS_ERR(shp));
+ shp->shm_lprid = task_tgid_vnr(current);
shp->shm_dtim = get_seconds();
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
@@ -221,7 +256,7 @@ static void shm_close(struct vm_area_struct *vma)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- mutex_unlock(&shm_ids(ns).mutex);
+ up_write(&shm_ids(ns).rw_mutex);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -337,8 +372,19 @@ static struct vm_operations_struct shm_vm_ops = {
#endif
};
-static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
+/**
+ * newseg - Create a new shared memory segment
+ * @ns: namespace
+ * @params: ptr to the structure that contains key, size and shmflg
+ *
+ * Called with shm_ids.rw_mutex held as a writer.
+ */
+
+static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
{
+ key_t key = params->key;
+ int shmflg = params->flg;
+ size_t size = params->u.size;
int error;
struct shmid_kernel *shp;
int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
@@ -387,28 +433,30 @@ static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size)
if (IS_ERR(file))
goto no_file;
- error = -ENOSPC;
id = shm_addid(ns, shp);
- if(id == -1)
+ if (id < 0) {
+ error = id;
goto no_id;
+ }
- shp->shm_cprid = current->tgid;
+ shp->shm_cprid = task_tgid_vnr(current);
shp->shm_lprid = 0;
shp->shm_atim = shp->shm_dtim = 0;
shp->shm_ctim = get_seconds();
shp->shm_segsz = size;
shp->shm_nattch = 0;
- shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
+ shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq);
shp->shm_file = file;
/*
* shmid gets reported as "inode#" in /proc/pid/maps.
* proc-ps tools use this. Changing this will break them.
*/
- file->f_dentry->d_inode->i_ino = shp->id;
+ file->f_dentry->d_inode->i_ino = shp->shm_perm.id;
ns->shm_tot += numpages;
+ error = shp->shm_perm.id;
shm_unlock(shp);
- return shp->id;
+ return error;
no_id:
fput(file);
@@ -418,42 +466,49 @@ no_file:
return error;
}
-asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
struct shmid_kernel *shp;
- int err, id = 0;
+
+ shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+ return security_shm_associate(shp, shmflg);
+}
+
+/*
+ * Called with shm_ids.rw_mutex and ipcp locked.
+ */
+static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
+ struct ipc_params *params)
+{
+ struct shmid_kernel *shp;
+
+ shp = container_of(ipcp, struct shmid_kernel, shm_perm);
+ if (shp->shm_segsz < params->u.size)
+ return -EINVAL;
+
+ return 0;
+}
+
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
+{
struct ipc_namespace *ns;
+ struct ipc_ops shm_ops;
+ struct ipc_params shm_params;
ns = current->nsproxy->ipc_ns;
- mutex_lock(&shm_ids(ns).mutex);
- if (key == IPC_PRIVATE) {
- err = newseg(ns, key, shmflg, size);
- } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) {
- if (!(shmflg & IPC_CREAT))
- err = -ENOENT;
- else
- err = newseg(ns, key, shmflg, size);
- } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
- err = -EEXIST;
- } else {
- shp = shm_lock(ns, id);
- BUG_ON(shp==NULL);
- if (shp->shm_segsz < size)
- err = -EINVAL;
- else if (ipcperms(&shp->shm_perm, shmflg))
- err = -EACCES;
- else {
- int shmid = shm_buildid(ns, id, shp->shm_perm.seq);
- err = security_shm_associate(shp, shmflg);
- if (!err)
- err = shmid;
- }
- shm_unlock(shp);
- }
- mutex_unlock(&shm_ids(ns).mutex);
+ shm_ops.getnew = newseg;
+ shm_ops.associate = shm_security;
+ shm_ops.more_checks = shm_more_checks;
- return err;
+ shm_params.key = key;
+ shm_params.flg = shmflg;
+ shm_params.u.size = size;
+
+ return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
}
static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
@@ -547,20 +602,26 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
}
}
+/*
+ * Called with shm_ids.rw_mutex held as a reader
+ */
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
{
- int i;
+ int next_id;
+ int total, in_use;
*rss = 0;
*swp = 0;
- for (i = 0; i <= shm_ids(ns).max_id; i++) {
+ in_use = shm_ids(ns).in_use;
+
+ for (total = 0, next_id = 0; total < in_use; next_id++) {
struct shmid_kernel *shp;
struct inode *inode;
- shp = shm_get(ns, i);
- if(!shp)
+ shp = idr_find(&shm_ids(ns).ipcs_idr, next_id);
+ if (shp == NULL)
continue;
inode = shp->shm_file->f_path.dentry->d_inode;
@@ -575,6 +636,8 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
*swp += info->swapped;
spin_unlock(&info->lock);
}
+
+ total++;
}
}
@@ -610,8 +673,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
shminfo.shmmin = SHMMIN;
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- /* reading a integer is always atomic */
- err= shm_ids(ns).max_id;
+
+ down_read(&shm_ids(ns).rw_mutex);
+ err = ipc_get_maxid(&shm_ids(ns));
+ up_read(&shm_ids(ns).rw_mutex);
+
if(err<0)
err = 0;
goto out;
@@ -625,14 +691,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
return err;
memset(&shm_info,0,sizeof(shm_info));
- mutex_lock(&shm_ids(ns).mutex);
+ down_read(&shm_ids(ns).rw_mutex);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
- err = shm_ids(ns).max_id;
- mutex_unlock(&shm_ids(ns).mutex);
+ err = ipc_get_maxid(&shm_ids(ns));
+ up_read(&shm_ids(ns).rw_mutex);
if(copy_to_user (buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -646,20 +712,25 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
{
struct shmid64_ds tbuf;
int result;
- memset(&tbuf, 0, sizeof(tbuf));
- shp = shm_lock(ns, shmid);
- if(shp==NULL) {
- err = -EINVAL;
+
+ if (!buf) {
+ err = -EFAULT;
goto out;
- } else if(cmd==SHM_STAT) {
- err = -EINVAL;
- if (shmid > shm_ids(ns).max_id)
- goto out_unlock;
- result = shm_buildid(ns, shmid, shp->shm_perm.seq);
+ }
+
+ if (cmd == SHM_STAT) {
+ shp = shm_lock(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
+ goto out;
+ }
+ result = shp->shm_perm.id;
} else {
- err = shm_checkid(ns, shp,shmid);
- if(err)
- goto out_unlock;
+ shp = shm_lock_check(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
+ goto out;
+ }
result = 0;
}
err=-EACCES;
@@ -668,6 +739,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
+ memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
tbuf.shm_atime = shp->shm_atim;
@@ -686,14 +758,11 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
case SHM_LOCK:
case SHM_UNLOCK:
{
- shp = shm_lock(ns, shmid);
- if(shp==NULL) {
- err = -EINVAL;
+ shp = shm_lock_check(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
goto out;
}
- err = shm_checkid(ns, shp,shmid);
- if(err)
- goto out_unlock;
err = audit_ipc_obj(&(shp->shm_perm));
if (err)
@@ -742,14 +811,12 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
* Instead we set a destroyed flag, and then blow
* the name away when the usage hits zero.
*/
- mutex_lock(&shm_ids(ns).mutex);
- shp = shm_lock(ns, shmid);
- err = -EINVAL;
- if (shp == NULL)
+ down_write(&shm_ids(ns).rw_mutex);
+ shp = shm_lock_check_down(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
goto out_up;
- err = shm_checkid(ns, shp, shmid);
- if(err)
- goto out_unlock_up;
+ }
err = audit_ipc_obj(&(shp->shm_perm));
if (err)
@@ -767,24 +834,27 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
goto out_unlock_up;
do_shm_rmid(ns, shp);
- mutex_unlock(&shm_ids(ns).mutex);
+ up_write(&shm_ids(ns).rw_mutex);
goto out;
}
case IPC_SET:
{
+ if (!buf) {
+ err = -EFAULT;
+ goto out;
+ }
+
if (copy_shmid_from_user (&setbuf, buf, version)) {
err = -EFAULT;
goto out;
}
- mutex_lock(&shm_ids(ns).mutex);
- shp = shm_lock(ns, shmid);
- err=-EINVAL;
- if(shp==NULL)
+ down_write(&shm_ids(ns).rw_mutex);
+ shp = shm_lock_check_down(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
goto out_up;
- err = shm_checkid(ns, shp,shmid);
- if(err)
- goto out_unlock_up;
+ }
err = audit_ipc_obj(&(shp->shm_perm));
if (err)
goto out_unlock_up;
@@ -819,7 +889,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
out_unlock_up:
shm_unlock(shp);
out_up:
- mutex_unlock(&shm_ids(ns).mutex);
+ up_write(&shm_ids(ns).rw_mutex);
goto out;
out_unlock:
shm_unlock(shp);
@@ -890,13 +960,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
* additional creator id...
*/
ns = current->nsproxy->ipc_ns;
- shp = shm_lock(ns, shmid);
- if(shp == NULL)
+ shp = shm_lock_check(ns, shmid);
+ if (IS_ERR(shp)) {
+ err = PTR_ERR(shp);
goto out;
-
- err = shm_checkid(ns, shp,shmid);
- if (err)
- goto out_unlock;
+ }
err = -EACCES;
if (ipcperms(&shp->shm_perm, acc_mode))
@@ -925,7 +993,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
- sfd->id = shp->id;
+ sfd->id = shp->shm_perm.id;
sfd->ns = get_ipc_ns(ns);
sfd->file = shp->shm_file;
sfd->vm_ops = NULL;
@@ -955,16 +1023,16 @@ invalid:
fput(file);
out_nattch:
- mutex_lock(&shm_ids(ns).mutex);
- shp = shm_lock(ns, shmid);
- BUG_ON(!shp);
+ down_write(&shm_ids(ns).rw_mutex);
+ shp = shm_lock_down(ns, shmid);
+ BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
if(shp->shm_nattch == 0 &&
shp->shm_perm.mode & SHM_DEST)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- mutex_unlock(&shm_ids(ns).mutex);
+ up_write(&shm_ids(ns).rw_mutex);
out:
return err;
@@ -1094,7 +1162,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
format = BIG_STRING;
return seq_printf(s, format,
shp->shm_perm.key,
- shp->id,
+ shp->shm_perm.id,
shp->shm_perm.mode,
shp->shm_segsz,
shp->shm_cprid,
diff --git a/ipc/util.c b/ipc/util.c
index 44e5135aee4..1aa0ebf71ba 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -32,6 +32,7 @@
#include <linux/proc_fs.h>
#include <linux/audit.h>
#include <linux/nsproxy.h>
+#include <linux/rwsem.h>
#include <asm/unistd.h>
@@ -129,23 +130,16 @@ __initcall(ipc_init);
/**
* ipc_init_ids - initialise IPC identifiers
* @ids: Identifier set
- * @size: Number of identifiers
*
- * Given a size for the ipc identifier range (limited below IPCMNI)
- * set up the sequence range to use then allocate and initialise the
- * array itself.
+ * Set up the sequence range to use for the ipc identifier range (limited
+ * below IPCMNI) then initialise the ids idr.
*/
-void ipc_init_ids(struct ipc_ids* ids, int size)
+void ipc_init_ids(struct ipc_ids *ids)
{
- int i;
+ init_rwsem(&ids->rw_mutex);
- mutex_init(&ids->mutex);
-
- if(size > IPCMNI)
- size = IPCMNI;
ids->in_use = 0;
- ids->max_id = -1;
ids->seq = 0;
{
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
@@ -155,17 +149,7 @@ void ipc_init_ids(struct ipc_ids* ids, int size)
ids->seq_max = seq_limit;
}
- ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size +
- sizeof(struct ipc_id_ary));
-
- if(ids->entries == NULL) {
- printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n");
- size = 0;
- ids->entries = &ids->nullentry;
- }
- ids->entries->size = size;
- for(i=0;i<size;i++)
- ids->entries->p[i] = NULL;
+ idr_init(&ids->ipcs_idr);
}
#ifdef CONFIG_PROC_FS
@@ -208,99 +192,96 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.mutex locked.
- * Returns the identifier if found or -1 if not.
+ * Requires ipc_ids.rw_mutex locked.
+ * Returns the LOCKED pointer to the ipc structure if found or NULL
+ * if not.
+ * If key is found ipc points to the owning ipc structure
*/
-int ipc_findkey(struct ipc_ids* ids, key_t key)
+static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
{
- int id;
- struct kern_ipc_perm* p;
- int max_id = ids->max_id;
+ struct kern_ipc_perm *ipc;
+ int next_id;
+ int total;
- /*
- * rcu_dereference() is not needed here
- * since ipc_ids.mutex is held
- */
- for (id = 0; id <= max_id; id++) {
- p = ids->entries->p[id];
- if(p==NULL)
+ for (total = 0, next_id = 0; total < ids->in_use; next_id++) {
+ ipc = idr_find(&ids->ipcs_idr, next_id);
+
+ if (ipc == NULL)
+ continue;
+
+ if (ipc->key != key) {
+ total++;
continue;
- if (key == p->key)
- return id;
+ }
+
+ ipc_lock_by_ptr(ipc);
+ return ipc;
}
- return -1;
+
+ return NULL;
}
-/*
- * Requires ipc_ids.mutex locked
+/**
+ * ipc_get_maxid - get the last assigned id
+ * @ids: IPC identifier set
+ *
+ * Called with ipc_ids.rw_mutex held.
*/
-static int grow_ary(struct ipc_ids* ids, int newsize)
-{
- struct ipc_id_ary* new;
- struct ipc_id_ary* old;
- int i;
- int size = ids->entries->size;
-
- if(newsize > IPCMNI)
- newsize = IPCMNI;
- if(newsize <= size)
- return newsize;
-
- new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize +
- sizeof(struct ipc_id_ary));
- if(new == NULL)
- return size;
- new->size = newsize;
- memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size);
- for(i=size;i<newsize;i++) {
- new->p[i] = NULL;
- }
- old = ids->entries;
- /*
- * Use rcu_assign_pointer() to make sure the memcpyed contents
- * of the new array are visible before the new array becomes visible.
- */
- rcu_assign_pointer(ids->entries, new);
+int ipc_get_maxid(struct ipc_ids *ids)
+{
+ struct kern_ipc_perm *ipc;
+ int max_id = -1;
+ int total, id;
+
+ if (ids->in_use == 0)
+ return -1;
- __ipc_fini_ids(ids, old);
- return newsize;
+ if (ids->in_use == IPCMNI)
+ return IPCMNI - 1;
+
+ /* Look for the last assigned id */
+ total = 0;
+ for (id = 0; id < IPCMNI && total < ids->in_use; id++) {
+ ipc = idr_find(&ids->ipcs_idr, id);
+ if (ipc != NULL) {
+ max_id = id;
+ total++;
+ }
+ }
+ return max_id;
}
/**
* ipc_addid - add an IPC identifier
* @ids: IPC identifier set
* @new: new IPC permission set
- * @size: new size limit for the id array
+ * @size: limit for the number of used ids
*
- * Add an entry 'new' to the IPC arrays. The permissions object is
+ * Add an entry 'new' to the IPC ids idr. The permissions object is
* initialised and the first free entry is set up and the id assigned
- * is returned. The list is returned in a locked state on success.
- * On failure the list is not locked and -1 is returned.
+ * is returned. The 'new' entry is returned in a locked state on success.
+ * On failure the entry is not locked and a negative err-code is returned.
*
- * Called with ipc_ids.mutex held.
+ * Called with ipc_ids.rw_mutex held as a writer.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
- int id;
+ int id, err;
- size = grow_ary(ids,size);
+ if (size > IPCMNI)
+ size = IPCMNI;
+
+ if (ids->in_use >= size)
+ return -ENOSPC;
+
+ err = idr_get_new(&ids->ipcs_idr, new, &id);
+ if (err)
+ return err;
- /*
- * rcu_dereference()() is not needed here since
- * ipc_ids.mutex is held
- */
- for (id = 0; id < size; id++) {
- if(ids->entries->p[id] == NULL)
- goto found;
- }
- return -1;
-found:
ids->in_use++;
- if (id > ids->max_id)
- ids->max_id = id;
new->cuid = new->uid = current->euid;
new->gid = new->cgid = current->egid;
@@ -313,48 +294,153 @@ found:
new->deleted = 0;
rcu_read_lock();
spin_lock(&new->lock);
- ids->entries->p[id] = new;
return id;
}
/**
+ * ipcget_new - create a new ipc object
+ * @ns: namespace
+ * @ids: IPC identifer set
+ * @ops: the actual creation routine to call
+ * @params: its parameters
+ *
+ * This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ * when the key is IPC_PRIVATE.
+ */
+int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
+ struct ipc_ops *ops, struct ipc_params *params)
+{
+ int err;
+retry:
+ err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+ if (!err)
+ return -ENOMEM;
+
+ down_write(&ids->rw_mutex);
+ err = ops->getnew(ns, params);
+ up_write(&ids->rw_mutex);
+
+ if (err == -EAGAIN)
+ goto retry;
+
+ return err;
+}
+
+/**
+ * ipc_check_perms - check security and permissions for an IPC
+ * @ipcp: ipc permission set
+ * @ops: the actual security routine to call
+ * @params: its parameters
+ *
+ * This routine is called by sys_msgget(), sys_semget() and sys_shmget()
+ * when the key is not IPC_PRIVATE and that key already exists in the
+ * ids IDR.
+ *
+ * On success, the IPC id is returned.
+ *
+ * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ */
+static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops,
+ struct ipc_params *params)
+{
+ int err;
+
+ if (ipcperms(ipcp, params->flg))
+ err = -EACCES;
+ else {
+ err = ops->associate(ipcp, params->flg);
+ if (!err)
+ err = ipcp->id;
+ }
+
+ return err;
+}
+
+/**
+ * ipcget_public - get an ipc object or create a new one
+ * @ns: namespace
+ * @ids: IPC identifer set
+ * @ops: the actual creation routine to call
+ * @params: its parameters
+ *
+ * This routine is called by sys_msgget, sys_semget() and sys_shmget()
+ * when the key is not IPC_PRIVATE.
+ * It adds a new entry if the key is not found and does some permission
+ * / security checkings if the key is found.
+ *
+ * On success, the ipc id is returned.
+ */
+int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
+ struct ipc_ops *ops, struct ipc_params *params)
+{
+ struct kern_ipc_perm *ipcp;
+ int flg = params->flg;
+ int err;
+retry:
+ err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL);
+
+ /*
+ * Take the lock as a writer since we are potentially going to add
+ * a new entry + read locks are not "upgradable"
+ */
+ down_write(&ids->rw_mutex);
+ ipcp = ipc_findkey(ids, params->key);
+ if (ipcp == NULL) {
+ /* key not used */
+ if (!(flg & IPC_CREAT))
+ err = -ENOENT;
+ else if (!err)
+ err = -ENOMEM;
+ else
+ err = ops->getnew(ns, params);
+ } else {
+ /* ipc object has been locked by ipc_findkey() */
+
+ if (flg & IPC_CREAT && flg & IPC_EXCL)
+ err = -EEXIST;
+ else {
+ err = 0;
+ if (ops->more_checks)
+ err = ops->more_checks(ipcp, params);
+ if (!err)
+ /*
+ * ipc_check_perms returns the IPC id on
+ * success
+ */
+ err = ipc_check_perms(ipcp, ops, params);
+ }
+ ipc_unlock(ipcp);
+ }
+ up_write(&ids->rw_mutex);
+
+ if (err == -EAGAIN)
+ goto retry;
+
+ return err;
+}
+
+
+/**
* ipc_rmid - remove an IPC identifier
- * @ids: identifier set
- * @id: Identifier to remove
+ * @ids: IPC identifier set
+ * @ipcp: ipc perm structure containing the identifier to remove
*
- * The identifier must be valid, and in use. The kernel will panic if
- * fed an invalid identifier. The entry is removed and internal
- * variables recomputed. The object associated with the identifier
- * is returned.
- * ipc_ids.mutex and the spinlock for this ID is hold before this function
- * is called, and remain locked on the exit.
+ * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * before this function is called, and remain locked on the exit.
*/
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id)
+void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp)
{
- struct kern_ipc_perm* p;
- int lid = id % SEQ_MULTIPLIER;
- BUG_ON(lid >= ids->entries->size);
+ int lid = ipcid_to_idx(ipcp->id);
+
+ idr_remove(&ids->ipcs_idr, lid);
- /*
- * do not need a rcu_dereference()() here to force ordering
- * on Alpha, since the ipc_ids.mutex is held.
- */
- p = ids->entries->p[lid];
- ids->entries->p[lid] = NULL;
- BUG_ON(p==NULL);
ids->in_use--;
- if (lid == ids->max_id) {
- do {
- lid--;
- if(lid == -1)
- break;
- } while (ids->entries->p[lid] == NULL);
- ids->max_id = lid;
- }
- p->deleted = 1;
- return p;
+ ipcp->deleted = 1;
+
+ return;
}
/**
@@ -491,10 +577,12 @@ static void ipc_do_vfree(struct work_struct *work)
*/
static void ipc_schedule_free(struct rcu_head *head)
{
- struct ipc_rcu_grace *grace =
- container_of(head, struct ipc_rcu_grace, rcu);
- struct ipc_rcu_sched *sched =
- container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]);
+ struct ipc_rcu_grace *grace;
+ struct ipc_rcu_sched *sched;
+
+ grace = container_of(head, struct ipc_rcu_grace, rcu);
+ sched = container_of(&(grace->data[0]), struct ipc_rcu_sched,
+ data[0]);
INIT_WORK(&sched->work, ipc_do_vfree);
schedule_work(&sched->work);
@@ -583,7 +671,7 @@ void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
}
/**
- * ipc64_perm_to_ipc_perm - convert old ipc permissions to new
+ * ipc64_perm_to_ipc_perm - convert new ipc permissions to old
* @in: new style IPC permissions
* @out: old style IPC permissions
*
@@ -602,44 +690,37 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out)
out->seq = in->seq;
}
-/*
- * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get()
- * is called with shm_ids.mutex locked. Since grow_ary() is also called with
- * shm_ids.mutex down(for Shared Memory), there is no need to add read
- * barriers here to gurantee the writes in grow_ary() are seen in order
- * here (for Alpha).
+/**
+ * ipc_lock - Lock an ipc structure without rw_mutex held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
+ *
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
*
- * However ipc_get() itself does not necessary require ipc_ids.mutex down. So
- * if in the future ipc_get() is used by other places without ipc_ids.mutex
- * down, then ipc_get() needs read memery barriers as ipc_lock() does.
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is not already
+ * held, i.e. idr tree not protected: it protects the idr tree in read mode
+ * during the idr_find().
*/
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id)
-{
- struct kern_ipc_perm* out;
- int lid = id % SEQ_MULTIPLIER;
- if(lid >= ids->entries->size)
- return NULL;
- out = ids->entries->p[lid];
- return out;
-}
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id)
{
- struct kern_ipc_perm* out;
- int lid = id % SEQ_MULTIPLIER;
- struct ipc_id_ary* entries;
+ struct kern_ipc_perm *out;
+ int lid = ipcid_to_idx(id);
+
+ down_read(&ids->rw_mutex);
rcu_read_lock();
- entries = rcu_dereference(ids->entries);
- if(lid >= entries->size) {
- rcu_read_unlock();
- return NULL;
- }
- out = entries->p[lid];
- if(out == NULL) {
+ out = idr_find(&ids->ipcs_idr, lid);
+ if (out == NULL) {
rcu_read_unlock();
- return NULL;
+ up_read(&ids->rw_mutex);
+ return ERR_PTR(-EINVAL);
}
+
+ up_read(&ids->rw_mutex);
+
spin_lock(&out->lock);
/* ipc_rmid() may have already freed the ID while ipc_lock
@@ -648,33 +729,44 @@ struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
if (out->deleted) {
spin_unlock(&out->lock);
rcu_read_unlock();
- return NULL;
+ return ERR_PTR(-EINVAL);
}
+
return out;
}
-void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
-{
- rcu_read_lock();
- spin_lock(&perm->lock);
-}
+/**
+ * ipc_lock_down - Lock an ipc structure with rw_sem held
+ * @ids: IPC identifier set
+ * @id: ipc id to look for
+ *
+ * Look for an id in the ipc ids idr and lock the associated ipc object.
+ *
+ * The ipc object is locked on exit.
+ *
+ * This is the routine that should be called when the rw_mutex is already
+ * held, i.e. idr tree protected.
+ */
-void ipc_unlock(struct kern_ipc_perm* perm)
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id)
{
- spin_unlock(&perm->lock);
- rcu_read_unlock();
-}
+ struct kern_ipc_perm *out;
+ int lid = ipcid_to_idx(id);
-int ipc_buildid(struct ipc_ids* ids, int id, int seq)
-{
- return SEQ_MULTIPLIER*seq + id;
-}
+ rcu_read_lock();
+ out = idr_find(&ids->ipcs_idr, lid);
+ if (out == NULL) {
+ rcu_read_unlock();
+ return ERR_PTR(-EINVAL);
+ }
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid)
-{
- if(uid/SEQ_MULTIPLIER != ipcp->seq)
- return 1;
- return 0;
+ spin_lock(&out->lock);
+
+ /*
+ * No need to verify that the structure is still valid since the
+ * rw_mutex is held.
+ */
+ return out;
}
#ifdef __ARCH_WANT_IPC_PARSE_VERSION
@@ -707,27 +799,30 @@ struct ipc_proc_iter {
struct ipc_proc_iface *iface;
};
-static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+/*
+ * This routine locks the ipc structure found at least at position pos.
+ */
+struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos,
+ loff_t *new_pos)
{
- struct ipc_proc_iter *iter = s->private;
- struct ipc_proc_iface *iface = iter->iface;
- struct kern_ipc_perm *ipc = it;
- loff_t p;
- struct ipc_ids *ids;
+ struct kern_ipc_perm *ipc;
+ int total, id;
- ids = iter->ns->ids[iface->ids];
+ total = 0;
+ for (id = 0; id < pos && total < ids->in_use; id++) {
+ ipc = idr_find(&ids->ipcs_idr, id);
+ if (ipc != NULL)
+ total++;
+ }
- /* If we had an ipc id locked before, unlock it */
- if (ipc && ipc != SEQ_START_TOKEN)
- ipc_unlock(ipc);
+ if (total >= ids->in_use)
+ return NULL;
- /*
- * p = *pos - 1 (because id 0 starts at position 1)
- * + 1 (because we increment the position by one)
- */
- for (p = *pos; p <= ids->max_id; p++) {
- if ((ipc = ipc_lock(ids, p)) != NULL) {
- *pos = p + 1;
+ for ( ; pos < IPCMNI; pos++) {
+ ipc = idr_find(&ids->ipcs_idr, pos);
+ if (ipc != NULL) {
+ *new_pos = pos + 1;
+ ipc_lock_by_ptr(ipc);
return ipc;
}
}
@@ -736,16 +831,27 @@ static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
return NULL;
}
+static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
+{
+ struct ipc_proc_iter *iter = s->private;
+ struct ipc_proc_iface *iface = iter->iface;
+ struct kern_ipc_perm *ipc = it;
+
+ /* If we had an ipc id locked before, unlock it */
+ if (ipc && ipc != SEQ_START_TOKEN)
+ ipc_unlock(ipc);
+
+ return sysvipc_find_ipc(iter->ns->ids[iface->ids], *pos, pos);
+}
+
/*
- * File positions: pos 0 -> header, pos n -> ipc id + 1.
- * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START.
+ * File positions: pos 0 -> header, pos n -> ipc id = n - 1.
+ * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START.
*/
static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
{
struct ipc_proc_iter *iter = s->private;
struct ipc_proc_iface *iface = iter->iface;
- struct kern_ipc_perm *ipc;
- loff_t p;
struct ipc_ids *ids;
ids = iter->ns->ids[iface->ids];
@@ -754,7 +860,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- mutex_lock(&ids->mutex);
+ down_read(&ids->rw_mutex);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -765,13 +871,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
return SEQ_START_TOKEN;
/* Find the (pos-1)th ipc */
- for (p = *pos - 1; p <= ids->max_id; p++) {
- if ((ipc = ipc_lock(ids, p)) != NULL) {
- *pos = p + 1;
- return ipc;
- }
- }
- return NULL;
+ return sysvipc_find_ipc(ids, *pos - 1, pos);
}
static void sysvipc_proc_stop(struct seq_file *s, void *it)
@@ -781,13 +881,13 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
struct ipc_proc_iface *iface = iter->iface;
struct ipc_ids *ids;
- /* If we had a locked segment, release it */
+ /* If we had a locked structure, release it */
if (ipc && ipc != SEQ_START_TOKEN)
ipc_unlock(ipc);
ids = iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- mutex_unlock(&ids->mutex);
+ up_read(&ids->rw_mutex);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 333e891bcac..9ffea40457c 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -10,6 +10,9 @@
#ifndef _IPC_UTIL_H
#define _IPC_UTIL_H
+#include <linux/idr.h>
+#include <linux/err.h>
+
#define USHRT_MAX 0xffff
#define SEQ_MULTIPLIER (IPCMNI)
@@ -25,24 +28,46 @@ void sem_exit_ns(struct ipc_namespace *ns);
void msg_exit_ns(struct ipc_namespace *ns);
void shm_exit_ns(struct ipc_namespace *ns);
-struct ipc_id_ary {
- int size;
- struct kern_ipc_perm *p[0];
-};
-
struct ipc_ids {
int in_use;
- int max_id;
unsigned short seq;
unsigned short seq_max;
- struct mutex mutex;
- struct ipc_id_ary nullentry;
- struct ipc_id_ary* entries;
+ struct rw_semaphore rw_mutex;
+ struct idr ipcs_idr;
+};
+
+/*
+ * Structure that holds the parameters needed by the ipc operations
+ * (see after)
+ */
+struct ipc_params {
+ key_t key;
+ int flg;
+ union {
+ size_t size; /* for shared memories */
+ int nsems; /* for semaphores */
+ } u; /* holds the getnew() specific param */
+};
+
+/*
+ * Structure that holds some ipc operations. This structure is used to unify
+ * the calls to sys_msgget(), sys_semget(), sys_shmget()
+ * . routine to call to create a new ipc object. Can be one of newque,
+ * newary, newseg
+ * . routine to call to check permissions for a new ipc object.
+ * Can be one of security_msg_associate, security_sem_associate,
+ * security_shm_associate
+ * . routine to call for an extra check if needed
+ */
+struct ipc_ops {
+ int (*getnew) (struct ipc_namespace *, struct ipc_params *);
+ int (*associate) (struct kern_ipc_perm *, int);
+ int (*more_checks) (struct kern_ipc_perm *, struct ipc_params *);
};
struct seq_file;
-void ipc_init_ids(struct ipc_ids *ids, int size);
+void ipc_init_ids(struct ipc_ids *);
#ifdef CONFIG_PROC_FS
void __init ipc_init_proc_interface(const char *path, const char *header,
int ids, int (*show)(struct seq_file *, void *));
@@ -54,14 +79,19 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#define IPC_MSG_IDS 1
#define IPC_SHM_IDS 2
-/* must be called with ids->mutex acquired.*/
-int ipc_findkey(struct ipc_ids* ids, key_t key);
-int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size);
+#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
+
+/* must be called with ids->rw_mutex acquired for writing */
+int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
+
+/* must be called with ids->rw_mutex acquired for reading */
+int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
-struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id);
+void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *);
-int ipcperms (struct kern_ipc_perm *ipcp, short flg);
+/* must be called with ipcp locked */
+int ipcperms(struct kern_ipc_perm *ipcp, short flg);
/* for rare, potentially huge allocations.
* both function can sleep
@@ -79,24 +109,12 @@ void* ipc_rcu_alloc(int size);
void ipc_rcu_getref(void *ptr);
void ipc_rcu_putref(void *ptr);
-static inline void __ipc_fini_ids(struct ipc_ids *ids,
- struct ipc_id_ary *entries)
-{
- if (entries != &ids->nullentry)
- ipc_rcu_putref(entries);
-}
-
-static inline void ipc_fini_ids(struct ipc_ids *ids)
-{
- __ipc_fini_ids(ids, ids->entries);
-}
-
-struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id);
-struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id);
-void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp);
-void ipc_unlock(struct kern_ipc_perm* perm);
-int ipc_buildid(struct ipc_ids* ids, int id, int seq);
-int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid);
+/*
+ * ipc_lock_down: called with rw_mutex held
+ * ipc_lock: called without that lock held
+ */
+struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int);
+struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int);
void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out);
void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out);
@@ -111,5 +129,89 @@ int ipc_parse_version (int *cmd);
extern void free_msg(struct msg_msg *msg);
extern struct msg_msg *load_msg(const void __user *src, int len);
extern int store_msg(void __user *dest, struct msg_msg *msg, int len);
+extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *,
+ struct ipc_ops *, struct ipc_params *);
+extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *,
+ struct ipc_ops *, struct ipc_params *);
+
+static inline int ipc_buildid(int id, int seq)
+{
+ return SEQ_MULTIPLIER * seq + id;
+}
+
+/*
+ * Must be called with ipcp locked
+ */
+static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid)
+{
+ if (uid / SEQ_MULTIPLIER != ipcp->seq)
+ return 1;
+ return 0;
+}
+
+static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm)
+{
+ rcu_read_lock();
+ spin_lock(&perm->lock);
+}
+
+static inline void ipc_unlock(struct kern_ipc_perm *perm)
+{
+ spin_unlock(&perm->lock);
+ rcu_read_unlock();
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids,
+ int id)
+{
+ struct kern_ipc_perm *out;
+
+ out = ipc_lock_down(ids, id);
+ if (IS_ERR(out))
+ return out;
+
+ if (ipc_checkid(out, id)) {
+ ipc_unlock(out);
+ return ERR_PTR(-EIDRM);
+ }
+
+ return out;
+}
+
+static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids,
+ int id)
+{
+ struct kern_ipc_perm *out;
+
+ out = ipc_lock(ids, id);
+ if (IS_ERR(out))
+ return out;
+
+ if (ipc_checkid(out, id)) {
+ ipc_unlock(out);
+ return ERR_PTR(-EIDRM);
+ }
+
+ return out;
+}
+
+/**
+ * ipcget - Common sys_*get() code
+ * @ns : namsepace
+ * @ids : IPC identifier set
+ * @ops : operations to be called on ipc object creation, permission checks
+ * and further checks
+ * @params : the parameters needed by the previous operations.
+ *
+ * Common routine called by sys_msgget(), sys_semget() and sys_shmget().
+ */
+static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
+ struct ipc_ops *ops, struct ipc_params *params)
+{
+ if (params->key == IPC_PRIVATE)
+ return ipcget_new(ns, ids, ops, params);
+ else
+ return ipcget_public(ns, ids, ops, params);
+}
#endif
diff --git a/kernel/Kconfig.instrumentation b/kernel/Kconfig.instrumentation
new file mode 100644
index 00000000000..f5f2c769d95
--- /dev/null
+++ b/kernel/Kconfig.instrumentation
@@ -0,0 +1,49 @@
+menuconfig INSTRUMENTATION
+ bool "Instrumentation Support"
+ default y
+ ---help---
+ Say Y here to get to see options related to performance measurement,
+ system-wide debugging, and testing. This option alone does not add any
+ kernel code.
+
+ If you say N, all options in this submenu will be skipped and
+ disabled. If you're trying to debug the kernel itself, go see the
+ Kernel Hacking menu.
+
+if INSTRUMENTATION
+
+config PROFILING
+ bool "Profiling support (EXPERIMENTAL)"
+ help
+ Say Y here to enable the extended profiling support mechanisms used
+ by profilers such as OProfile.
+
+config OPROFILE
+ tristate "OProfile system profiling (EXPERIMENTAL)"
+ depends on PROFILING
+ depends on ALPHA || ARM || BLACKFIN || X86_32 || IA64 || M32R || MIPS || PARISC || PPC || S390 || SUPERH || SPARC || X86_64
+ help
+ OProfile is a profiling system capable of profiling the
+ whole system, include the kernel, kernel modules, libraries,
+ and applications.
+
+ If unsure, say N.
+
+config KPROBES
+ bool "Kprobes"
+ depends on KALLSYMS && MODULES
+ depends on X86_32 || IA64 || PPC || S390 || SPARC64 || X86_64 || AVR32
+ help
+ Kprobes allows you to trap at almost any kernel address and
+ execute a callback function. register_kprobe() establishes
+ a probepoint and specifies the callback. Kprobes is useful
+ for kernel debugging, non-intrusive instrumentation and testing.
+ If in doubt, say "N".
+
+config MARKERS
+ bool "Activate markers"
+ help
+ Place an empty function call at each marker site. Can be
+ dynamically changed for a probe function.
+
+endif # INSTRUMENTATION
diff --git a/kernel/Makefile b/kernel/Makefile
index d63fbb18798..f60afe74259 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -8,9 +8,10 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
signal.o sys.o kmod.o workqueue.o pid.o \
rcupdate.o extable.o params.o posix-timers.o \
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
- hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \
- utsname.o sysctl_check.o
+ hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \
+ utsname.o notifier.o
+obj-$(CONFIG_SYSCTL) += sysctl_check.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += time/
obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
@@ -36,11 +37,16 @@ obj-$(CONFIG_PM) += power/
obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_COMPAT) += compat.o
+obj-$(CONFIG_CGROUPS) += cgroup.o
+obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
obj-$(CONFIG_CPUSETS) += cpuset.o
+obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o
+obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
obj-$(CONFIG_IKCONFIG) += configs.o
obj-$(CONFIG_STOP_MACHINE) += stop_machine.o
obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
+obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_SYSFS) += ksysfs.o
obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o
@@ -51,6 +57,7 @@ obj-$(CONFIG_RELAY) += relay.o
obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+obj-$(CONFIG_MARKERS) += marker.o
ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
# According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
diff --git a/kernel/audit.c b/kernel/audit.c
index 6977ea57a7e..f93c2713017 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -468,6 +468,21 @@ int audit_send_list(void *_dest)
return 0;
}
+#ifdef CONFIG_AUDIT_TREE
+static int prune_tree_thread(void *unused)
+{
+ mutex_lock(&audit_cmd_mutex);
+ audit_prune_trees();
+ mutex_unlock(&audit_cmd_mutex);
+ return 0;
+}
+
+void audit_schedule_prune(void)
+{
+ kthread_run(prune_tree_thread, NULL, "audit_prune_tree");
+}
+#endif
+
struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
int multi, void *payload, int size)
{
@@ -540,6 +555,8 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_SIGNAL_INFO:
case AUDIT_TTY_GET:
case AUDIT_TTY_SET:
+ case AUDIT_TRIM:
+ case AUDIT_MAKE_EQUIV:
if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
err = -EPERM;
break;
@@ -756,6 +773,76 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
uid, seq, data, nlmsg_len(nlh),
loginuid, sid);
break;
+ case AUDIT_TRIM:
+ audit_trim_trees();
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ if (!ab)
+ break;
+ audit_log_format(ab, "auid=%u", loginuid);
+ if (sid) {
+ u32 len;
+ ctx = NULL;
+ if (selinux_sid_to_string(sid, &ctx, &len))
+ audit_log_format(ab, " ssid=%u", sid);
+ else
+ audit_log_format(ab, " subj=%s", ctx);
+ kfree(ctx);
+ }
+ audit_log_format(ab, " op=trim res=1");
+ audit_log_end(ab);
+ break;
+ case AUDIT_MAKE_EQUIV: {
+ void *bufp = data;
+ u32 sizes[2];
+ size_t len = nlmsg_len(nlh);
+ char *old, *new;
+
+ err = -EINVAL;
+ if (len < 2 * sizeof(u32))
+ break;
+ memcpy(sizes, bufp, 2 * sizeof(u32));
+ bufp += 2 * sizeof(u32);
+ len -= 2 * sizeof(u32);
+ old = audit_unpack_string(&bufp, &len, sizes[0]);
+ if (IS_ERR(old)) {
+ err = PTR_ERR(old);
+ break;
+ }
+ new = audit_unpack_string(&bufp, &len, sizes[1]);
+ if (IS_ERR(new)) {
+ err = PTR_ERR(new);
+ kfree(old);
+ break;
+ }
+ /* OK, here comes... */
+ err = audit_tag_tree(old, new);
+
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ if (!ab) {
+ kfree(old);
+ kfree(new);
+ break;
+ }
+ audit_log_format(ab, "auid=%u", loginuid);
+ if (sid) {
+ u32 len;
+ ctx = NULL;
+ if (selinux_sid_to_string(sid, &ctx, &len))
+ audit_log_format(ab, " ssid=%u", sid);
+ else
+ audit_log_format(ab, " subj=%s", ctx);
+ kfree(ctx);
+ }
+ audit_log_format(ab, " op=make_equiv old=");
+ audit_log_untrustedstring(ab, old);
+ audit_log_format(ab, " new=");
+ audit_log_untrustedstring(ab, new);
+ audit_log_format(ab, " res=%d", !err);
+ audit_log_end(ab);
+ kfree(old);
+ kfree(new);
+ break;
+ }
case AUDIT_SIGNAL_INFO:
err = selinux_sid_to_string(audit_sig_sid, &ctx, &len);
if (err)
diff --git a/kernel/audit.h b/kernel/audit.h
index 95877435c34..2554bd524fd 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -73,6 +73,9 @@ struct audit_field {
struct selinux_audit_rule *se_rule;
};
+struct audit_tree;
+struct audit_chunk;
+
struct audit_krule {
int vers_ops;
u32 flags;
@@ -86,7 +89,8 @@ struct audit_krule {
struct audit_field *arch_f; /* quick access to arch field */
struct audit_field *inode_f; /* quick access to an inode field */
struct audit_watch *watch; /* associated watch */
- struct list_head rlist; /* entry in audit_watch.rules list */
+ struct audit_tree *tree; /* associated watched tree */
+ struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
};
struct audit_entry {
@@ -130,6 +134,34 @@ extern void audit_handle_ievent(struct inotify_watch *, u32, u32, u32,
const char *, struct inode *);
extern int selinux_audit_rule_update(void);
+extern struct mutex audit_filter_mutex;
+extern void audit_free_rule_rcu(struct rcu_head *);
+
+#ifdef CONFIG_AUDIT_TREE
+extern struct audit_chunk *audit_tree_lookup(const struct inode *);
+extern void audit_put_chunk(struct audit_chunk *);
+extern int audit_tree_match(struct audit_chunk *, struct audit_tree *);
+extern int audit_make_tree(struct audit_krule *, char *, u32);
+extern int audit_add_tree_rule(struct audit_krule *);
+extern int audit_remove_tree_rule(struct audit_krule *);
+extern void audit_trim_trees(void);
+extern int audit_tag_tree(char *old, char *new);
+extern void audit_schedule_prune(void);
+extern void audit_prune_trees(void);
+extern const char *audit_tree_path(struct audit_tree *);
+extern void audit_put_tree(struct audit_tree *);
+#else
+#define audit_remove_tree_rule(rule) BUG()
+#define audit_add_tree_rule(rule) -EINVAL
+#define audit_make_tree(rule, str, op) -EINVAL
+#define audit_trim_trees() (void)0
+#define audit_put_tree(tree) (void)0
+#define audit_tag_tree(old, new) -EINVAL
+#define audit_tree_path(rule) "" /* never called */
+#endif
+
+extern char *audit_unpack_string(void **, size_t *, size_t);
+
#ifdef CONFIG_AUDITSYSCALL
extern int __audit_signal_info(int sig, struct task_struct *t);
static inline int audit_signal_info(int sig, struct task_struct *t)
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c
new file mode 100644
index 00000000000..f4fcf58f20f
--- /dev/null
+++ b/kernel/audit_tree.c
@@ -0,0 +1,903 @@
+#include "audit.h"
+#include <linux/inotify.h>
+#include <linux/namei.h>
+#include <linux/mount.h>
+
+struct audit_tree;
+struct audit_chunk;
+
+struct audit_tree {
+ atomic_t count;
+ int goner;
+ struct audit_chunk *root;
+ struct list_head chunks;
+ struct list_head rules;
+ struct list_head list;
+ struct list_head same_root;
+ struct rcu_head head;
+ char pathname[];
+};
+
+struct audit_chunk {
+ struct list_head hash;
+ struct inotify_watch watch;
+ struct list_head trees; /* with root here */
+ int dead;
+ int count;
+ struct rcu_head head;
+ struct node {
+ struct list_head list;
+ struct audit_tree *owner;
+ unsigned index; /* index; upper bit indicates 'will prune' */
+ } owners[];
+};
+
+static LIST_HEAD(tree_list);
+static LIST_HEAD(prune_list);
+
+/*
+ * One struct chunk is attached to each inode of interest.
+ * We replace struct chunk on tagging/untagging.
+ * Rules have pointer to struct audit_tree.
+ * Rules have struct list_head rlist forming a list of rules over
+ * the same tree.
+ * References to struct chunk are collected at audit_inode{,_child}()
+ * time and used in AUDIT_TREE rule matching.
+ * These references are dropped at the same time we are calling
+ * audit_free_names(), etc.
+ *
+ * Cyclic lists galore:
+ * tree.chunks anchors chunk.owners[].list hash_lock
+ * tree.rules anchors rule.rlist audit_filter_mutex
+ * chunk.trees anchors tree.same_root hash_lock
+ * chunk.hash is a hash with middle bits of watch.inode as
+ * a hash function. RCU, hash_lock
+ *
+ * tree is refcounted; one reference for "some rules on rules_list refer to
+ * it", one for each chunk with pointer to it.
+ *
+ * chunk is refcounted by embedded inotify_watch.
+ *
+ * node.index allows to get from node.list to containing chunk.
+ * MSB of that sucker is stolen to mark taggings that we might have to
+ * revert - several operations have very unpleasant cleanup logics and
+ * that makes a difference. Some.
+ */
+
+static struct inotify_handle *rtree_ih;
+
+static struct audit_tree *alloc_tree(const char *s)
+{
+ struct audit_tree *tree;
+
+ tree = kmalloc(sizeof(struct audit_tree) + strlen(s) + 1, GFP_KERNEL);
+ if (tree) {
+ atomic_set(&tree->count, 1);
+ tree->goner = 0;
+ INIT_LIST_HEAD(&tree->chunks);
+ INIT_LIST_HEAD(&tree->rules);
+ INIT_LIST_HEAD(&tree->list);
+ INIT_LIST_HEAD(&tree->same_root);
+ tree->root = NULL;
+ strcpy(tree->pathname, s);
+ }
+ return tree;
+}
+
+static inline void get_tree(struct audit_tree *tree)
+{
+ atomic_inc(&tree->count);
+}
+
+static void __put_tree(struct rcu_head *rcu)
+{
+ struct audit_tree *tree = container_of(rcu, struct audit_tree, head);
+ kfree(tree);
+}
+
+static inline void put_tree(struct audit_tree *tree)
+{
+ if (atomic_dec_and_test(&tree->count))
+ call_rcu(&tree->head, __put_tree);
+}
+
+/* to avoid bringing the entire thing in audit.h */
+const char *audit_tree_path(struct audit_tree *tree)
+{
+ return tree->pathname;
+}
+
+static struct audit_chunk *alloc_chunk(int count)
+{
+ struct audit_chunk *chunk;
+ size_t size;
+ int i;
+
+ size = offsetof(struct audit_chunk, owners) + count * sizeof(struct node);
+ chunk = kzalloc(size, GFP_KERNEL);
+ if (!chunk)
+ return NULL;
+
+ INIT_LIST_HEAD(&chunk->hash);
+ INIT_LIST_HEAD(&chunk->trees);
+ chunk->count = count;
+ for (i = 0; i < count; i++) {
+ INIT_LIST_HEAD(&chunk->owners[i].list);
+ chunk->owners[i].index = i;
+ }
+ inotify_init_watch(&chunk->watch);
+ return chunk;
+}
+
+static void __free_chunk(struct rcu_head *rcu)
+{
+ struct audit_chunk *chunk = container_of(rcu, struct audit_chunk, head);
+ int i;
+
+ for (i = 0; i < chunk->count; i++) {
+ if (chunk->owners[i].owner)
+ put_tree(chunk->owners[i].owner);
+ }
+ kfree(chunk);
+}
+
+static inline void free_chunk(struct audit_chunk *chunk)
+{
+ call_rcu(&chunk->head, __free_chunk);
+}
+
+void audit_put_chunk(struct audit_chunk *chunk)
+{
+ put_inotify_watch(&chunk->watch);
+}
+
+enum {HASH_SIZE = 128};
+static struct list_head chunk_hash_heads[HASH_SIZE];
+static __cacheline_aligned_in_smp DEFINE_SPINLOCK(hash_lock);
+
+static inline struct list_head *chunk_hash(const struct inode *inode)
+{
+ unsigned long n = (unsigned long)inode / L1_CACHE_BYTES;
+ return chunk_hash_heads + n % HASH_SIZE;
+}
+
+/* hash_lock is held by caller */
+static void insert_hash(struct audit_chunk *chunk)
+{
+ struct list_head *list = chunk_hash(chunk->watch.inode);
+ list_add_rcu(&chunk->hash, list);
+}
+
+/* called under rcu_read_lock */
+struct audit_chunk *audit_tree_lookup(const struct inode *inode)
+{
+ struct list_head *list = chunk_hash(inode);
+ struct list_head *pos;
+
+ list_for_each_rcu(pos, list) {
+ struct audit_chunk *p = container_of(pos, struct audit_chunk, hash);
+ if (p->watch.inode == inode) {
+ get_inotify_watch(&p->watch);
+ return p;
+ }
+ }
+ return NULL;
+}
+
+int audit_tree_match(struct audit_chunk *chunk, struct audit_tree *tree)
+{
+ int n;
+ for (n = 0; n < chunk->count; n++)
+ if (chunk->owners[n].owner == tree)
+ return 1;
+ return 0;
+}
+
+/* tagging and untagging inodes with trees */
+
+static void untag_chunk(struct audit_chunk *chunk, struct node *p)
+{
+ struct audit_chunk *new;
+ struct audit_tree *owner;
+ int size = chunk->count - 1;
+ int i, j;
+
+ mutex_lock(&chunk->watch.inode->inotify_mutex);
+ if (chunk->dead) {
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+ return;
+ }
+
+ owner = p->owner;
+
+ if (!size) {
+ chunk->dead = 1;
+ spin_lock(&hash_lock);
+ list_del_init(&chunk->trees);
+ if (owner->root == chunk)
+ owner->root = NULL;
+ list_del_init(&p->list);
+ list_del_rcu(&chunk->hash);
+ spin_unlock(&hash_lock);
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+ return;
+ }
+
+ new = alloc_chunk(size);
+ if (!new)
+ goto Fallback;
+ if (inotify_clone_watch(&chunk->watch, &new->watch) < 0) {
+ free_chunk(new);
+ goto Fallback;
+ }
+
+ chunk->dead = 1;
+ spin_lock(&hash_lock);
+ list_replace_init(&chunk->trees, &new->trees);
+ if (owner->root == chunk) {
+ list_del_init(&owner->same_root);
+ owner->root = NULL;
+ }
+
+ for (i = j = 0; i < size; i++, j++) {
+ struct audit_tree *s;
+ if (&chunk->owners[j] == p) {
+ list_del_init(&p->list);
+ i--;
+ continue;
+ }
+ s = chunk->owners[j].owner;
+ new->owners[i].owner = s;
+ new->owners[i].index = chunk->owners[j].index - j + i;
+ if (!s) /* result of earlier fallback */
+ continue;
+ get_tree(s);
+ list_replace_init(&chunk->owners[i].list, &new->owners[j].list);
+ }
+
+ list_replace_rcu(&chunk->hash, &new->hash);
+ list_for_each_entry(owner, &new->trees, same_root)
+ owner->root = new;
+ spin_unlock(&hash_lock);
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+ return;
+
+Fallback:
+ // do the best we can
+ spin_lock(&hash_lock);
+ if (owner->root == chunk) {
+ list_del_init(&owner->same_root);
+ owner->root = NULL;
+ }
+ list_del_init(&p->list);
+ p->owner = NULL;
+ put_tree(owner);
+ spin_unlock(&hash_lock);
+ mutex_unlock(&chunk->watch.inode->inotify_mutex);
+}
+
+static int create_chunk(struct inode *inode, struct audit_tree *tree)
+{
+ struct audit_chunk *chunk = alloc_chunk(1);
+ if (!chunk)
+ return -ENOMEM;
+
+ if (inotify_add_watch(rtree_ih, &chunk->watch, inode, IN_IGNORED | IN_DELETE_SELF) < 0) {
+ free_chunk(chunk);
+ return -ENOSPC;
+ }
+
+ mutex_lock(&inode->inotify_mutex);
+ spin_lock(&hash_lock);
+ if (tree->goner) {
+ spin_unlock(&hash_lock);
+ chunk->dead = 1;
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+ return 0;
+ }
+ chunk->owners[0].index = (1U << 31);
+ chunk->owners[0].owner = tree;
+ get_tree(tree);
+ list_add(&chunk->owners[0].list, &tree->chunks);
+ if (!tree->root) {
+ tree->root = chunk;
+ list_add(&tree->same_root, &chunk->trees);
+ }
+ insert_hash(chunk);
+ spin_unlock(&hash_lock);
+ mutex_unlock(&inode->inotify_mutex);
+ return 0;
+}
+
+/* the first tagged inode becomes root of tree */
+static int tag_chunk(struct inode *inode, struct audit_tree *tree)
+{
+ struct inotify_watch *watch;
+ struct audit_tree *owner;
+ struct audit_chunk *chunk, *old;
+ struct node *p;
+ int n;
+
+ if (inotify_find_watch(rtree_ih, inode, &watch) < 0)
+ return create_chunk(inode, tree);
+
+ old = container_of(watch, struct audit_chunk, watch);
+
+ /* are we already there? */
+ spin_lock(&hash_lock);
+ for (n = 0; n < old->count; n++) {
+ if (old->owners[n].owner == tree) {
+ spin_unlock(&hash_lock);
+ put_inotify_watch(watch);
+ return 0;
+ }
+ }
+ spin_unlock(&hash_lock);
+
+ chunk = alloc_chunk(old->count + 1);
+ if (!chunk)
+ return -ENOMEM;
+
+ mutex_lock(&inode->inotify_mutex);
+ if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) {
+ mutex_unlock(&inode->inotify_mutex);
+ free_chunk(chunk);
+ return -ENOSPC;
+ }
+ spin_lock(&hash_lock);
+ if (tree->goner) {
+ spin_unlock(&hash_lock);
+ chunk->dead = 1;
+ inotify_evict_watch(&chunk->watch);
+ mutex_unlock(&inode->inotify_mutex);
+ put_inotify_watch(&chunk->watch);
+ return 0;
+ }
+ list_replace_init(&old->trees, &chunk->trees);
+ for (n = 0, p = chunk->owners; n < old->count; n++, p++) {
+ struct audit_tree *s = old->owners[n].owner;
+ p->owner = s;
+ p->index = old->owners[n].index;
+ if (!s) /* result of fallback in untag */
+ continue;
+ get_tree(s);
+ list_replace_init(&old->owners[n].list, &p->list);
+ }
+ p->index = (chunk->count - 1) | (1U<<31);
+ p->owner = tree;
+ get_tree(tree);
+ list_add(&p->list, &tree->chunks);
+ list_replace_rcu(&old->hash, &chunk->hash);
+ list_for_each_entry(owner, &chunk->trees, same_root)
+ owner->root = chunk;
+ old->dead = 1;
+ if (!tree->root) {
+ tree->root = chunk;
+ list_add(&tree->same_root, &chunk->trees);
+ }
+ spin_unlock(&hash_lock);
+ inotify_evict_watch(&old->watch);
+ mutex_unlock(&inode->inotify_mutex);
+ put_inotify_watch(&old->watch);
+ return 0;
+}
+
+static struct audit_chunk *find_chunk(struct node *p)
+{
+ int index = p->index & ~(1U<<31);
+ p -= index;
+ return container_of(p, struct audit_chunk, owners[0]);
+}
+
+static void kill_rules(struct audit_tree *tree)
+{
+ struct audit_krule *rule, *next;
+ struct audit_entry *entry;
+ struct audit_buffer *ab;
+
+ list_for_each_entry_safe(rule, next, &tree->rules, rlist) {
+ entry = container_of(rule, struct audit_entry, rule);
+
+ list_del_init(&rule->rlist);
+ if (rule->tree) {
+ /* not a half-baked one */
+ ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
+ audit_log_format(ab, "op=remove rule dir=");
+ audit_log_untrustedstring(ab, rule->tree->pathname);
+ if (rule->filterkey) {
+ audit_log_format(ab, " key=");
+ audit_log_untrustedstring(ab, rule->filterkey);
+ } else
+ audit_log_format(ab, " key=(null)");
+ audit_log_format(ab, " list=%d res=1", rule->listnr);
+ audit_log_end(ab);
+ rule->tree = NULL;
+ list_del_rcu(&entry->list);
+ call_rcu(&entry->rcu, audit_free_rule_rcu);
+ }
+ }
+}
+
+/*
+ * finish killing struct audit_tree
+ */
+static void prune_one(struct audit_tree *victim)
+{
+ spin_lock(&hash_lock);
+ while (!list_empty(&victim->chunks)) {
+ struct node *p;
+ struct audit_chunk *chunk;
+
+ p = list_entry(victim->chunks.next, struct node, list);
+ chunk = find_chunk(p);
+ get_inotify_watch(&chunk->watch);
+ spin_unlock(&hash_lock);
+
+ untag_chunk(chunk, p);
+
+ put_inotify_watch(&chunk->watch);
+ spin_lock(&hash_lock);
+ }
+ spin_unlock(&hash_lock);
+ put_tree(victim);
+}
+
+/* trim the uncommitted chunks from tree */
+
+static void trim_marked(struct audit_tree *tree)
+{
+ struct list_head *p, *q;
+ spin_lock(&hash_lock);
+ if (tree->goner) {
+ spin_unlock(&hash_lock);
+ return;
+ }
+ /* reorder */
+ for (p = tree->chunks.next; p != &tree->chunks; p = q) {
+ struct node *node = list_entry(p, struct node, list);
+ q = p->next;
+ if (node->index & (1U<<31)) {
+ list_del_init(p);
+ list_add(p, &tree->chunks);
+ }
+ }
+
+ while (!list_empty(&tree->chunks)) {
+ struct node *node;
+ struct audit_chunk *chunk;
+
+ node = list_entry(tree->chunks.next, struct node, list);
+
+ /* have we run out of marked? */
+ if (!(node->index & (1U<<31)))
+ break;
+
+ chunk = find_chunk(node);
+ get_inotify_watch(&chunk->watch);
+ spin_unlock(&hash_lock);
+
+ untag_chunk(chunk, node);
+
+ put_inotify_watch(&chunk->watch);
+ spin_lock(&hash_lock);
+ }
+ if (!tree->root && !tree->goner) {
+ tree->goner = 1;
+ spin_unlock(&hash_lock);
+ mutex_lock(&audit_filter_mutex);
+ kill_rules(tree);
+ list_del_init(&tree->list);
+ mutex_unlock(&audit_filter_mutex);
+ prune_one(tree);
+ } else {
+ spin_unlock(&hash_lock);
+ }
+}
+
+/* called with audit_filter_mutex */
+int audit_remove_tree_rule(struct audit_krule *rule)
+{
+ struct audit_tree *tree;
+ tree = rule->tree;
+ if (tree) {
+ spin_lock(&hash_lock);
+ list_del_init(&rule->rlist);
+ if (list_empty(&tree->rules) && !tree->goner) {
+ tree->root = NULL;
+ list_del_init(&tree->same_root);
+ tree->goner = 1;
+ list_move(&tree->list, &prune_list);
+ rule->tree = NULL;
+ spin_unlock(&hash_lock);
+ audit_schedule_prune();
+ return 1;
+ }
+ rule->tree = NULL;
+ spin_unlock(&hash_lock);
+ return 1;
+ }
+ return 0;
+}
+
+void audit_trim_trees(void)
+{
+ struct list_head cursor;
+
+ mutex_lock(&audit_filter_mutex);
+ list_add(&cursor, &tree_list);
+ while (cursor.next != &tree_list) {
+ struct audit_tree *tree;
+ struct nameidata nd;
+ struct vfsmount *root_mnt;
+ struct node *node;
+ struct list_head list;
+ int err;
+
+ tree = container_of(cursor.next, struct audit_tree, list);
+ get_tree(tree);
+ list_del(&cursor);
+ list_add(&cursor, &tree->list);
+ mutex_unlock(&audit_filter_mutex);
+
+ err = path_lookup(tree->pathname, 0, &nd);
+ if (err)
+ goto skip_it;
+
+ root_mnt = collect_mounts(nd.mnt, nd.dentry);
+ path_release(&nd);
+ if (!root_mnt)
+ goto skip_it;
+
+ list_add_tail(&list, &root_mnt->mnt_list);
+ spin_lock(&hash_lock);
+ list_for_each_entry(node, &tree->chunks, list) {
+ struct audit_chunk *chunk = find_chunk(node);
+ struct inode *inode = chunk->watch.inode;
+ struct vfsmount *mnt;
+ node->index |= 1U<<31;
+ list_for_each_entry(mnt, &list, mnt_list) {
+ if (mnt->mnt_root->d_inode == inode) {
+ node->index &= ~(1U<<31);
+ break;
+ }
+ }
+ }
+ spin_unlock(&hash_lock);
+ trim_marked(tree);
+ put_tree(tree);
+ list_del_init(&list);
+ drop_collected_mounts(root_mnt);
+skip_it:
+ mutex_lock(&audit_filter_mutex);
+ }
+ list_del(&cursor);
+ mutex_unlock(&audit_filter_mutex);
+}
+
+static int is_under(struct vfsmount *mnt, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ if (mnt != nd->mnt) {
+ for (;;) {
+ if (mnt->mnt_parent == mnt)
+ return 0;
+ if (mnt->mnt_parent == nd->mnt)
+ break;
+ mnt = mnt->mnt_parent;
+ }
+ dentry = mnt->mnt_mountpoint;
+ }
+ return is_subdir(dentry, nd->dentry);
+}
+
+int audit_make_tree(struct audit_krule *rule, char *pathname, u32 op)
+{
+
+ if (pathname[0] != '/' ||
+ rule->listnr != AUDIT_FILTER_EXIT ||
+ op & ~AUDIT_EQUAL ||
+ rule->inode_f || rule->watch || rule->tree)
+ return -EINVAL;
+ rule->tree = alloc_tree(pathname);
+ if (!rule->tree)
+ return -ENOMEM;
+ return 0;
+}
+
+void audit_put_tree(struct audit_tree *tree)
+{
+ put_tree(tree);
+}
+
+/* called with audit_filter_mutex */
+int audit_add_tree_rule(struct audit_krule *rule)
+{
+ struct audit_tree *seed = rule->tree, *tree;
+ struct nameidata nd;
+ struct vfsmount *mnt, *p;
+ struct list_head list;
+ int err;
+
+ list_for_each_entry(tree, &tree_list, list) {
+ if (!strcmp(seed->pathname, tree->pathname)) {
+ put_tree(seed);
+ rule->tree = tree;
+ list_add(&rule->rlist, &tree->rules);
+ return 0;
+ }
+ }
+ tree = seed;
+ list_add(&tree->list, &tree_list);
+ list_add(&rule->rlist, &tree->rules);
+ /* do not set rule->tree yet */
+ mutex_unlock(&audit_filter_mutex);
+
+ err = path_lookup(tree->pathname, 0, &nd);
+ if (err)
+ goto Err;
+ mnt = collect_mounts(nd.mnt, nd.dentry);
+ path_release(&nd);
+ if (!mnt) {
+ err = -ENOMEM;
+ goto Err;
+ }
+ list_add_tail(&list, &mnt->mnt_list);
+
+ get_tree(tree);
+ list_for_each_entry(p, &list, mnt_list) {
+ err = tag_chunk(p->mnt_root->d_inode, tree);
+ if (err)
+ break;
+ }
+
+ list_del(&list);
+ drop_collected_mounts(mnt);
+
+ if (!err) {
+ struct node *node;
+ spin_lock(&hash_lock);
+ list_for_each_entry(node, &tree->chunks, list)
+ node->index &= ~(1U<<31);
+ spin_unlock(&hash_lock);
+ } else {
+ trim_marked(tree);
+ goto Err;
+ }
+
+ mutex_lock(&audit_filter_mutex);
+ if (list_empty(&rule->rlist)) {
+ put_tree(tree);
+ return -ENOENT;
+ }
+ rule->tree = tree;
+ put_tree(tree);
+
+ return 0;
+Err:
+ mutex_lock(&audit_filter_mutex);
+ list_del_init(&tree->list);
+ list_del_init(&tree->rules);
+ put_tree(tree);
+ return err;
+}
+
+int audit_tag_tree(char *old, char *new)
+{
+ struct list_head cursor, barrier;
+ int failed = 0;
+ struct nameidata nd;
+ struct vfsmount *tagged;
+ struct list_head list;
+ struct vfsmount *mnt;
+ struct dentry *dentry;
+ int err;
+
+ err = path_lookup(new, 0, &nd);
+ if (err)
+ return err;
+ tagged = collect_mounts(nd.mnt, nd.dentry);
+ path_release(&nd);
+ if (!tagged)
+ return -ENOMEM;
+
+ err = path_lookup(old, 0, &nd);
+ if (err) {
+ drop_collected_mounts(tagged);
+ return err;
+ }
+ mnt = mntget(nd.mnt);
+ dentry = dget(nd.dentry);
+ path_release(&nd);
+
+ if (dentry == tagged->mnt_root && dentry == mnt->mnt_root)
+ follow_up(&mnt, &dentry);
+
+ list_add_tail(&list, &tagged->mnt_list);
+
+ mutex_lock(&audit_filter_mutex);
+ list_add(&barrier, &tree_list);
+ list_add(&cursor, &barrier);
+
+ while (cursor.next != &tree_list) {
+ struct audit_tree *tree;
+ struct vfsmount *p;
+
+ tree = container_of(cursor.next, struct audit_tree, list);
+ get_tree(tree);
+ list_del(&cursor);
+ list_add(&cursor, &tree->list);
+ mutex_unlock(&audit_filter_mutex);
+
+ err = path_lookup(tree->pathname, 0, &nd);
+ if (err) {
+ put_tree(tree);
+ mutex_lock(&audit_filter_mutex);
+ continue;
+ }
+
+ spin_lock(&vfsmount_lock);
+ if (!is_under(mnt, dentry, &nd)) {
+ spin_unlock(&vfsmount_lock);
+ path_release(&nd);
+ put_tree(tree);
+ mutex_lock(&audit_filter_mutex);
+ continue;
+ }
+ spin_unlock(&vfsmount_lock);
+ path_release(&nd);
+
+ list_for_each_entry(p, &list, mnt_list) {
+ failed = tag_chunk(p->mnt_root->d_inode, tree);
+ if (failed)
+ break;
+ }
+
+ if (failed) {
+ put_tree(tree);
+ mutex_lock(&audit_filter_mutex);
+ break;
+ }
+
+ mutex_lock(&audit_filter_mutex);
+ spin_lock(&hash_lock);
+ if (!tree->goner) {
+ list_del(&tree->list);
+ list_add(&tree->list, &tree_list);
+ }
+ spin_unlock(&hash_lock);
+ put_tree(tree);
+ }
+
+ while (barrier.prev != &tree_list) {
+ struct audit_tree *tree;
+
+ tree = container_of(barrier.prev, struct audit_tree, list);
+ get_tree(tree);
+ list_del(&tree->list);
+ list_add(&tree->list, &barrier);
+ mutex_unlock(&audit_filter_mutex);
+
+ if (!failed) {
+ struct node *node;
+ spin_lock(&hash_lock);
+ list_for_each_entry(node, &tree->chunks, list)
+ node->index &= ~(1U<<31);
+ spin_unlock(&hash_lock);
+ } else {
+ trim_marked(tree);
+ }
+
+ put_tree(tree);
+ mutex_lock(&audit_filter_mutex);
+ }
+ list_del(&barrier);
+ list_del(&cursor);
+ list_del(&list);
+ mutex_unlock(&audit_filter_mutex);
+ dput(dentry);
+ mntput(mnt);
+ drop_collected_mounts(tagged);
+ return failed;
+}
+
+/*
+ * That gets run when evict_chunk() ends up needing to kill audit_tree.
+ * Runs from a separate thread, with audit_cmd_mutex held.
+ */
+void audit_prune_trees(void)
+{
+ mutex_lock(&audit_filter_mutex);
+
+ while (!list_empty(&prune_list)) {
+ struct audit_tree *victim;
+
+ victim = list_entry(prune_list.next, struct audit_tree, list);
+ list_del_init(&victim->list);
+
+ mutex_unlock(&audit_filter_mutex);
+
+ prune_one(victim);
+
+ mutex_lock(&audit_filter_mutex);
+ }
+
+ mutex_unlock(&audit_filter_mutex);
+}
+
+/*
+ * Here comes the stuff asynchronous to auditctl operations
+ */
+
+/* inode->inotify_mutex is locked */
+static void evict_chunk(struct audit_chunk *chunk)
+{
+ struct audit_tree *owner;
+ int n;
+
+ if (chunk->dead)
+ return;
+
+ chunk->dead = 1;
+ mutex_lock(&audit_filter_mutex);
+ spin_lock(&hash_lock);
+ while (!list_empty(&chunk->trees)) {
+ owner = list_entry(chunk->trees.next,
+ struct audit_tree, same_root);
+ owner->goner = 1;
+ owner->root = NULL;
+ list_del_init(&owner->same_root);
+ spin_unlock(&hash_lock);
+ kill_rules(owner);
+ list_move(&owner->list, &prune_list);
+ audit_schedule_prune();
+ spin_lock(&hash_lock);
+ }
+ list_del_rcu(&chunk->hash);
+ for (n = 0; n < chunk->count; n++)
+ list_del_init(&chunk->owners[n].list);
+ spin_unlock(&hash_lock);
+ mutex_unlock(&audit_filter_mutex);
+}
+
+static void handle_event(struct inotify_watch *watch, u32 wd, u32 mask,
+ u32 cookie, const char *dname, struct inode *inode)
+{
+ struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+
+ if (mask & IN_IGNORED) {
+ evict_chunk(chunk);
+ put_inotify_watch(watch);
+ }
+}
+
+static void destroy_watch(struct inotify_watch *watch)
+{
+ struct audit_chunk *chunk = container_of(watch, struct audit_chunk, watch);
+ free_chunk(chunk);
+}
+
+static const struct inotify_operations rtree_inotify_ops = {
+ .handle_event = handle_event,
+ .destroy_watch = destroy_watch,
+};
+
+static int __init audit_tree_init(void)
+{
+ int i;
+
+ rtree_ih = inotify_init(&rtree_inotify_ops);
+ if (IS_ERR(rtree_ih))
+ audit_panic("cannot initialize inotify handle for rectree watches");
+
+ for (i = 0; i < HASH_SIZE; i++)
+ INIT_LIST_HEAD(&chunk_hash_heads[i]);
+
+ return 0;
+}
+__initcall(audit_tree_init);
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index df66a21fb36..5d96f2cc7be 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -87,7 +87,7 @@ struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
#endif
};
-static DEFINE_MUTEX(audit_filter_mutex);
+DEFINE_MUTEX(audit_filter_mutex);
/* Inotify handle */
extern struct inotify_handle *audit_ih;
@@ -145,7 +145,7 @@ static inline void audit_free_rule(struct audit_entry *e)
kfree(e);
}
-static inline void audit_free_rule_rcu(struct rcu_head *head)
+void audit_free_rule_rcu(struct rcu_head *head)
{
struct audit_entry *e = container_of(head, struct audit_entry, rcu);
audit_free_rule(e);
@@ -217,7 +217,7 @@ static inline struct audit_entry *audit_init_entry(u32 field_count)
/* Unpack a filter field's string representation from user-space
* buffer. */
-static char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
+char *audit_unpack_string(void **bufp, size_t *remain, size_t len)
{
char *str;
@@ -247,7 +247,7 @@ static inline int audit_to_inode(struct audit_krule *krule,
struct audit_field *f)
{
if (krule->listnr != AUDIT_FILTER_EXIT ||
- krule->watch || krule->inode_f)
+ krule->watch || krule->inode_f || krule->tree)
return -EINVAL;
krule->inode_f = f;
@@ -266,7 +266,7 @@ static int audit_to_watch(struct audit_krule *krule, char *path, int len,
if (path[0] != '/' || path[len-1] == '/' ||
krule->listnr != AUDIT_FILTER_EXIT ||
op & ~AUDIT_EQUAL ||
- krule->inode_f || krule->watch) /* 1 inode # per rule, for hash */
+ krule->inode_f || krule->watch || krule->tree)
return -EINVAL;
watch = audit_init_watch(path);
@@ -622,6 +622,17 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data,
goto exit_free;
}
break;
+ case AUDIT_DIR:
+ str = audit_unpack_string(&bufp, &remain, f->val);
+ if (IS_ERR(str))
+ goto exit_free;
+ entry->rule.buflen += f->val;
+
+ err = audit_make_tree(&entry->rule, str, f->op);
+ kfree(str);
+ if (err)
+ goto exit_free;
+ break;
case AUDIT_INODE:
err = audit_to_inode(&entry->rule, f);
if (err)
@@ -668,7 +679,7 @@ exit_free:
}
/* Pack a filter field's string representation into data block. */
-static inline size_t audit_pack_string(void **bufp, char *str)
+static inline size_t audit_pack_string(void **bufp, const char *str)
{
size_t len = strlen(str);
@@ -747,6 +758,11 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule)
data->buflen += data->values[i] =
audit_pack_string(&bufp, krule->watch->path);
break;
+ case AUDIT_DIR:
+ data->buflen += data->values[i] =
+ audit_pack_string(&bufp,
+ audit_tree_path(krule->tree));
+ break;
case AUDIT_FILTERKEY:
data->buflen += data->values[i] =
audit_pack_string(&bufp, krule->filterkey);
@@ -795,6 +811,11 @@ static int audit_compare_rule(struct audit_krule *a, struct audit_krule *b)
if (strcmp(a->watch->path, b->watch->path))
return 1;
break;
+ case AUDIT_DIR:
+ if (strcmp(audit_tree_path(a->tree),
+ audit_tree_path(b->tree)))
+ return 1;
+ break;
case AUDIT_FILTERKEY:
/* both filterkeys exist based on above type compare */
if (strcmp(a->filterkey, b->filterkey))
@@ -897,6 +918,14 @@ static struct audit_entry *audit_dupe_rule(struct audit_krule *old,
new->inode_f = old->inode_f;
new->watch = NULL;
new->field_count = old->field_count;
+ /*
+ * note that we are OK with not refcounting here; audit_match_tree()
+ * never dereferences tree and we can't get false positives there
+ * since we'd have to have rule gone from the list *and* removed
+ * before the chunks found by lookup had been allocated, i.e. before
+ * the beginning of list scan.
+ */
+ new->tree = old->tree;
memcpy(new->fields, old->fields, sizeof(struct audit_field) * fcount);
/* deep copy this information, updating the se_rule fields, because
@@ -1217,6 +1246,7 @@ static inline int audit_add_rule(struct audit_entry *entry,
struct audit_entry *e;
struct audit_field *inode_f = entry->rule.inode_f;
struct audit_watch *watch = entry->rule.watch;
+ struct audit_tree *tree = entry->rule.tree;
struct nameidata *ndp = NULL, *ndw = NULL;
int h, err;
#ifdef CONFIG_AUDITSYSCALL
@@ -1238,6 +1268,9 @@ static inline int audit_add_rule(struct audit_entry *entry,
mutex_unlock(&audit_filter_mutex);
if (e) {
err = -EEXIST;
+ /* normally audit_add_tree_rule() will free it on failure */
+ if (tree)
+ audit_put_tree(tree);
goto error;
}
@@ -1259,6 +1292,13 @@ static inline int audit_add_rule(struct audit_entry *entry,
h = audit_hash_ino((u32)watch->ino);
list = &audit_inode_hash[h];
}
+ if (tree) {
+ err = audit_add_tree_rule(&entry->rule);
+ if (err) {
+ mutex_unlock(&audit_filter_mutex);
+ goto error;
+ }
+ }
if (entry->rule.flags & AUDIT_FILTER_PREPEND) {
list_add_rcu(&entry->list, list);
@@ -1292,6 +1332,7 @@ static inline int audit_del_rule(struct audit_entry *entry,
struct audit_entry *e;
struct audit_field *inode_f = entry->rule.inode_f;
struct audit_watch *watch, *tmp_watch = entry->rule.watch;
+ struct audit_tree *tree = entry->rule.tree;
LIST_HEAD(inotify_list);
int h, ret = 0;
#ifdef CONFIG_AUDITSYSCALL
@@ -1336,6 +1377,9 @@ static inline int audit_del_rule(struct audit_entry *entry,
}
}
+ if (e->rule.tree)
+ audit_remove_tree_rule(&e->rule);
+
list_del_rcu(&e->list);
call_rcu(&e->rcu, audit_free_rule_rcu);
@@ -1354,6 +1398,8 @@ static inline int audit_del_rule(struct audit_entry *entry,
out:
if (tmp_watch)
audit_put_watch(tmp_watch); /* match initial get */
+ if (tree)
+ audit_put_tree(tree); /* that's the temporary one */
return ret;
}
@@ -1737,6 +1783,7 @@ int selinux_audit_rule_update(void)
{
struct audit_entry *entry, *n, *nentry;
struct audit_watch *watch;
+ struct audit_tree *tree;
int i, err = 0;
/* audit_filter_mutex synchronizes the writers */
@@ -1748,6 +1795,7 @@ int selinux_audit_rule_update(void)
continue;
watch = entry->rule.watch;
+ tree = entry->rule.tree;
nentry = audit_dupe_rule(&entry->rule, watch);
if (unlikely(IS_ERR(nentry))) {
/* save the first error encountered for the
@@ -1763,7 +1811,9 @@ int selinux_audit_rule_update(void)
list_add(&nentry->rule.rlist,
&watch->rules);
list_del(&entry->rule.rlist);
- }
+ } else if (tree)
+ list_replace_init(&entry->rule.rlist,
+ &nentry->rule.rlist);
list_replace_rcu(&entry->list, &nentry->list);
}
call_rcu(&entry->rcu, audit_free_rule_rcu);
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index e19b5a33aed..bce9ecdb771 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -65,6 +65,7 @@
#include <linux/binfmts.h>
#include <linux/highmem.h>
#include <linux/syscalls.h>
+#include <linux/inotify.h>
#include "audit.h"
@@ -179,6 +180,11 @@ struct audit_aux_data_pids {
int pid_count;
};
+struct audit_tree_refs {
+ struct audit_tree_refs *next;
+ struct audit_chunk *c[31];
+};
+
/* The per-task audit context. */
struct audit_context {
int dummy; /* must be the first element */
@@ -211,6 +217,9 @@ struct audit_context {
pid_t target_pid;
u32 target_sid;
+ struct audit_tree_refs *trees, *first_trees;
+ int tree_count;
+
#if AUDIT_DEBUG
int put_count;
int ino_count;
@@ -265,6 +274,117 @@ static int audit_match_perm(struct audit_context *ctx, int mask)
}
}
+/*
+ * We keep a linked list of fixed-sized (31 pointer) arrays of audit_chunk *;
+ * ->first_trees points to its beginning, ->trees - to the current end of data.
+ * ->tree_count is the number of free entries in array pointed to by ->trees.
+ * Original condition is (NULL, NULL, 0); as soon as it grows we never revert to NULL,
+ * "empty" becomes (p, p, 31) afterwards. We don't shrink the list (and seriously,
+ * it's going to remain 1-element for almost any setup) until we free context itself.
+ * References in it _are_ dropped - at the same time we free/drop aux stuff.
+ */
+
+#ifdef CONFIG_AUDIT_TREE
+static int put_tree_ref(struct audit_context *ctx, struct audit_chunk *chunk)
+{
+ struct audit_tree_refs *p = ctx->trees;
+ int left = ctx->tree_count;
+ if (likely(left)) {
+ p->c[--left] = chunk;
+ ctx->tree_count = left;
+ return 1;
+ }
+ if (!p)
+ return 0;
+ p = p->next;
+ if (p) {
+ p->c[30] = chunk;
+ ctx->trees = p;
+ ctx->tree_count = 30;
+ return 1;
+ }
+ return 0;
+}
+
+static int grow_tree_refs(struct audit_context *ctx)
+{
+ struct audit_tree_refs *p = ctx->trees;
+ ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL);
+ if (!ctx->trees) {
+ ctx->trees = p;
+ return 0;
+ }
+ if (p)
+ p->next = ctx->trees;
+ else
+ ctx->first_trees = ctx->trees;
+ ctx->tree_count = 31;
+ return 1;
+}
+#endif
+
+static void unroll_tree_refs(struct audit_context *ctx,
+ struct audit_tree_refs *p, int count)
+{
+#ifdef CONFIG_AUDIT_TREE
+ struct audit_tree_refs *q;
+ int n;
+ if (!p) {
+ /* we started with empty chain */
+ p = ctx->first_trees;
+ count = 31;
+ /* if the very first allocation has failed, nothing to do */
+ if (!p)
+ return;
+ }
+ n = count;
+ for (q = p; q != ctx->trees; q = q->next, n = 31) {
+ while (n--) {
+ audit_put_chunk(q->c[n]);
+ q->c[n] = NULL;
+ }
+ }
+ while (n-- > ctx->tree_count) {
+ audit_put_chunk(q->c[n]);
+ q->c[n] = NULL;
+ }
+ ctx->trees = p;
+ ctx->tree_count = count;
+#endif
+}
+
+static void free_tree_refs(struct audit_context *ctx)
+{
+ struct audit_tree_refs *p, *q;
+ for (p = ctx->first_trees; p; p = q) {
+ q = p->next;
+ kfree(p);
+ }
+}
+
+static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
+{
+#ifdef CONFIG_AUDIT_TREE
+ struct audit_tree_refs *p;
+ int n;
+ if (!tree)
+ return 0;
+ /* full ones */
+ for (p = ctx->first_trees; p != ctx->trees; p = p->next) {
+ for (n = 0; n < 31; n++)
+ if (audit_tree_match(p->c[n], tree))
+ return 1;
+ }
+ /* partial */
+ if (p) {
+ for (n = ctx->tree_count; n < 31; n++)
+ if (audit_tree_match(p->c[n], tree))
+ return 1;
+ }
+#endif
+ return 0;
+}
+
/* Determine if any context name data matches a rule's watch data */
/* Compare a task_struct with an audit_rule. Return 1 on match, 0
* otherwise. */
@@ -379,6 +499,10 @@ static int audit_filter_rules(struct task_struct *tsk,
result = (name->dev == rule->watch->dev &&
name->ino == rule->watch->ino);
break;
+ case AUDIT_DIR:
+ if (ctx)
+ result = match_tree_refs(ctx, rule->tree);
+ break;
case AUDIT_LOGINUID:
result = 0;
if (ctx)
@@ -727,6 +851,8 @@ static inline void audit_free_context(struct audit_context *context)
context->name_count, count);
}
audit_free_names(context);
+ unroll_tree_refs(context, NULL, 0);
+ free_tree_refs(context);
audit_free_aux(context);
kfree(context->filterkey);
kfree(context);
@@ -1270,6 +1396,7 @@ void audit_syscall_exit(int valid, long return_code)
tsk->audit_context = new_context;
} else {
audit_free_names(context);
+ unroll_tree_refs(context, NULL, 0);
audit_free_aux(context);
context->aux = NULL;
context->aux_pids = NULL;
@@ -1281,6 +1408,95 @@ void audit_syscall_exit(int valid, long return_code)
}
}
+static inline void handle_one(const struct inode *inode)
+{
+#ifdef CONFIG_AUDIT_TREE
+ struct audit_context *context;
+ struct audit_tree_refs *p;
+ struct audit_chunk *chunk;
+ int count;
+ if (likely(list_empty(&inode->inotify_watches)))
+ return;
+ context = current->audit_context;
+ p = context->trees;
+ count = context->tree_count;
+ rcu_read_lock();
+ chunk = audit_tree_lookup(inode);
+ rcu_read_unlock();
+ if (!chunk)
+ return;
+ if (likely(put_tree_ref(context, chunk)))
+ return;
+ if (unlikely(!grow_tree_refs(context))) {
+ printk(KERN_WARNING "out of memory, audit has lost a tree reference");
+ audit_set_auditable(context);
+ audit_put_chunk(chunk);
+ unroll_tree_refs(context, p, count);
+ return;
+ }
+ put_tree_ref(context, chunk);
+#endif
+}
+
+static void handle_path(const struct dentry *dentry)
+{
+#ifdef CONFIG_AUDIT_TREE
+ struct audit_context *context;
+ struct audit_tree_refs *p;
+ const struct dentry *d, *parent;
+ struct audit_chunk *drop;
+ unsigned long seq;
+ int count;
+
+ context = current->audit_context;
+ p = context->trees;
+ count = context->tree_count;
+retry:
+ drop = NULL;
+ d = dentry;
+ rcu_read_lock();
+ seq = read_seqbegin(&rename_lock);
+ for(;;) {
+ struct inode *inode = d->d_inode;
+ if (inode && unlikely(!list_empty(&inode->inotify_watches))) {
+ struct audit_chunk *chunk;
+ chunk = audit_tree_lookup(inode);
+ if (chunk) {
+ if (unlikely(!put_tree_ref(context, chunk))) {
+ drop = chunk;
+ break;
+ }
+ }
+ }
+ parent = d->d_parent;
+ if (parent == d)
+ break;
+ d = parent;
+ }
+ if (unlikely(read_seqretry(&rename_lock, seq) || drop)) { /* in this order */
+ rcu_read_unlock();
+ if (!drop) {
+ /* just a race with rename */
+ unroll_tree_refs(context, p, count);
+ goto retry;
+ }
+ audit_put_chunk(drop);
+ if (grow_tree_refs(context)) {
+ /* OK, got more space */
+ unroll_tree_refs(context, p, count);
+ goto retry;
+ }
+ /* too bad */
+ printk(KERN_WARNING
+ "out of memory, audit has lost a tree reference");
+ unroll_tree_refs(context, p, count);
+ audit_set_auditable(context);
+ return;
+ }
+ rcu_read_unlock();
+#endif
+}
+
/**
* audit_getname - add a name to the list
* @name: name to add
@@ -1399,14 +1615,15 @@ static void audit_copy_inode(struct audit_names *name, const struct inode *inode
/**
* audit_inode - store the inode and device from a lookup
* @name: name being audited
- * @inode: inode being audited
+ * @dentry: dentry being audited
*
* Called from fs/namei.c:path_lookup().
*/
-void __audit_inode(const char *name, const struct inode *inode)
+void __audit_inode(const char *name, const struct dentry *dentry)
{
int idx;
struct audit_context *context = current->audit_context;
+ const struct inode *inode = dentry->d_inode;
if (!context->in_syscall)
return;
@@ -1426,13 +1643,14 @@ void __audit_inode(const char *name, const struct inode *inode)
idx = context->name_count - 1;
context->names[idx].name = NULL;
}
+ handle_path(dentry);
audit_copy_inode(&context->names[idx], inode);
}
/**
* audit_inode_child - collect inode info for created/removed objects
* @dname: inode's dentry name
- * @inode: inode being audited
+ * @dentry: dentry being audited
* @parent: inode of dentry parent
*
* For syscalls that create or remove filesystem objects, audit_inode
@@ -1443,17 +1661,20 @@ void __audit_inode(const char *name, const struct inode *inode)
* must be hooked prior, in order to capture the target inode during
* unsuccessful attempts.
*/
-void __audit_inode_child(const char *dname, const struct inode *inode,
+void __audit_inode_child(const char *dname, const struct dentry *dentry,
const struct inode *parent)
{
int idx;
struct audit_context *context = current->audit_context;
const char *found_parent = NULL, *found_child = NULL;
+ const struct inode *inode = dentry->d_inode;
int dirlen = 0;
if (!context->in_syscall)
return;
+ if (inode)
+ handle_one(inode);
/* determine matching parent */
if (!dname)
goto add_names;
diff --git a/kernel/capability.c b/kernel/capability.c
index cbc5fd60c0f..efbd9cdce13 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/security.h>
#include <linux/syscalls.h>
+#include <linux/pid_namespace.h>
#include <asm/uaccess.h>
/*
@@ -61,8 +62,8 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
spin_lock(&task_capability_lock);
read_lock(&tasklist_lock);
- if (pid && pid != current->pid) {
- target = find_task_by_pid(pid);
+ if (pid && pid != task_pid_vnr(current)) {
+ target = find_task_by_vpid(pid);
if (!target) {
ret = -ESRCH;
goto out;
@@ -95,7 +96,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective,
int found = 0;
struct pid *pgrp;
- pgrp = find_pid(pgrp_nr);
+ pgrp = find_vpid(pgrp_nr);
do_each_pid_task(pgrp, PIDTYPE_PGID, g) {
target = g;
while_each_thread(g, target) {
@@ -129,7 +130,7 @@ static inline int cap_set_all(kernel_cap_t *effective,
int found = 0;
do_each_thread(g, target) {
- if (target == current || is_init(target))
+ if (target == current || is_container_init(target->group_leader))
continue;
found = 1;
if (security_capset_check(target, effective, inheritable,
@@ -184,7 +185,7 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
if (get_user(pid, &header->pid))
return -EFAULT;
- if (pid && pid != current->pid && !capable(CAP_SETPCAP))
+ if (pid && pid != task_pid_vnr(current) && !capable(CAP_SETPCAP))
return -EPERM;
if (copy_from_user(&effective, &data->effective, sizeof(effective)) ||
@@ -195,8 +196,8 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data)
spin_lock(&task_capability_lock);
read_lock(&tasklist_lock);
- if (pid > 0 && pid != current->pid) {
- target = find_task_by_pid(pid);
+ if (pid > 0 && pid != task_pid_vnr(current)) {
+ target = find_task_by_vpid(pid);
if (!target) {
ret = -ESRCH;
goto out;
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
new file mode 100644
index 00000000000..5987dccdb2a
--- /dev/null
+++ b/kernel/cgroup.c
@@ -0,0 +1,2805 @@
+/*
+ * kernel/cgroup.c
+ *
+ * Generic process-grouping system.
+ *
+ * Based originally on the cpuset system, extracted by Paul Menage
+ * Copyright (C) 2006 Google, Inc
+ *
+ * Copyright notices from the original cpuset code:
+ * --------------------------------------------------
+ * Copyright (C) 2003 BULL SA.
+ * Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ *
+ * Portions derived from Patrick Mochel's sysfs code.
+ * sysfs is Copyright (c) 2001-3 Patrick Mochel
+ *
+ * 2003-10-10 Written by Simon Derr.
+ * 2003-10-22 Updates by Stephen Hemminger.
+ * 2004 May-July Rework by Paul Jackson.
+ * ---------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ */
+
+#include <linux/cgroup.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/proc_fs.h>
+#include <linux/rcupdate.h>
+#include <linux/sched.h>
+#include <linux/backing-dev.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/magic.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/sort.h>
+#include <linux/kmod.h>
+#include <linux/delayacct.h>
+#include <linux/cgroupstats.h>
+
+#include <asm/atomic.h>
+
+static DEFINE_MUTEX(cgroup_mutex);
+
+/* Generate an array of cgroup subsystem pointers */
+#define SUBSYS(_x) &_x ## _subsys,
+
+static struct cgroup_subsys *subsys[] = {
+#include <linux/cgroup_subsys.h>
+};
+
+/*
+ * A cgroupfs_root represents the root of a cgroup hierarchy,
+ * and may be associated with a superblock to form an active
+ * hierarchy
+ */
+struct cgroupfs_root {
+ struct super_block *sb;
+
+ /*
+ * The bitmask of subsystems intended to be attached to this
+ * hierarchy
+ */
+ unsigned long subsys_bits;
+
+ /* The bitmask of subsystems currently attached to this hierarchy */
+ unsigned long actual_subsys_bits;
+
+ /* A list running through the attached subsystems */
+ struct list_head subsys_list;
+
+ /* The root cgroup for this hierarchy */
+ struct cgroup top_cgroup;
+
+ /* Tracks how many cgroups are currently defined in hierarchy.*/
+ int number_of_cgroups;
+
+ /* A list running through the mounted hierarchies */
+ struct list_head root_list;
+
+ /* Hierarchy-specific flags */
+ unsigned long flags;
+
+ /* The path to use for release notifications. No locking
+ * between setting and use - so if userspace updates this
+ * while child cgroups exist, you could miss a
+ * notification. We ensure that it's always a valid
+ * NUL-terminated string */
+ char release_agent_path[PATH_MAX];
+};
+
+
+/*
+ * The "rootnode" hierarchy is the "dummy hierarchy", reserved for the
+ * subsystems that are otherwise unattached - it never has more than a
+ * single cgroup, and all tasks are part of that cgroup.
+ */
+static struct cgroupfs_root rootnode;
+
+/* The list of hierarchy roots */
+
+static LIST_HEAD(roots);
+static int root_count;
+
+/* dummytop is a shorthand for the dummy hierarchy's top cgroup */
+#define dummytop (&rootnode.top_cgroup)
+
+/* This flag indicates whether tasks in the fork and exit paths should
+ * take callback_mutex and check for fork/exit handlers to call. This
+ * avoids us having to do extra work in the fork/exit path if none of the
+ * subsystems need to be called.
+ */
+static int need_forkexit_callback;
+
+/* bits in struct cgroup flags field */
+enum {
+ /* Control Group is dead */
+ CGRP_REMOVED,
+ /* Control Group has previously had a child cgroup or a task,
+ * but no longer (only if CGRP_NOTIFY_ON_RELEASE is set) */
+ CGRP_RELEASABLE,
+ /* Control Group requires release notifications to userspace */
+ CGRP_NOTIFY_ON_RELEASE,
+};
+
+/* convenient tests for these bits */
+inline int cgroup_is_removed(const struct cgroup *cgrp)
+{
+ return test_bit(CGRP_REMOVED, &cgrp->flags);
+}
+
+/* bits in struct cgroupfs_root flags field */
+enum {
+ ROOT_NOPREFIX, /* mounted subsystems have no named prefix */
+};
+
+inline int cgroup_is_releasable(const struct cgroup *cgrp)
+{
+ const int bits =
+ (1 << CGRP_RELEASABLE) |
+ (1 << CGRP_NOTIFY_ON_RELEASE);
+ return (cgrp->flags & bits) == bits;
+}
+
+inline int notify_on_release(const struct cgroup *cgrp)
+{
+ return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+}
+
+/*
+ * for_each_subsys() allows you to iterate on each subsystem attached to
+ * an active hierarchy
+ */
+#define for_each_subsys(_root, _ss) \
+list_for_each_entry(_ss, &_root->subsys_list, sibling)
+
+/* for_each_root() allows you to iterate across the active hierarchies */
+#define for_each_root(_root) \
+list_for_each_entry(_root, &roots, root_list)
+
+/* the list of cgroups eligible for automatic release. Protected by
+ * release_list_lock */
+static LIST_HEAD(release_list);
+static DEFINE_SPINLOCK(release_list_lock);
+static void cgroup_release_agent(struct work_struct *work);
+static DECLARE_WORK(release_agent_work, cgroup_release_agent);
+static void check_for_release(struct cgroup *cgrp);
+
+/* Link structure for associating css_set objects with cgroups */
+struct cg_cgroup_link {
+ /*
+ * List running through cg_cgroup_links associated with a
+ * cgroup, anchored on cgroup->css_sets
+ */
+ struct list_head cgrp_link_list;
+ /*
+ * List running through cg_cgroup_links pointing at a
+ * single css_set object, anchored on css_set->cg_links
+ */
+ struct list_head cg_link_list;
+ struct css_set *cg;
+};
+
+/* The default css_set - used by init and its children prior to any
+ * hierarchies being mounted. It contains a pointer to the root state
+ * for each subsystem. Also used to anchor the list of css_sets. Not
+ * reference-counted, to improve performance when child cgroups
+ * haven't been created.
+ */
+
+static struct css_set init_css_set;
+static struct cg_cgroup_link init_css_set_link;
+
+/* css_set_lock protects the list of css_set objects, and the
+ * chain of tasks off each css_set. Nests outside task->alloc_lock
+ * due to cgroup_iter_start() */
+static DEFINE_RWLOCK(css_set_lock);
+static int css_set_count;
+
+/* We don't maintain the lists running through each css_set to its
+ * task until after the first call to cgroup_iter_start(). This
+ * reduces the fork()/exit() overhead for people who have cgroups
+ * compiled into their kernel but not actually in use */
+static int use_task_css_set_links;
+
+/* When we create or destroy a css_set, the operation simply
+ * takes/releases a reference count on all the cgroups referenced
+ * by subsystems in this css_set. This can end up multiple-counting
+ * some cgroups, but that's OK - the ref-count is just a
+ * busy/not-busy indicator; ensuring that we only count each cgroup
+ * once would require taking a global lock to ensure that no
+ * subsystems moved between hierarchies while we were doing so.
+ *
+ * Possible TODO: decide at boot time based on the number of
+ * registered subsystems and the number of CPUs or NUMA nodes whether
+ * it's better for performance to ref-count every subsystem, or to
+ * take a global lock and only add one ref count to each hierarchy.
+ */
+
+/*
+ * unlink a css_set from the list and free it
+ */
+static void unlink_css_set(struct css_set *cg)
+{
+ write_lock(&css_set_lock);
+ list_del(&cg->list);
+ css_set_count--;
+ while (!list_empty(&cg->cg_links)) {
+ struct cg_cgroup_link *link;
+ link = list_entry(cg->cg_links.next,
+ struct cg_cgroup_link, cg_link_list);
+ list_del(&link->cg_link_list);
+ list_del(&link->cgrp_link_list);
+ kfree(link);
+ }
+ write_unlock(&css_set_lock);
+}
+
+static void __release_css_set(struct kref *k, int taskexit)
+{
+ int i;
+ struct css_set *cg = container_of(k, struct css_set, ref);
+
+ unlink_css_set(cg);
+
+ rcu_read_lock();
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup *cgrp = cg->subsys[i]->cgroup;
+ if (atomic_dec_and_test(&cgrp->count) &&
+ notify_on_release(cgrp)) {
+ if (taskexit)
+ set_bit(CGRP_RELEASABLE, &cgrp->flags);
+ check_for_release(cgrp);
+ }
+ }
+ rcu_read_unlock();
+ kfree(cg);
+}
+
+static void release_css_set(struct kref *k)
+{
+ __release_css_set(k, 0);
+}
+
+static void release_css_set_taskexit(struct kref *k)
+{
+ __release_css_set(k, 1);
+}
+
+/*
+ * refcounted get/put for css_set objects
+ */
+static inline void get_css_set(struct css_set *cg)
+{
+ kref_get(&cg->ref);
+}
+
+static inline void put_css_set(struct css_set *cg)
+{
+ kref_put(&cg->ref, release_css_set);
+}
+
+static inline void put_css_set_taskexit(struct css_set *cg)
+{
+ kref_put(&cg->ref, release_css_set_taskexit);
+}
+
+/*
+ * find_existing_css_set() is a helper for
+ * find_css_set(), and checks to see whether an existing
+ * css_set is suitable. This currently walks a linked-list for
+ * simplicity; a later patch will use a hash table for better
+ * performance
+ *
+ * oldcg: the cgroup group that we're using before the cgroup
+ * transition
+ *
+ * cgrp: the cgroup that we're moving into
+ *
+ * template: location in which to build the desired set of subsystem
+ * state objects for the new cgroup group
+ */
+
+static struct css_set *find_existing_css_set(
+ struct css_set *oldcg,
+ struct cgroup *cgrp,
+ struct cgroup_subsys_state *template[])
+{
+ int i;
+ struct cgroupfs_root *root = cgrp->root;
+ struct list_head *l = &init_css_set.list;
+
+ /* Built the set of subsystem state objects that we want to
+ * see in the new css_set */
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ if (root->subsys_bits & (1ull << i)) {
+ /* Subsystem is in this hierarchy. So we want
+ * the subsystem state from the new
+ * cgroup */
+ template[i] = cgrp->subsys[i];
+ } else {
+ /* Subsystem is not in this hierarchy, so we
+ * don't want to change the subsystem state */
+ template[i] = oldcg->subsys[i];
+ }
+ }
+
+ /* Look through existing cgroup groups to find one to reuse */
+ do {
+ struct css_set *cg =
+ list_entry(l, struct css_set, list);
+
+ if (!memcmp(template, cg->subsys, sizeof(cg->subsys))) {
+ /* All subsystems matched */
+ return cg;
+ }
+ /* Try the next cgroup group */
+ l = l->next;
+ } while (l != &init_css_set.list);
+
+ /* No existing cgroup group matched */
+ return NULL;
+}
+
+/*
+ * allocate_cg_links() allocates "count" cg_cgroup_link structures
+ * and chains them on tmp through their cgrp_link_list fields. Returns 0 on
+ * success or a negative error
+ */
+
+static int allocate_cg_links(int count, struct list_head *tmp)
+{
+ struct cg_cgroup_link *link;
+ int i;
+ INIT_LIST_HEAD(tmp);
+ for (i = 0; i < count; i++) {
+ link = kmalloc(sizeof(*link), GFP_KERNEL);
+ if (!link) {
+ while (!list_empty(tmp)) {
+ link = list_entry(tmp->next,
+ struct cg_cgroup_link,
+ cgrp_link_list);
+ list_del(&link->cgrp_link_list);
+ kfree(link);
+ }
+ return -ENOMEM;
+ }
+ list_add(&link->cgrp_link_list, tmp);
+ }
+ return 0;
+}
+
+static void free_cg_links(struct list_head *tmp)
+{
+ while (!list_empty(tmp)) {
+ struct cg_cgroup_link *link;
+ link = list_entry(tmp->next,
+ struct cg_cgroup_link,
+ cgrp_link_list);
+ list_del(&link->cgrp_link_list);
+ kfree(link);
+ }
+}
+
+/*
+ * find_css_set() takes an existing cgroup group and a
+ * cgroup object, and returns a css_set object that's
+ * equivalent to the old group, but with the given cgroup
+ * substituted into the appropriate hierarchy. Must be called with
+ * cgroup_mutex held
+ */
+
+static struct css_set *find_css_set(
+ struct css_set *oldcg, struct cgroup *cgrp)
+{
+ struct css_set *res;
+ struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT];
+ int i;
+
+ struct list_head tmp_cg_links;
+ struct cg_cgroup_link *link;
+
+ /* First see if we already have a cgroup group that matches
+ * the desired set */
+ write_lock(&css_set_lock);
+ res = find_existing_css_set(oldcg, cgrp, template);
+ if (res)
+ get_css_set(res);
+ write_unlock(&css_set_lock);
+
+ if (res)
+ return res;
+
+ res = kmalloc(sizeof(*res), GFP_KERNEL);
+ if (!res)
+ return NULL;
+
+ /* Allocate all the cg_cgroup_link objects that we'll need */
+ if (allocate_cg_links(root_count, &tmp_cg_links) < 0) {
+ kfree(res);
+ return NULL;
+ }
+
+ kref_init(&res->ref);
+ INIT_LIST_HEAD(&res->cg_links);
+ INIT_LIST_HEAD(&res->tasks);
+
+ /* Copy the set of subsystem state objects generated in
+ * find_existing_css_set() */
+ memcpy(res->subsys, template, sizeof(res->subsys));
+
+ write_lock(&css_set_lock);
+ /* Add reference counts and links from the new css_set. */
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup *cgrp = res->subsys[i]->cgroup;
+ struct cgroup_subsys *ss = subsys[i];
+ atomic_inc(&cgrp->count);
+ /*
+ * We want to add a link once per cgroup, so we
+ * only do it for the first subsystem in each
+ * hierarchy
+ */
+ if (ss->root->subsys_list.next == &ss->sibling) {
+ BUG_ON(list_empty(&tmp_cg_links));
+ link = list_entry(tmp_cg_links.next,
+ struct cg_cgroup_link,
+ cgrp_link_list);
+ list_del(&link->cgrp_link_list);
+ list_add(&link->cgrp_link_list, &cgrp->css_sets);
+ link->cg = res;
+ list_add(&link->cg_link_list, &res->cg_links);
+ }
+ }
+ if (list_empty(&rootnode.subsys_list)) {
+ link = list_entry(tmp_cg_links.next,
+ struct cg_cgroup_link,
+ cgrp_link_list);
+ list_del(&link->cgrp_link_list);
+ list_add(&link->cgrp_link_list, &dummytop->css_sets);
+ link->cg = res;
+ list_add(&link->cg_link_list, &res->cg_links);
+ }
+
+ BUG_ON(!list_empty(&tmp_cg_links));
+
+ /* Link this cgroup group into the list */
+ list_add(&res->list, &init_css_set.list);
+ css_set_count++;
+ INIT_LIST_HEAD(&res->tasks);
+ write_unlock(&css_set_lock);
+
+ return res;
+}
+
+/*
+ * There is one global cgroup mutex. We also require taking
+ * task_lock() when dereferencing a task's cgroup subsys pointers.
+ * See "The task_lock() exception", at the end of this comment.
+ *
+ * A task must hold cgroup_mutex to modify cgroups.
+ *
+ * Any task can increment and decrement the count field without lock.
+ * So in general, code holding cgroup_mutex can't rely on the count
+ * field not changing. However, if the count goes to zero, then only
+ * attach_task() can increment it again. Because a count of zero
+ * means that no tasks are currently attached, therefore there is no
+ * way a task attached to that cgroup can fork (the other way to
+ * increment the count). So code holding cgroup_mutex can safely
+ * assume that if the count is zero, it will stay zero. Similarly, if
+ * a task holds cgroup_mutex on a cgroup with zero count, it
+ * knows that the cgroup won't be removed, as cgroup_rmdir()
+ * needs that mutex.
+ *
+ * The cgroup_common_file_write handler for operations that modify
+ * the cgroup hierarchy holds cgroup_mutex across the entire operation,
+ * single threading all such cgroup modifications across the system.
+ *
+ * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't
+ * (usually) take cgroup_mutex. These are the two most performance
+ * critical pieces of code here. The exception occurs on cgroup_exit(),
+ * when a task in a notify_on_release cgroup exits. Then cgroup_mutex
+ * is taken, and if the cgroup count is zero, a usermode call made
+ * to /sbin/cgroup_release_agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * A cgroup can only be deleted if both its 'count' of using tasks
+ * is zero, and its list of 'children' cgroups is empty. Since all
+ * tasks in the system use _some_ cgroup, and since there is always at
+ * least one task in the system (init, pid == 1), therefore, top_cgroup
+ * always has either children cgroups and/or using tasks. So we don't
+ * need a special hack to ensure that top_cgroup cannot be deleted.
+ *
+ * The task_lock() exception
+ *
+ * The need for this exception arises from the action of
+ * attach_task(), which overwrites one tasks cgroup pointer with
+ * another. It does so using cgroup_mutexe, however there are
+ * several performance critical places that need to reference
+ * task->cgroup without the expense of grabbing a system global
+ * mutex. Therefore except as noted below, when dereferencing or, as
+ * in attach_task(), modifying a task'ss cgroup pointer we use
+ * task_lock(), which acts on a spinlock (task->alloc_lock) already in
+ * the task_struct routinely used for such matters.
+ *
+ * P.S. One more locking exception. RCU is used to guard the
+ * update of a tasks cgroup pointer by attach_task()
+ */
+
+/**
+ * cgroup_lock - lock out any changes to cgroup structures
+ *
+ */
+
+void cgroup_lock(void)
+{
+ mutex_lock(&cgroup_mutex);
+}
+
+/**
+ * cgroup_unlock - release lock on cgroup changes
+ *
+ * Undo the lock taken in a previous cgroup_lock() call.
+ */
+
+void cgroup_unlock(void)
+{
+ mutex_unlock(&cgroup_mutex);
+}
+
+/*
+ * A couple of forward declarations required, due to cyclic reference loop:
+ * cgroup_mkdir -> cgroup_create -> cgroup_populate_dir ->
+ * cgroup_add_file -> cgroup_create_file -> cgroup_dir_inode_operations
+ * -> cgroup_mkdir.
+ */
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode);
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry);
+static int cgroup_populate_dir(struct cgroup *cgrp);
+static struct inode_operations cgroup_dir_inode_operations;
+static struct file_operations proc_cgroupstats_operations;
+
+static struct backing_dev_info cgroup_backing_dev_info = {
+ .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
+};
+
+static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb)
+{
+ struct inode *inode = new_inode(sb);
+
+ if (inode) {
+ inode->i_mode = mode;
+ inode->i_uid = current->fsuid;
+ inode->i_gid = current->fsgid;
+ inode->i_blocks = 0;
+ inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+ inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info;
+ }
+ return inode;
+}
+
+static void cgroup_diput(struct dentry *dentry, struct inode *inode)
+{
+ /* is dentry a directory ? if so, kfree() associated cgroup */
+ if (S_ISDIR(inode->i_mode)) {
+ struct cgroup *cgrp = dentry->d_fsdata;
+ BUG_ON(!(cgroup_is_removed(cgrp)));
+ /* It's possible for external users to be holding css
+ * reference counts on a cgroup; css_put() needs to
+ * be able to access the cgroup after decrementing
+ * the reference count in order to know if it needs to
+ * queue the cgroup to be handled by the release
+ * agent */
+ synchronize_rcu();
+ kfree(cgrp);
+ }
+ iput(inode);
+}
+
+static void remove_dir(struct dentry *d)
+{
+ struct dentry *parent = dget(d->d_parent);
+
+ d_delete(d);
+ simple_rmdir(parent->d_inode, d);
+ dput(parent);
+}
+
+static void cgroup_clear_directory(struct dentry *dentry)
+{
+ struct list_head *node;
+
+ BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
+ spin_lock(&dcache_lock);
+ node = dentry->d_subdirs.next;
+ while (node != &dentry->d_subdirs) {
+ struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
+ list_del_init(node);
+ if (d->d_inode) {
+ /* This should never be called on a cgroup
+ * directory with child cgroups */
+ BUG_ON(d->d_inode->i_mode & S_IFDIR);
+ d = dget_locked(d);
+ spin_unlock(&dcache_lock);
+ d_delete(d);
+ simple_unlink(dentry->d_inode, d);
+ dput(d);
+ spin_lock(&dcache_lock);
+ }
+ node = dentry->d_subdirs.next;
+ }
+ spin_unlock(&dcache_lock);
+}
+
+/*
+ * NOTE : the dentry must have been dget()'ed
+ */
+static void cgroup_d_remove_dir(struct dentry *dentry)
+{
+ cgroup_clear_directory(dentry);
+
+ spin_lock(&dcache_lock);
+ list_del_init(&dentry->d_u.d_child);
+ spin_unlock(&dcache_lock);
+ remove_dir(dentry);
+}
+
+static int rebind_subsystems(struct cgroupfs_root *root,
+ unsigned long final_bits)
+{
+ unsigned long added_bits, removed_bits;
+ struct cgroup *cgrp = &root->top_cgroup;
+ int i;
+
+ removed_bits = root->actual_subsys_bits & ~final_bits;
+ added_bits = final_bits & ~root->actual_subsys_bits;
+ /* Check that any added subsystems are currently free */
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ unsigned long long bit = 1ull << i;
+ struct cgroup_subsys *ss = subsys[i];
+ if (!(bit & added_bits))
+ continue;
+ if (ss->root != &rootnode) {
+ /* Subsystem isn't free */
+ return -EBUSY;
+ }
+ }
+
+ /* Currently we don't handle adding/removing subsystems when
+ * any child cgroups exist. This is theoretically supportable
+ * but involves complex error handling, so it's being left until
+ * later */
+ if (!list_empty(&cgrp->children))
+ return -EBUSY;
+
+ /* Process each subsystem */
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ unsigned long bit = 1UL << i;
+ if (bit & added_bits) {
+ /* We're binding this subsystem to this hierarchy */
+ BUG_ON(cgrp->subsys[i]);
+ BUG_ON(!dummytop->subsys[i]);
+ BUG_ON(dummytop->subsys[i]->cgroup != dummytop);
+ cgrp->subsys[i] = dummytop->subsys[i];
+ cgrp->subsys[i]->cgroup = cgrp;
+ list_add(&ss->sibling, &root->subsys_list);
+ rcu_assign_pointer(ss->root, root);
+ if (ss->bind)
+ ss->bind(ss, cgrp);
+
+ } else if (bit & removed_bits) {
+ /* We're removing this subsystem */
+ BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]);
+ BUG_ON(cgrp->subsys[i]->cgroup != cgrp);
+ if (ss->bind)
+ ss->bind(ss, dummytop);
+ dummytop->subsys[i]->cgroup = dummytop;
+ cgrp->subsys[i] = NULL;
+ rcu_assign_pointer(subsys[i]->root, &rootnode);
+ list_del(&ss->sibling);
+ } else if (bit & final_bits) {
+ /* Subsystem state should already exist */
+ BUG_ON(!cgrp->subsys[i]);
+ } else {
+ /* Subsystem state shouldn't exist */
+ BUG_ON(cgrp->subsys[i]);
+ }
+ }
+ root->subsys_bits = root->actual_subsys_bits = final_bits;
+ synchronize_rcu();
+
+ return 0;
+}
+
+static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct cgroupfs_root *root = vfs->mnt_sb->s_fs_info;
+ struct cgroup_subsys *ss;
+
+ mutex_lock(&cgroup_mutex);
+ for_each_subsys(root, ss)
+ seq_printf(seq, ",%s", ss->name);
+ if (test_bit(ROOT_NOPREFIX, &root->flags))
+ seq_puts(seq, ",noprefix");
+ if (strlen(root->release_agent_path))
+ seq_printf(seq, ",release_agent=%s", root->release_agent_path);
+ mutex_unlock(&cgroup_mutex);
+ return 0;
+}
+
+struct cgroup_sb_opts {
+ unsigned long subsys_bits;
+ unsigned long flags;
+ char *release_agent;
+};
+
+/* Convert a hierarchy specifier into a bitmask of subsystems and
+ * flags. */
+static int parse_cgroupfs_options(char *data,
+ struct cgroup_sb_opts *opts)
+{
+ char *token, *o = data ?: "all";
+
+ opts->subsys_bits = 0;
+ opts->flags = 0;
+ opts->release_agent = NULL;
+
+ while ((token = strsep(&o, ",")) != NULL) {
+ if (!*token)
+ return -EINVAL;
+ if (!strcmp(token, "all")) {
+ opts->subsys_bits = (1 << CGROUP_SUBSYS_COUNT) - 1;
+ } else if (!strcmp(token, "noprefix")) {
+ set_bit(ROOT_NOPREFIX, &opts->flags);
+ } else if (!strncmp(token, "release_agent=", 14)) {
+ /* Specifying two release agents is forbidden */
+ if (opts->release_agent)
+ return -EINVAL;
+ opts->release_agent = kzalloc(PATH_MAX, GFP_KERNEL);
+ if (!opts->release_agent)
+ return -ENOMEM;
+ strncpy(opts->release_agent, token + 14, PATH_MAX - 1);
+ opts->release_agent[PATH_MAX - 1] = 0;
+ } else {
+ struct cgroup_subsys *ss;
+ int i;
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ ss = subsys[i];
+ if (!strcmp(token, ss->name)) {
+ set_bit(i, &opts->subsys_bits);
+ break;
+ }
+ }
+ if (i == CGROUP_SUBSYS_COUNT)
+ return -ENOENT;
+ }
+ }
+
+ /* We can't have an empty hierarchy */
+ if (!opts->subsys_bits)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int cgroup_remount(struct super_block *sb, int *flags, char *data)
+{
+ int ret = 0;
+ struct cgroupfs_root *root = sb->s_fs_info;
+ struct cgroup *cgrp = &root->top_cgroup;
+ struct cgroup_sb_opts opts;
+
+ mutex_lock(&cgrp->dentry->d_inode->i_mutex);
+ mutex_lock(&cgroup_mutex);
+
+ /* See what subsystems are wanted */
+ ret = parse_cgroupfs_options(data, &opts);
+ if (ret)
+ goto out_unlock;
+
+ /* Don't allow flags to change at remount */
+ if (opts.flags != root->flags) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ ret = rebind_subsystems(root, opts.subsys_bits);
+
+ /* (re)populate subsystem files */
+ if (!ret)
+ cgroup_populate_dir(cgrp);
+
+ if (opts.release_agent)
+ strcpy(root->release_agent_path, opts.release_agent);
+ out_unlock:
+ if (opts.release_agent)
+ kfree(opts.release_agent);
+ mutex_unlock(&cgroup_mutex);
+ mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+ return ret;
+}
+
+static struct super_operations cgroup_ops = {
+ .statfs = simple_statfs,
+ .drop_inode = generic_delete_inode,
+ .show_options = cgroup_show_options,
+ .remount_fs = cgroup_remount,
+};
+
+static void init_cgroup_root(struct cgroupfs_root *root)
+{
+ struct cgroup *cgrp = &root->top_cgroup;
+ INIT_LIST_HEAD(&root->subsys_list);
+ INIT_LIST_HEAD(&root->root_list);
+ root->number_of_cgroups = 1;
+ cgrp->root = root;
+ cgrp->top_cgroup = cgrp;
+ INIT_LIST_HEAD(&cgrp->sibling);
+ INIT_LIST_HEAD(&cgrp->children);
+ INIT_LIST_HEAD(&cgrp->css_sets);
+ INIT_LIST_HEAD(&cgrp->release_list);
+}
+
+static int cgroup_test_super(struct super_block *sb, void *data)
+{
+ struct cgroupfs_root *new = data;
+ struct cgroupfs_root *root = sb->s_fs_info;
+
+ /* First check subsystems */
+ if (new->subsys_bits != root->subsys_bits)
+ return 0;
+
+ /* Next check flags */
+ if (new->flags != root->flags)
+ return 0;
+
+ return 1;
+}
+
+static int cgroup_set_super(struct super_block *sb, void *data)
+{
+ int ret;
+ struct cgroupfs_root *root = data;
+
+ ret = set_anon_super(sb, NULL);
+ if (ret)
+ return ret;
+
+ sb->s_fs_info = root;
+ root->sb = sb;
+
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = CGROUP_SUPER_MAGIC;
+ sb->s_op = &cgroup_ops;
+
+ return 0;
+}
+
+static int cgroup_get_rootdir(struct super_block *sb)
+{
+ struct inode *inode =
+ cgroup_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, sb);
+ struct dentry *dentry;
+
+ if (!inode)
+ return -ENOMEM;
+
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+ inode->i_op = &cgroup_dir_inode_operations;
+ /* directories start off with i_nlink == 2 (for "." entry) */
+ inc_nlink(inode);
+ dentry = d_alloc_root(inode);
+ if (!dentry) {
+ iput(inode);
+ return -ENOMEM;
+ }
+ sb->s_root = dentry;
+ return 0;
+}
+
+static int cgroup_get_sb(struct file_system_type *fs_type,
+ int flags, const char *unused_dev_name,
+ void *data, struct vfsmount *mnt)
+{
+ struct cgroup_sb_opts opts;
+ int ret = 0;
+ struct super_block *sb;
+ struct cgroupfs_root *root;
+ struct list_head tmp_cg_links, *l;
+ INIT_LIST_HEAD(&tmp_cg_links);
+
+ /* First find the desired set of subsystems */
+ ret = parse_cgroupfs_options(data, &opts);
+ if (ret) {
+ if (opts.release_agent)
+ kfree(opts.release_agent);
+ return ret;
+ }
+
+ root = kzalloc(sizeof(*root), GFP_KERNEL);
+ if (!root)
+ return -ENOMEM;
+
+ init_cgroup_root(root);
+ root->subsys_bits = opts.subsys_bits;
+ root->flags = opts.flags;
+ if (opts.release_agent) {
+ strcpy(root->release_agent_path, opts.release_agent);
+ kfree(opts.release_agent);
+ }
+
+ sb = sget(fs_type, cgroup_test_super, cgroup_set_super, root);
+
+ if (IS_ERR(sb)) {
+ kfree(root);
+ return PTR_ERR(sb);
+ }
+
+ if (sb->s_fs_info != root) {
+ /* Reusing an existing superblock */
+ BUG_ON(sb->s_root == NULL);
+ kfree(root);
+ root = NULL;
+ } else {
+ /* New superblock */
+ struct cgroup *cgrp = &root->top_cgroup;
+ struct inode *inode;
+
+ BUG_ON(sb->s_root != NULL);
+
+ ret = cgroup_get_rootdir(sb);
+ if (ret)
+ goto drop_new_super;
+ inode = sb->s_root->d_inode;
+
+ mutex_lock(&inode->i_mutex);
+ mutex_lock(&cgroup_mutex);
+
+ /*
+ * We're accessing css_set_count without locking
+ * css_set_lock here, but that's OK - it can only be
+ * increased by someone holding cgroup_lock, and
+ * that's us. The worst that can happen is that we
+ * have some link structures left over
+ */
+ ret = allocate_cg_links(css_set_count, &tmp_cg_links);
+ if (ret) {
+ mutex_unlock(&cgroup_mutex);
+ mutex_unlock(&inode->i_mutex);
+ goto drop_new_super;
+ }
+
+ ret = rebind_subsystems(root, root->subsys_bits);
+ if (ret == -EBUSY) {
+ mutex_unlock(&cgroup_mutex);
+ mutex_unlock(&inode->i_mutex);
+ goto drop_new_super;
+ }
+
+ /* EBUSY should be the only error here */
+ BUG_ON(ret);
+
+ list_add(&root->root_list, &roots);
+ root_count++;
+
+ sb->s_root->d_fsdata = &root->top_cgroup;
+ root->top_cgroup.dentry = sb->s_root;
+
+ /* Link the top cgroup in this hierarchy into all
+ * the css_set objects */
+ write_lock(&css_set_lock);
+ l = &init_css_set.list;
+ do {
+ struct css_set *cg;
+ struct cg_cgroup_link *link;
+ cg = list_entry(l, struct css_set, list);
+ BUG_ON(list_empty(&tmp_cg_links));
+ link = list_entry(tmp_cg_links.next,
+ struct cg_cgroup_link,
+ cgrp_link_list);
+ list_del(&link->cgrp_link_list);
+ link->cg = cg;
+ list_add(&link->cgrp_link_list,
+ &root->top_cgroup.css_sets);
+ list_add(&link->cg_link_list, &cg->cg_links);
+ l = l->next;
+ } while (l != &init_css_set.list);
+ write_unlock(&css_set_lock);
+
+ free_cg_links(&tmp_cg_links);
+
+ BUG_ON(!list_empty(&cgrp->sibling));
+ BUG_ON(!list_empty(&cgrp->children));
+ BUG_ON(root->number_of_cgroups != 1);
+
+ cgroup_populate_dir(cgrp);
+ mutex_unlock(&inode->i_mutex);
+ mutex_unlock(&cgroup_mutex);
+ }
+
+ return simple_set_mnt(mnt, sb);
+
+ drop_new_super:
+ up_write(&sb->s_umount);
+ deactivate_super(sb);
+ free_cg_links(&tmp_cg_links);
+ return ret;
+}
+
+static void cgroup_kill_sb(struct super_block *sb) {
+ struct cgroupfs_root *root = sb->s_fs_info;
+ struct cgroup *cgrp = &root->top_cgroup;
+ int ret;
+
+ BUG_ON(!root);
+
+ BUG_ON(root->number_of_cgroups != 1);
+ BUG_ON(!list_empty(&cgrp->children));
+ BUG_ON(!list_empty(&cgrp->sibling));
+
+ mutex_lock(&cgroup_mutex);
+
+ /* Rebind all subsystems back to the default hierarchy */
+ ret = rebind_subsystems(root, 0);
+ /* Shouldn't be able to fail ... */
+ BUG_ON(ret);
+
+ /*
+ * Release all the links from css_sets to this hierarchy's
+ * root cgroup
+ */
+ write_lock(&css_set_lock);
+ while (!list_empty(&cgrp->css_sets)) {
+ struct cg_cgroup_link *link;
+ link = list_entry(cgrp->css_sets.next,
+ struct cg_cgroup_link, cgrp_link_list);
+ list_del(&link->cg_link_list);
+ list_del(&link->cgrp_link_list);
+ kfree(link);
+ }
+ write_unlock(&css_set_lock);
+
+ if (!list_empty(&root->root_list)) {
+ list_del(&root->root_list);
+ root_count--;
+ }
+ mutex_unlock(&cgroup_mutex);
+
+ kfree(root);
+ kill_litter_super(sb);
+}
+
+static struct file_system_type cgroup_fs_type = {
+ .name = "cgroup",
+ .get_sb = cgroup_get_sb,
+ .kill_sb = cgroup_kill_sb,
+};
+
+static inline struct cgroup *__d_cgrp(struct dentry *dentry)
+{
+ return dentry->d_fsdata;
+}
+
+static inline struct cftype *__d_cft(struct dentry *dentry)
+{
+ return dentry->d_fsdata;
+}
+
+/*
+ * Called with cgroup_mutex held. Writes path of cgroup into buf.
+ * Returns 0 on success, -errno on error.
+ */
+int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen)
+{
+ char *start;
+
+ if (cgrp == dummytop) {
+ /*
+ * Inactive subsystems have no dentry for their root
+ * cgroup
+ */
+ strcpy(buf, "/");
+ return 0;
+ }
+
+ start = buf + buflen;
+
+ *--start = '\0';
+ for (;;) {
+ int len = cgrp->dentry->d_name.len;
+ if ((start -= len) < buf)
+ return -ENAMETOOLONG;
+ memcpy(start, cgrp->dentry->d_name.name, len);
+ cgrp = cgrp->parent;
+ if (!cgrp)
+ break;
+ if (!cgrp->parent)
+ continue;
+ if (--start < buf)
+ return -ENAMETOOLONG;
+ *start = '/';
+ }
+ memmove(buf, start, buf + buflen - start);
+ return 0;
+}
+
+/*
+ * Return the first subsystem attached to a cgroup's hierarchy, and
+ * its subsystem id.
+ */
+
+static void get_first_subsys(const struct cgroup *cgrp,
+ struct cgroup_subsys_state **css, int *subsys_id)
+{
+ const struct cgroupfs_root *root = cgrp->root;
+ const struct cgroup_subsys *test_ss;
+ BUG_ON(list_empty(&root->subsys_list));
+ test_ss = list_entry(root->subsys_list.next,
+ struct cgroup_subsys, sibling);
+ if (css) {
+ *css = cgrp->subsys[test_ss->subsys_id];
+ BUG_ON(!*css);
+ }
+ if (subsys_id)
+ *subsys_id = test_ss->subsys_id;
+}
+
+/*
+ * Attach task 'tsk' to cgroup 'cgrp'
+ *
+ * Call holding cgroup_mutex. May take task_lock of
+ * the task 'pid' during call.
+ */
+static int attach_task(struct cgroup *cgrp, struct task_struct *tsk)
+{
+ int retval = 0;
+ struct cgroup_subsys *ss;
+ struct cgroup *oldcgrp;
+ struct css_set *cg = tsk->cgroups;
+ struct css_set *newcg;
+ struct cgroupfs_root *root = cgrp->root;
+ int subsys_id;
+
+ get_first_subsys(cgrp, NULL, &subsys_id);
+
+ /* Nothing to do if the task is already in that cgroup */
+ oldcgrp = task_cgroup(tsk, subsys_id);
+ if (cgrp == oldcgrp)
+ return 0;
+
+ for_each_subsys(root, ss) {
+ if (ss->can_attach) {
+ retval = ss->can_attach(ss, cgrp, tsk);
+ if (retval) {
+ return retval;
+ }
+ }
+ }
+
+ /*
+ * Locate or allocate a new css_set for this task,
+ * based on its final set of cgroups
+ */
+ newcg = find_css_set(cg, cgrp);
+ if (!newcg) {
+ return -ENOMEM;
+ }
+
+ task_lock(tsk);
+ if (tsk->flags & PF_EXITING) {
+ task_unlock(tsk);
+ put_css_set(newcg);
+ return -ESRCH;
+ }
+ rcu_assign_pointer(tsk->cgroups, newcg);
+ task_unlock(tsk);
+
+ /* Update the css_set linked lists if we're using them */
+ write_lock(&css_set_lock);
+ if (!list_empty(&tsk->cg_list)) {
+ list_del(&tsk->cg_list);
+ list_add(&tsk->cg_list, &newcg->tasks);
+ }
+ write_unlock(&css_set_lock);
+
+ for_each_subsys(root, ss) {
+ if (ss->attach) {
+ ss->attach(ss, cgrp, oldcgrp, tsk);
+ }
+ }
+ set_bit(CGRP_RELEASABLE, &oldcgrp->flags);
+ synchronize_rcu();
+ put_css_set(cg);
+ return 0;
+}
+
+/*
+ * Attach task with pid 'pid' to cgroup 'cgrp'. Call with
+ * cgroup_mutex, may take task_lock of task
+ */
+static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf)
+{
+ pid_t pid;
+ struct task_struct *tsk;
+ int ret;
+
+ if (sscanf(pidbuf, "%d", &pid) != 1)
+ return -EIO;
+
+ if (pid) {
+ rcu_read_lock();
+ tsk = find_task_by_pid(pid);
+ if (!tsk || tsk->flags & PF_EXITING) {
+ rcu_read_unlock();
+ return -ESRCH;
+ }
+ get_task_struct(tsk);
+ rcu_read_unlock();
+
+ if ((current->euid) && (current->euid != tsk->uid)
+ && (current->euid != tsk->suid)) {
+ put_task_struct(tsk);
+ return -EACCES;
+ }
+ } else {
+ tsk = current;
+ get_task_struct(tsk);
+ }
+
+ ret = attach_task(cgrp, tsk);
+ put_task_struct(tsk);
+ return ret;
+}
+
+/* The various types of files and directories in a cgroup file system */
+
+enum cgroup_filetype {
+ FILE_ROOT,
+ FILE_DIR,
+ FILE_TASKLIST,
+ FILE_NOTIFY_ON_RELEASE,
+ FILE_RELEASABLE,
+ FILE_RELEASE_AGENT,
+};
+
+static ssize_t cgroup_write_uint(struct cgroup *cgrp, struct cftype *cft,
+ struct file *file,
+ const char __user *userbuf,
+ size_t nbytes, loff_t *unused_ppos)
+{
+ char buffer[64];
+ int retval = 0;
+ u64 val;
+ char *end;
+
+ if (!nbytes)
+ return -EINVAL;
+ if (nbytes >= sizeof(buffer))
+ return -E2BIG;
+ if (copy_from_user(buffer, userbuf, nbytes))
+ return -EFAULT;
+
+ buffer[nbytes] = 0; /* nul-terminate */
+
+ /* strip newline if necessary */
+ if (nbytes && (buffer[nbytes-1] == '\n'))
+ buffer[nbytes-1] = 0;
+ val = simple_strtoull(buffer, &end, 0);
+ if (*end)
+ return -EINVAL;
+
+ /* Pass to subsystem */
+ retval = cft->write_uint(cgrp, cft, val);
+ if (!retval)
+ retval = nbytes;
+ return retval;
+}
+
+static ssize_t cgroup_common_file_write(struct cgroup *cgrp,
+ struct cftype *cft,
+ struct file *file,
+ const char __user *userbuf,
+ size_t nbytes, loff_t *unused_ppos)
+{
+ enum cgroup_filetype type = cft->private;
+ char *buffer;
+ int retval = 0;
+
+ if (nbytes >= PATH_MAX)
+ return -E2BIG;
+
+ /* +1 for nul-terminator */
+ buffer = kmalloc(nbytes + 1, GFP_KERNEL);
+ if (buffer == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(buffer, userbuf, nbytes)) {
+ retval = -EFAULT;
+ goto out1;
+ }
+ buffer[nbytes] = 0; /* nul-terminate */
+
+ mutex_lock(&cgroup_mutex);
+
+ if (cgroup_is_removed(cgrp)) {
+ retval = -ENODEV;
+ goto out2;
+ }
+
+ switch (type) {
+ case FILE_TASKLIST:
+ retval = attach_task_by_pid(cgrp, buffer);
+ break;
+ case FILE_NOTIFY_ON_RELEASE:
+ clear_bit(CGRP_RELEASABLE, &cgrp->flags);
+ if (simple_strtoul(buffer, NULL, 10) != 0)
+ set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+ else
+ clear_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
+ break;
+ case FILE_RELEASE_AGENT:
+ {
+ struct cgroupfs_root *root = cgrp->root;
+ /* Strip trailing newline */
+ if (nbytes && (buffer[nbytes-1] == '\n')) {
+ buffer[nbytes-1] = 0;
+ }
+ if (nbytes < sizeof(root->release_agent_path)) {
+ /* We never write anything other than '\0'
+ * into the last char of release_agent_path,
+ * so it always remains a NUL-terminated
+ * string */
+ strncpy(root->release_agent_path, buffer, nbytes);
+ root->release_agent_path[nbytes] = 0;
+ } else {
+ retval = -ENOSPC;
+ }
+ break;
+ }
+ default:
+ retval = -EINVAL;
+ goto out2;
+ }
+
+ if (retval == 0)
+ retval = nbytes;
+out2:
+ mutex_unlock(&cgroup_mutex);
+out1:
+ kfree(buffer);
+ return retval;
+}
+
+static ssize_t cgroup_file_write(struct file *file, const char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ struct cftype *cft = __d_cft(file->f_dentry);
+ struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+ if (!cft)
+ return -ENODEV;
+ if (cft->write)
+ return cft->write(cgrp, cft, file, buf, nbytes, ppos);
+ if (cft->write_uint)
+ return cgroup_write_uint(cgrp, cft, file, buf, nbytes, ppos);
+ return -EINVAL;
+}
+
+static ssize_t cgroup_read_uint(struct cgroup *cgrp, struct cftype *cft,
+ struct file *file,
+ char __user *buf, size_t nbytes,
+ loff_t *ppos)
+{
+ char tmp[64];
+ u64 val = cft->read_uint(cgrp, cft);
+ int len = sprintf(tmp, "%llu\n", (unsigned long long) val);
+
+ return simple_read_from_buffer(buf, nbytes, ppos, tmp, len);
+}
+
+static ssize_t cgroup_common_file_read(struct cgroup *cgrp,
+ struct cftype *cft,
+ struct file *file,
+ char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ enum cgroup_filetype type = cft->private;
+ char *page;
+ ssize_t retval = 0;
+ char *s;
+
+ if (!(page = (char *)__get_free_page(GFP_KERNEL)))
+ return -ENOMEM;
+
+ s = page;
+
+ switch (type) {
+ case FILE_RELEASE_AGENT:
+ {
+ struct cgroupfs_root *root;
+ size_t n;
+ mutex_lock(&cgroup_mutex);
+ root = cgrp->root;
+ n = strnlen(root->release_agent_path,
+ sizeof(root->release_agent_path));
+ n = min(n, (size_t) PAGE_SIZE);
+ strncpy(s, root->release_agent_path, n);
+ mutex_unlock(&cgroup_mutex);
+ s += n;
+ break;
+ }
+ default:
+ retval = -EINVAL;
+ goto out;
+ }
+ *s++ = '\n';
+
+ retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page);
+out:
+ free_page((unsigned long)page);
+ return retval;
+}
+
+static ssize_t cgroup_file_read(struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ struct cftype *cft = __d_cft(file->f_dentry);
+ struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+
+ if (!cft)
+ return -ENODEV;
+
+ if (cft->read)
+ return cft->read(cgrp, cft, file, buf, nbytes, ppos);
+ if (cft->read_uint)
+ return cgroup_read_uint(cgrp, cft, file, buf, nbytes, ppos);
+ return -EINVAL;
+}
+
+static int cgroup_file_open(struct inode *inode, struct file *file)
+{
+ int err;
+ struct cftype *cft;
+
+ err = generic_file_open(inode, file);
+ if (err)
+ return err;
+
+ cft = __d_cft(file->f_dentry);
+ if (!cft)
+ return -ENODEV;
+ if (cft->open)
+ err = cft->open(inode, file);
+ else
+ err = 0;
+
+ return err;
+}
+
+static int cgroup_file_release(struct inode *inode, struct file *file)
+{
+ struct cftype *cft = __d_cft(file->f_dentry);
+ if (cft->release)
+ return cft->release(inode, file);
+ return 0;
+}
+
+/*
+ * cgroup_rename - Only allow simple rename of directories in place.
+ */
+static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ if (!S_ISDIR(old_dentry->d_inode->i_mode))
+ return -ENOTDIR;
+ if (new_dentry->d_inode)
+ return -EEXIST;
+ if (old_dir != new_dir)
+ return -EIO;
+ return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
+}
+
+static struct file_operations cgroup_file_operations = {
+ .read = cgroup_file_read,
+ .write = cgroup_file_write,
+ .llseek = generic_file_llseek,
+ .open = cgroup_file_open,
+ .release = cgroup_file_release,
+};
+
+static struct inode_operations cgroup_dir_inode_operations = {
+ .lookup = simple_lookup,
+ .mkdir = cgroup_mkdir,
+ .rmdir = cgroup_rmdir,
+ .rename = cgroup_rename,
+};
+
+static int cgroup_create_file(struct dentry *dentry, int mode,
+ struct super_block *sb)
+{
+ static struct dentry_operations cgroup_dops = {
+ .d_iput = cgroup_diput,
+ };
+
+ struct inode *inode;
+
+ if (!dentry)
+ return -ENOENT;
+ if (dentry->d_inode)
+ return -EEXIST;
+
+ inode = cgroup_new_inode(mode, sb);
+ if (!inode)
+ return -ENOMEM;
+
+ if (S_ISDIR(mode)) {
+ inode->i_op = &cgroup_dir_inode_operations;
+ inode->i_fop = &simple_dir_operations;
+
+ /* start off with i_nlink == 2 (for "." entry) */
+ inc_nlink(inode);
+
+ /* start with the directory inode held, so that we can
+ * populate it without racing with another mkdir */
+ mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD);
+ } else if (S_ISREG(mode)) {
+ inode->i_size = 0;
+ inode->i_fop = &cgroup_file_operations;
+ }
+ dentry->d_op = &cgroup_dops;
+ d_instantiate(dentry, inode);
+ dget(dentry); /* Extra count - pin the dentry in core */
+ return 0;
+}
+
+/*
+ * cgroup_create_dir - create a directory for an object.
+ * cgrp: the cgroup we create the directory for.
+ * It must have a valid ->parent field
+ * And we are going to fill its ->dentry field.
+ * dentry: dentry of the new cgroup
+ * mode: mode to set on new directory.
+ */
+static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry,
+ int mode)
+{
+ struct dentry *parent;
+ int error = 0;
+
+ parent = cgrp->parent->dentry;
+ error = cgroup_create_file(dentry, S_IFDIR | mode, cgrp->root->sb);
+ if (!error) {
+ dentry->d_fsdata = cgrp;
+ inc_nlink(parent->d_inode);
+ cgrp->dentry = dentry;
+ dget(dentry);
+ }
+ dput(dentry);
+
+ return error;
+}
+
+int cgroup_add_file(struct cgroup *cgrp,
+ struct cgroup_subsys *subsys,
+ const struct cftype *cft)
+{
+ struct dentry *dir = cgrp->dentry;
+ struct dentry *dentry;
+ int error;
+
+ char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 };
+ if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) {
+ strcpy(name, subsys->name);
+ strcat(name, ".");
+ }
+ strcat(name, cft->name);
+ BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex));
+ dentry = lookup_one_len(name, dir, strlen(name));
+ if (!IS_ERR(dentry)) {
+ error = cgroup_create_file(dentry, 0644 | S_IFREG,
+ cgrp->root->sb);
+ if (!error)
+ dentry->d_fsdata = (void *)cft;
+ dput(dentry);
+ } else
+ error = PTR_ERR(dentry);
+ return error;
+}
+
+int cgroup_add_files(struct cgroup *cgrp,
+ struct cgroup_subsys *subsys,
+ const struct cftype cft[],
+ int count)
+{
+ int i, err;
+ for (i = 0; i < count; i++) {
+ err = cgroup_add_file(cgrp, subsys, &cft[i]);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+/* Count the number of tasks in a cgroup. */
+
+int cgroup_task_count(const struct cgroup *cgrp)
+{
+ int count = 0;
+ struct list_head *l;
+
+ read_lock(&css_set_lock);
+ l = cgrp->css_sets.next;
+ while (l != &cgrp->css_sets) {
+ struct cg_cgroup_link *link =
+ list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+ count += atomic_read(&link->cg->ref.refcount);
+ l = l->next;
+ }
+ read_unlock(&css_set_lock);
+ return count;
+}
+
+/*
+ * Advance a list_head iterator. The iterator should be positioned at
+ * the start of a css_set
+ */
+static void cgroup_advance_iter(struct cgroup *cgrp,
+ struct cgroup_iter *it)
+{
+ struct list_head *l = it->cg_link;
+ struct cg_cgroup_link *link;
+ struct css_set *cg;
+
+ /* Advance to the next non-empty css_set */
+ do {
+ l = l->next;
+ if (l == &cgrp->css_sets) {
+ it->cg_link = NULL;
+ return;
+ }
+ link = list_entry(l, struct cg_cgroup_link, cgrp_link_list);
+ cg = link->cg;
+ } while (list_empty(&cg->tasks));
+ it->cg_link = l;
+ it->task = cg->tasks.next;
+}
+
+void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+ /*
+ * The first time anyone tries to iterate across a cgroup,
+ * we need to enable the list linking each css_set to its
+ * tasks, and fix up all existing tasks.
+ */
+ if (!use_task_css_set_links) {
+ struct task_struct *p, *g;
+ write_lock(&css_set_lock);
+ use_task_css_set_links = 1;
+ do_each_thread(g, p) {
+ task_lock(p);
+ if (list_empty(&p->cg_list))
+ list_add(&p->cg_list, &p->cgroups->tasks);
+ task_unlock(p);
+ } while_each_thread(g, p);
+ write_unlock(&css_set_lock);
+ }
+ read_lock(&css_set_lock);
+ it->cg_link = &cgrp->css_sets;
+ cgroup_advance_iter(cgrp, it);
+}
+
+struct task_struct *cgroup_iter_next(struct cgroup *cgrp,
+ struct cgroup_iter *it)
+{
+ struct task_struct *res;
+ struct list_head *l = it->task;
+
+ /* If the iterator cg is NULL, we have no tasks */
+ if (!it->cg_link)
+ return NULL;
+ res = list_entry(l, struct task_struct, cg_list);
+ /* Advance iterator to find next entry */
+ l = l->next;
+ if (l == &res->cgroups->tasks) {
+ /* We reached the end of this task list - move on to
+ * the next cg_cgroup_link */
+ cgroup_advance_iter(cgrp, it);
+ } else {
+ it->task = l;
+ }
+ return res;
+}
+
+void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it)
+{
+ read_unlock(&css_set_lock);
+}
+
+/*
+ * Stuff for reading the 'tasks' file.
+ *
+ * Reading this file can return large amounts of data if a cgroup has
+ * *lots* of attached tasks. So it may need several calls to read(),
+ * but we cannot guarantee that the information we produce is correct
+ * unless we produce it entirely atomically.
+ *
+ * Upon tasks file open(), a struct ctr_struct is allocated, that
+ * will have a pointer to an array (also allocated here). The struct
+ * ctr_struct * is stored in file->private_data. Its resources will
+ * be freed by release() when the file is closed. The array is used
+ * to sprintf the PIDs and then used by read().
+ */
+struct ctr_struct {
+ char *buf;
+ int bufsz;
+};
+
+/*
+ * Load into 'pidarray' up to 'npids' of the tasks using cgroup
+ * 'cgrp'. Return actual number of pids loaded. No need to
+ * task_lock(p) when reading out p->cgroup, since we're in an RCU
+ * read section, so the css_set can't go away, and is
+ * immutable after creation.
+ */
+static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp)
+{
+ int n = 0;
+ struct cgroup_iter it;
+ struct task_struct *tsk;
+ cgroup_iter_start(cgrp, &it);
+ while ((tsk = cgroup_iter_next(cgrp, &it))) {
+ if (unlikely(n == npids))
+ break;
+ pidarray[n++] = task_pid_nr(tsk);
+ }
+ cgroup_iter_end(cgrp, &it);
+ return n;
+}
+
+/**
+ * Build and fill cgroupstats so that taskstats can export it to user
+ * space.
+ *
+ * @stats: cgroupstats to fill information into
+ * @dentry: A dentry entry belonging to the cgroup for which stats have
+ * been requested.
+ */
+int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry)
+{
+ int ret = -EINVAL;
+ struct cgroup *cgrp;
+ struct cgroup_iter it;
+ struct task_struct *tsk;
+ /*
+ * Validate dentry by checking the superblock operations
+ */
+ if (dentry->d_sb->s_op != &cgroup_ops)
+ goto err;
+
+ ret = 0;
+ cgrp = dentry->d_fsdata;
+ rcu_read_lock();
+
+ cgroup_iter_start(cgrp, &it);
+ while ((tsk = cgroup_iter_next(cgrp, &it))) {
+ switch (tsk->state) {
+ case TASK_RUNNING:
+ stats->nr_running++;
+ break;
+ case TASK_INTERRUPTIBLE:
+ stats->nr_sleeping++;
+ break;
+ case TASK_UNINTERRUPTIBLE:
+ stats->nr_uninterruptible++;
+ break;
+ case TASK_STOPPED:
+ stats->nr_stopped++;
+ break;
+ default:
+ if (delayacct_is_task_waiting_on_io(tsk))
+ stats->nr_io_wait++;
+ break;
+ }
+ }
+ cgroup_iter_end(cgrp, &it);
+
+ rcu_read_unlock();
+err:
+ return ret;
+}
+
+static int cmppid(const void *a, const void *b)
+{
+ return *(pid_t *)a - *(pid_t *)b;
+}
+
+/*
+ * Convert array 'a' of 'npids' pid_t's to a string of newline separated
+ * decimal pids in 'buf'. Don't write more than 'sz' chars, but return
+ * count 'cnt' of how many chars would be written if buf were large enough.
+ */
+static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
+{
+ int cnt = 0;
+ int i;
+
+ for (i = 0; i < npids; i++)
+ cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
+ return cnt;
+}
+
+/*
+ * Handle an open on 'tasks' file. Prepare a buffer listing the
+ * process id's of tasks currently attached to the cgroup being opened.
+ *
+ * Does not require any specific cgroup mutexes, and does not take any.
+ */
+static int cgroup_tasks_open(struct inode *unused, struct file *file)
+{
+ struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
+ struct ctr_struct *ctr;
+ pid_t *pidarray;
+ int npids;
+ char c;
+
+ if (!(file->f_mode & FMODE_READ))
+ return 0;
+
+ ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
+ if (!ctr)
+ goto err0;
+
+ /*
+ * If cgroup gets more users after we read count, we won't have
+ * enough space - tough. This race is indistinguishable to the
+ * caller from the case that the additional cgroup users didn't
+ * show up until sometime later on.
+ */
+ npids = cgroup_task_count(cgrp);
+ if (npids) {
+ pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
+ if (!pidarray)
+ goto err1;
+
+ npids = pid_array_load(pidarray, npids, cgrp);
+ sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
+
+ /* Call pid_array_to_buf() twice, first just to get bufsz */
+ ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
+ ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
+ if (!ctr->buf)
+ goto err2;
+ ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
+
+ kfree(pidarray);
+ } else {
+ ctr->buf = 0;
+ ctr->bufsz = 0;
+ }
+ file->private_data = ctr;
+ return 0;
+
+err2:
+ kfree(pidarray);
+err1:
+ kfree(ctr);
+err0:
+ return -ENOMEM;
+}
+
+static ssize_t cgroup_tasks_read(struct cgroup *cgrp,
+ struct cftype *cft,
+ struct file *file, char __user *buf,
+ size_t nbytes, loff_t *ppos)
+{
+ struct ctr_struct *ctr = file->private_data;
+
+ return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
+}
+
+static int cgroup_tasks_release(struct inode *unused_inode,
+ struct file *file)
+{
+ struct ctr_struct *ctr;
+
+ if (file->f_mode & FMODE_READ) {
+ ctr = file->private_data;
+ kfree(ctr->buf);
+ kfree(ctr);
+ }
+ return 0;
+}
+
+static u64 cgroup_read_notify_on_release(struct cgroup *cgrp,
+ struct cftype *cft)
+{
+ return notify_on_release(cgrp);
+}
+
+static u64 cgroup_read_releasable(struct cgroup *cgrp, struct cftype *cft)
+{
+ return test_bit(CGRP_RELEASABLE, &cgrp->flags);
+}
+
+/*
+ * for the common functions, 'private' gives the type of file
+ */
+static struct cftype files[] = {
+ {
+ .name = "tasks",
+ .open = cgroup_tasks_open,
+ .read = cgroup_tasks_read,
+ .write = cgroup_common_file_write,
+ .release = cgroup_tasks_release,
+ .private = FILE_TASKLIST,
+ },
+
+ {
+ .name = "notify_on_release",
+ .read_uint = cgroup_read_notify_on_release,
+ .write = cgroup_common_file_write,
+ .private = FILE_NOTIFY_ON_RELEASE,
+ },
+
+ {
+ .name = "releasable",
+ .read_uint = cgroup_read_releasable,
+ .private = FILE_RELEASABLE,
+ }
+};
+
+static struct cftype cft_release_agent = {
+ .name = "release_agent",
+ .read = cgroup_common_file_read,
+ .write = cgroup_common_file_write,
+ .private = FILE_RELEASE_AGENT,
+};
+
+static int cgroup_populate_dir(struct cgroup *cgrp)
+{
+ int err;
+ struct cgroup_subsys *ss;
+
+ /* First clear out any existing files */
+ cgroup_clear_directory(cgrp->dentry);
+
+ err = cgroup_add_files(cgrp, NULL, files, ARRAY_SIZE(files));
+ if (err < 0)
+ return err;
+
+ if (cgrp == cgrp->top_cgroup) {
+ if ((err = cgroup_add_file(cgrp, NULL, &cft_release_agent)) < 0)
+ return err;
+ }
+
+ for_each_subsys(cgrp->root, ss) {
+ if (ss->populate && (err = ss->populate(ss, cgrp)) < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static void init_cgroup_css(struct cgroup_subsys_state *css,
+ struct cgroup_subsys *ss,
+ struct cgroup *cgrp)
+{
+ css->cgroup = cgrp;
+ atomic_set(&css->refcnt, 0);
+ css->flags = 0;
+ if (cgrp == dummytop)
+ set_bit(CSS_ROOT, &css->flags);
+ BUG_ON(cgrp->subsys[ss->subsys_id]);
+ cgrp->subsys[ss->subsys_id] = css;
+}
+
+/*
+ * cgroup_create - create a cgroup
+ * parent: cgroup that will be parent of the new cgroup.
+ * name: name of the new cgroup. Will be strcpy'ed.
+ * mode: mode to set on new inode
+ *
+ * Must be called with the mutex on the parent inode held
+ */
+
+static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
+ int mode)
+{
+ struct cgroup *cgrp;
+ struct cgroupfs_root *root = parent->root;
+ int err = 0;
+ struct cgroup_subsys *ss;
+ struct super_block *sb = root->sb;
+
+ cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL);
+ if (!cgrp)
+ return -ENOMEM;
+
+ /* Grab a reference on the superblock so the hierarchy doesn't
+ * get deleted on unmount if there are child cgroups. This
+ * can be done outside cgroup_mutex, since the sb can't
+ * disappear while someone has an open control file on the
+ * fs */
+ atomic_inc(&sb->s_active);
+
+ mutex_lock(&cgroup_mutex);
+
+ cgrp->flags = 0;
+ INIT_LIST_HEAD(&cgrp->sibling);
+ INIT_LIST_HEAD(&cgrp->children);
+ INIT_LIST_HEAD(&cgrp->css_sets);
+ INIT_LIST_HEAD(&cgrp->release_list);
+
+ cgrp->parent = parent;
+ cgrp->root = parent->root;
+ cgrp->top_cgroup = parent->top_cgroup;
+
+ for_each_subsys(root, ss) {
+ struct cgroup_subsys_state *css = ss->create(ss, cgrp);
+ if (IS_ERR(css)) {
+ err = PTR_ERR(css);
+ goto err_destroy;
+ }
+ init_cgroup_css(css, ss, cgrp);
+ }
+
+ list_add(&cgrp->sibling, &cgrp->parent->children);
+ root->number_of_cgroups++;
+
+ err = cgroup_create_dir(cgrp, dentry, mode);
+ if (err < 0)
+ goto err_remove;
+
+ /* The cgroup directory was pre-locked for us */
+ BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex));
+
+ err = cgroup_populate_dir(cgrp);
+ /* If err < 0, we have a half-filled directory - oh well ;) */
+
+ mutex_unlock(&cgroup_mutex);
+ mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
+
+ return 0;
+
+ err_remove:
+
+ list_del(&cgrp->sibling);
+ root->number_of_cgroups--;
+
+ err_destroy:
+
+ for_each_subsys(root, ss) {
+ if (cgrp->subsys[ss->subsys_id])
+ ss->destroy(ss, cgrp);
+ }
+
+ mutex_unlock(&cgroup_mutex);
+
+ /* Release the reference count that we took on the superblock */
+ deactivate_super(sb);
+
+ kfree(cgrp);
+ return err;
+}
+
+static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ struct cgroup *c_parent = dentry->d_parent->d_fsdata;
+
+ /* the vfs holds inode->i_mutex already */
+ return cgroup_create(c_parent, dentry, mode | S_IFDIR);
+}
+
+static inline int cgroup_has_css_refs(struct cgroup *cgrp)
+{
+ /* Check the reference count on each subsystem. Since we
+ * already established that there are no tasks in the
+ * cgroup, if the css refcount is also 0, then there should
+ * be no outstanding references, so the subsystem is safe to
+ * destroy. We scan across all subsystems rather than using
+ * the per-hierarchy linked list of mounted subsystems since
+ * we can be called via check_for_release() with no
+ * synchronization other than RCU, and the subsystem linked
+ * list isn't RCU-safe */
+ int i;
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ struct cgroup_subsys_state *css;
+ /* Skip subsystems not in this hierarchy */
+ if (ss->root != cgrp->root)
+ continue;
+ css = cgrp->subsys[ss->subsys_id];
+ /* When called from check_for_release() it's possible
+ * that by this point the cgroup has been removed
+ * and the css deleted. But a false-positive doesn't
+ * matter, since it can only happen if the cgroup
+ * has been deleted and hence no longer needs the
+ * release agent to be called anyway. */
+ if (css && atomic_read(&css->refcnt)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry)
+{
+ struct cgroup *cgrp = dentry->d_fsdata;
+ struct dentry *d;
+ struct cgroup *parent;
+ struct cgroup_subsys *ss;
+ struct super_block *sb;
+ struct cgroupfs_root *root;
+
+ /* the vfs holds both inode->i_mutex already */
+
+ mutex_lock(&cgroup_mutex);
+ if (atomic_read(&cgrp->count) != 0) {
+ mutex_unlock(&cgroup_mutex);
+ return -EBUSY;
+ }
+ if (!list_empty(&cgrp->children)) {
+ mutex_unlock(&cgroup_mutex);
+ return -EBUSY;
+ }
+
+ parent = cgrp->parent;
+ root = cgrp->root;
+ sb = root->sb;
+
+ if (cgroup_has_css_refs(cgrp)) {
+ mutex_unlock(&cgroup_mutex);
+ return -EBUSY;
+ }
+
+ for_each_subsys(root, ss) {
+ if (cgrp->subsys[ss->subsys_id])
+ ss->destroy(ss, cgrp);
+ }
+
+ spin_lock(&release_list_lock);
+ set_bit(CGRP_REMOVED, &cgrp->flags);
+ if (!list_empty(&cgrp->release_list))
+ list_del(&cgrp->release_list);
+ spin_unlock(&release_list_lock);
+ /* delete my sibling from parent->children */
+ list_del(&cgrp->sibling);
+ spin_lock(&cgrp->dentry->d_lock);
+ d = dget(cgrp->dentry);
+ cgrp->dentry = NULL;
+ spin_unlock(&d->d_lock);
+
+ cgroup_d_remove_dir(d);
+ dput(d);
+ root->number_of_cgroups--;
+
+ set_bit(CGRP_RELEASABLE, &parent->flags);
+ check_for_release(parent);
+
+ mutex_unlock(&cgroup_mutex);
+ /* Drop the active superblock reference that we took when we
+ * created the cgroup */
+ deactivate_super(sb);
+ return 0;
+}
+
+static void cgroup_init_subsys(struct cgroup_subsys *ss)
+{
+ struct cgroup_subsys_state *css;
+ struct list_head *l;
+ printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name);
+
+ /* Create the top cgroup state for this subsystem */
+ ss->root = &rootnode;
+ css = ss->create(ss, dummytop);
+ /* We don't handle early failures gracefully */
+ BUG_ON(IS_ERR(css));
+ init_cgroup_css(css, ss, dummytop);
+
+ /* Update all cgroup groups to contain a subsys
+ * pointer to this state - since the subsystem is
+ * newly registered, all tasks and hence all cgroup
+ * groups are in the subsystem's top cgroup. */
+ write_lock(&css_set_lock);
+ l = &init_css_set.list;
+ do {
+ struct css_set *cg =
+ list_entry(l, struct css_set, list);
+ cg->subsys[ss->subsys_id] = dummytop->subsys[ss->subsys_id];
+ l = l->next;
+ } while (l != &init_css_set.list);
+ write_unlock(&css_set_lock);
+
+ /* If this subsystem requested that it be notified with fork
+ * events, we should send it one now for every process in the
+ * system */
+ if (ss->fork) {
+ struct task_struct *g, *p;
+
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ ss->fork(ss, p);
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+ }
+
+ need_forkexit_callback |= ss->fork || ss->exit;
+
+ ss->active = 1;
+}
+
+/**
+ * cgroup_init_early - initialize cgroups at system boot, and
+ * initialize any subsystems that request early init.
+ */
+int __init cgroup_init_early(void)
+{
+ int i;
+ kref_init(&init_css_set.ref);
+ kref_get(&init_css_set.ref);
+ INIT_LIST_HEAD(&init_css_set.list);
+ INIT_LIST_HEAD(&init_css_set.cg_links);
+ INIT_LIST_HEAD(&init_css_set.tasks);
+ css_set_count = 1;
+ init_cgroup_root(&rootnode);
+ list_add(&rootnode.root_list, &roots);
+ root_count = 1;
+ init_task.cgroups = &init_css_set;
+
+ init_css_set_link.cg = &init_css_set;
+ list_add(&init_css_set_link.cgrp_link_list,
+ &rootnode.top_cgroup.css_sets);
+ list_add(&init_css_set_link.cg_link_list,
+ &init_css_set.cg_links);
+
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+
+ BUG_ON(!ss->name);
+ BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN);
+ BUG_ON(!ss->create);
+ BUG_ON(!ss->destroy);
+ if (ss->subsys_id != i) {
+ printk(KERN_ERR "Subsys %s id == %d\n",
+ ss->name, ss->subsys_id);
+ BUG();
+ }
+
+ if (ss->early_init)
+ cgroup_init_subsys(ss);
+ }
+ return 0;
+}
+
+/**
+ * cgroup_init - register cgroup filesystem and /proc file, and
+ * initialize any subsystems that didn't request early init.
+ */
+int __init cgroup_init(void)
+{
+ int err;
+ int i;
+ struct proc_dir_entry *entry;
+
+ err = bdi_init(&cgroup_backing_dev_info);
+ if (err)
+ return err;
+
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ if (!ss->early_init)
+ cgroup_init_subsys(ss);
+ }
+
+ err = register_filesystem(&cgroup_fs_type);
+ if (err < 0)
+ goto out;
+
+ entry = create_proc_entry("cgroups", 0, NULL);
+ if (entry)
+ entry->proc_fops = &proc_cgroupstats_operations;
+
+out:
+ if (err)
+ bdi_destroy(&cgroup_backing_dev_info);
+
+ return err;
+}
+
+/*
+ * proc_cgroup_show()
+ * - Print task's cgroup paths into seq_file, one line for each hierarchy
+ * - Used for /proc/<pid>/cgroup.
+ * - No need to task_lock(tsk) on this tsk->cgroup reference, as it
+ * doesn't really matter if tsk->cgroup changes after we read it,
+ * and we take cgroup_mutex, keeping attach_task() from changing it
+ * anyway. No need to check that tsk->cgroup != NULL, thanks to
+ * the_top_cgroup_hack in cgroup_exit(), which sets an exiting tasks
+ * cgroup to top_cgroup.
+ */
+
+/* TODO: Use a proper seq_file iterator */
+static int proc_cgroup_show(struct seq_file *m, void *v)
+{
+ struct pid *pid;
+ struct task_struct *tsk;
+ char *buf;
+ int retval;
+ struct cgroupfs_root *root;
+
+ retval = -ENOMEM;
+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ goto out;
+
+ retval = -ESRCH;
+ pid = m->private;
+ tsk = get_pid_task(pid, PIDTYPE_PID);
+ if (!tsk)
+ goto out_free;
+
+ retval = 0;
+
+ mutex_lock(&cgroup_mutex);
+
+ for_each_root(root) {
+ struct cgroup_subsys *ss;
+ struct cgroup *cgrp;
+ int subsys_id;
+ int count = 0;
+
+ /* Skip this hierarchy if it has no active subsystems */
+ if (!root->actual_subsys_bits)
+ continue;
+ for_each_subsys(root, ss)
+ seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
+ seq_putc(m, ':');
+ get_first_subsys(&root->top_cgroup, NULL, &subsys_id);
+ cgrp = task_cgroup(tsk, subsys_id);
+ retval = cgroup_path(cgrp, buf, PAGE_SIZE);
+ if (retval < 0)
+ goto out_unlock;
+ seq_puts(m, buf);
+ seq_putc(m, '\n');
+ }
+
+out_unlock:
+ mutex_unlock(&cgroup_mutex);
+ put_task_struct(tsk);
+out_free:
+ kfree(buf);
+out:
+ return retval;
+}
+
+static int cgroup_open(struct inode *inode, struct file *file)
+{
+ struct pid *pid = PROC_I(inode)->pid;
+ return single_open(file, proc_cgroup_show, pid);
+}
+
+struct file_operations proc_cgroup_operations = {
+ .open = cgroup_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/* Display information about each subsystem and each hierarchy */
+static int proc_cgroupstats_show(struct seq_file *m, void *v)
+{
+ int i;
+ struct cgroupfs_root *root;
+
+ seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\n");
+ mutex_lock(&cgroup_mutex);
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ seq_printf(m, "%s\t%lu\t%d\n",
+ ss->name, ss->root->subsys_bits,
+ ss->root->number_of_cgroups);
+ }
+ mutex_unlock(&cgroup_mutex);
+ return 0;
+}
+
+static int cgroupstats_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, proc_cgroupstats_show, 0);
+}
+
+static struct file_operations proc_cgroupstats_operations = {
+ .open = cgroupstats_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+/**
+ * cgroup_fork - attach newly forked task to its parents cgroup.
+ * @tsk: pointer to task_struct of forking parent process.
+ *
+ * Description: A task inherits its parent's cgroup at fork().
+ *
+ * A pointer to the shared css_set was automatically copied in
+ * fork.c by dup_task_struct(). However, we ignore that copy, since
+ * it was not made under the protection of RCU or cgroup_mutex, so
+ * might no longer be a valid cgroup pointer. attach_task() might
+ * have already changed current->cgroups, allowing the previously
+ * referenced cgroup group to be removed and freed.
+ *
+ * At the point that cgroup_fork() is called, 'current' is the parent
+ * task, and the passed argument 'child' points to the child task.
+ */
+void cgroup_fork(struct task_struct *child)
+{
+ task_lock(current);
+ child->cgroups = current->cgroups;
+ get_css_set(child->cgroups);
+ task_unlock(current);
+ INIT_LIST_HEAD(&child->cg_list);
+}
+
+/**
+ * cgroup_fork_callbacks - called on a new task very soon before
+ * adding it to the tasklist. No need to take any locks since no-one
+ * can be operating on this task
+ */
+void cgroup_fork_callbacks(struct task_struct *child)
+{
+ if (need_forkexit_callback) {
+ int i;
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ if (ss->fork)
+ ss->fork(ss, child);
+ }
+ }
+}
+
+/**
+ * cgroup_post_fork - called on a new task after adding it to the
+ * task list. Adds the task to the list running through its css_set
+ * if necessary. Has to be after the task is visible on the task list
+ * in case we race with the first call to cgroup_iter_start() - to
+ * guarantee that the new task ends up on its list. */
+void cgroup_post_fork(struct task_struct *child)
+{
+ if (use_task_css_set_links) {
+ write_lock(&css_set_lock);
+ if (list_empty(&child->cg_list))
+ list_add(&child->cg_list, &child->cgroups->tasks);
+ write_unlock(&css_set_lock);
+ }
+}
+/**
+ * cgroup_exit - detach cgroup from exiting task
+ * @tsk: pointer to task_struct of exiting process
+ *
+ * Description: Detach cgroup from @tsk and release it.
+ *
+ * Note that cgroups marked notify_on_release force every task in
+ * them to take the global cgroup_mutex mutex when exiting.
+ * This could impact scaling on very large systems. Be reluctant to
+ * use notify_on_release cgroups where very high task exit scaling
+ * is required on large systems.
+ *
+ * the_top_cgroup_hack:
+ *
+ * Set the exiting tasks cgroup to the root cgroup (top_cgroup).
+ *
+ * We call cgroup_exit() while the task is still competent to
+ * handle notify_on_release(), then leave the task attached to the
+ * root cgroup in each hierarchy for the remainder of its exit.
+ *
+ * To do this properly, we would increment the reference count on
+ * top_cgroup, and near the very end of the kernel/exit.c do_exit()
+ * code we would add a second cgroup function call, to drop that
+ * reference. This would just create an unnecessary hot spot on
+ * the top_cgroup reference count, to no avail.
+ *
+ * Normally, holding a reference to a cgroup without bumping its
+ * count is unsafe. The cgroup could go away, or someone could
+ * attach us to a different cgroup, decrementing the count on
+ * the first cgroup that we never incremented. But in this case,
+ * top_cgroup isn't going away, and either task has PF_EXITING set,
+ * which wards off any attach_task() attempts, or task is a failed
+ * fork, never visible to attach_task.
+ *
+ */
+void cgroup_exit(struct task_struct *tsk, int run_callbacks)
+{
+ int i;
+ struct css_set *cg;
+
+ if (run_callbacks && need_forkexit_callback) {
+ for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
+ struct cgroup_subsys *ss = subsys[i];
+ if (ss->exit)
+ ss->exit(ss, tsk);
+ }
+ }
+
+ /*
+ * Unlink from the css_set task list if necessary.
+ * Optimistically check cg_list before taking
+ * css_set_lock
+ */
+ if (!list_empty(&tsk->cg_list)) {
+ write_lock(&css_set_lock);
+ if (!list_empty(&tsk->cg_list))
+ list_del(&tsk->cg_list);
+ write_unlock(&css_set_lock);
+ }
+
+ /* Reassign the task to the init_css_set. */
+ task_lock(tsk);
+ cg = tsk->cgroups;
+ tsk->cgroups = &init_css_set;
+ task_unlock(tsk);
+ if (cg)
+ put_css_set_taskexit(cg);
+}
+
+/**
+ * cgroup_clone - duplicate the current cgroup in the hierarchy
+ * that the given subsystem is attached to, and move this task into
+ * the new child
+ */
+int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys)
+{
+ struct dentry *dentry;
+ int ret = 0;
+ char nodename[MAX_CGROUP_TYPE_NAMELEN];
+ struct cgroup *parent, *child;
+ struct inode *inode;
+ struct css_set *cg;
+ struct cgroupfs_root *root;
+ struct cgroup_subsys *ss;
+
+ /* We shouldn't be called by an unregistered subsystem */
+ BUG_ON(!subsys->active);
+
+ /* First figure out what hierarchy and cgroup we're dealing
+ * with, and pin them so we can drop cgroup_mutex */
+ mutex_lock(&cgroup_mutex);
+ again:
+ root = subsys->root;
+ if (root == &rootnode) {
+ printk(KERN_INFO
+ "Not cloning cgroup for unused subsystem %s\n",
+ subsys->name);
+ mutex_unlock(&cgroup_mutex);
+ return 0;
+ }
+ cg = tsk->cgroups;
+ parent = task_cgroup(tsk, subsys->subsys_id);
+
+ snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "node_%d", tsk->pid);
+
+ /* Pin the hierarchy */
+ atomic_inc(&parent->root->sb->s_active);
+
+ /* Keep the cgroup alive */
+ get_css_set(cg);
+ mutex_unlock(&cgroup_mutex);
+
+ /* Now do the VFS work to create a cgroup */
+ inode = parent->dentry->d_inode;
+
+ /* Hold the parent directory mutex across this operation to
+ * stop anyone else deleting the new cgroup */
+ mutex_lock(&inode->i_mutex);
+ dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename));
+ if (IS_ERR(dentry)) {
+ printk(KERN_INFO
+ "Couldn't allocate dentry for %s: %ld\n", nodename,
+ PTR_ERR(dentry));
+ ret = PTR_ERR(dentry);
+ goto out_release;
+ }
+
+ /* Create the cgroup directory, which also creates the cgroup */
+ ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755);
+ child = __d_cgrp(dentry);
+ dput(dentry);
+ if (ret) {
+ printk(KERN_INFO
+ "Failed to create cgroup %s: %d\n", nodename,
+ ret);
+ goto out_release;
+ }
+
+ if (!child) {
+ printk(KERN_INFO
+ "Couldn't find new cgroup %s\n", nodename);
+ ret = -ENOMEM;
+ goto out_release;
+ }
+
+ /* The cgroup now exists. Retake cgroup_mutex and check
+ * that we're still in the same state that we thought we
+ * were. */
+ mutex_lock(&cgroup_mutex);
+ if ((root != subsys->root) ||
+ (parent != task_cgroup(tsk, subsys->subsys_id))) {
+ /* Aargh, we raced ... */
+ mutex_unlock(&inode->i_mutex);
+ put_css_set(cg);
+
+ deactivate_super(parent->root->sb);
+ /* The cgroup is still accessible in the VFS, but
+ * we're not going to try to rmdir() it at this
+ * point. */
+ printk(KERN_INFO
+ "Race in cgroup_clone() - leaking cgroup %s\n",
+ nodename);
+ goto again;
+ }
+
+ /* do any required auto-setup */
+ for_each_subsys(root, ss) {
+ if (ss->post_clone)
+ ss->post_clone(ss, child);
+ }
+
+ /* All seems fine. Finish by moving the task into the new cgroup */
+ ret = attach_task(child, tsk);
+ mutex_unlock(&cgroup_mutex);
+
+ out_release:
+ mutex_unlock(&inode->i_mutex);
+
+ mutex_lock(&cgroup_mutex);
+ put_css_set(cg);
+ mutex_unlock(&cgroup_mutex);
+ deactivate_super(parent->root->sb);
+ return ret;
+}
+
+/*
+ * See if "cgrp" is a descendant of the current task's cgroup in
+ * the appropriate hierarchy
+ *
+ * If we are sending in dummytop, then presumably we are creating
+ * the top cgroup in the subsystem.
+ *
+ * Called only by the ns (nsproxy) cgroup.
+ */
+int cgroup_is_descendant(const struct cgroup *cgrp)
+{
+ int ret;
+ struct cgroup *target;
+ int subsys_id;
+
+ if (cgrp == dummytop)
+ return 1;
+
+ get_first_subsys(cgrp, NULL, &subsys_id);
+ target = task_cgroup(current, subsys_id);
+ while (cgrp != target && cgrp!= cgrp->top_cgroup)
+ cgrp = cgrp->parent;
+ ret = (cgrp == target);
+ return ret;
+}
+
+static void check_for_release(struct cgroup *cgrp)
+{
+ /* All of these checks rely on RCU to keep the cgroup
+ * structure alive */
+ if (cgroup_is_releasable(cgrp) && !atomic_read(&cgrp->count)
+ && list_empty(&cgrp->children) && !cgroup_has_css_refs(cgrp)) {
+ /* Control Group is currently removeable. If it's not
+ * already queued for a userspace notification, queue
+ * it now */
+ int need_schedule_work = 0;
+ spin_lock(&release_list_lock);
+ if (!cgroup_is_removed(cgrp) &&
+ list_empty(&cgrp->release_list)) {
+ list_add(&cgrp->release_list, &release_list);
+ need_schedule_work = 1;
+ }
+ spin_unlock(&release_list_lock);
+ if (need_schedule_work)
+ schedule_work(&release_agent_work);
+ }
+}
+
+void __css_put(struct cgroup_subsys_state *css)
+{
+ struct cgroup *cgrp = css->cgroup;
+ rcu_read_lock();
+ if (atomic_dec_and_test(&css->refcnt) && notify_on_release(cgrp)) {
+ set_bit(CGRP_RELEASABLE, &cgrp->flags);
+ check_for_release(cgrp);
+ }
+ rcu_read_unlock();
+}
+
+/*
+ * Notify userspace when a cgroup is released, by running the
+ * configured release agent with the name of the cgroup (path
+ * relative to the root of cgroup file system) as the argument.
+ *
+ * Most likely, this user command will try to rmdir this cgroup.
+ *
+ * This races with the possibility that some other task will be
+ * attached to this cgroup before it is removed, or that some other
+ * user task will 'mkdir' a child cgroup of this cgroup. That's ok.
+ * The presumed 'rmdir' will fail quietly if this cgroup is no longer
+ * unused, and this cgroup will be reprieved from its death sentence,
+ * to continue to serve a useful existence. Next time it's released,
+ * we will get notified again, if it still has 'notify_on_release' set.
+ *
+ * The final arg to call_usermodehelper() is UMH_WAIT_EXEC, which
+ * means only wait until the task is successfully execve()'d. The
+ * separate release agent task is forked by call_usermodehelper(),
+ * then control in this thread returns here, without waiting for the
+ * release agent task. We don't bother to wait because the caller of
+ * this routine has no use for the exit status of the release agent
+ * task, so no sense holding our caller up for that.
+ *
+ */
+
+static void cgroup_release_agent(struct work_struct *work)
+{
+ BUG_ON(work != &release_agent_work);
+ mutex_lock(&cgroup_mutex);
+ spin_lock(&release_list_lock);
+ while (!list_empty(&release_list)) {
+ char *argv[3], *envp[3];
+ int i;
+ char *pathbuf;
+ struct cgroup *cgrp = list_entry(release_list.next,
+ struct cgroup,
+ release_list);
+ list_del_init(&cgrp->release_list);
+ spin_unlock(&release_list_lock);
+ pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!pathbuf) {
+ spin_lock(&release_list_lock);
+ continue;
+ }
+
+ if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0) {
+ kfree(pathbuf);
+ spin_lock(&release_list_lock);
+ continue;
+ }
+
+ i = 0;
+ argv[i++] = cgrp->root->release_agent_path;
+ argv[i++] = (char *)pathbuf;
+ argv[i] = NULL;
+
+ i = 0;
+ /* minimal command environment */
+ envp[i++] = "HOME=/";
+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+ envp[i] = NULL;
+
+ /* Drop the lock while we invoke the usermode helper,
+ * since the exec could involve hitting disk and hence
+ * be a slow process */
+ mutex_unlock(&cgroup_mutex);
+ call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+ kfree(pathbuf);
+ mutex_lock(&cgroup_mutex);
+ spin_lock(&release_list_lock);
+ }
+ spin_unlock(&release_list_lock);
+ mutex_unlock(&cgroup_mutex);
+}
diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c
new file mode 100644
index 00000000000..37301e877cb
--- /dev/null
+++ b/kernel/cgroup_debug.c
@@ -0,0 +1,97 @@
+/*
+ * kernel/ccontainer_debug.c - Example cgroup subsystem that
+ * exposes debug info
+ *
+ * Copyright (C) Google Inc, 2007
+ *
+ * Developed by Paul Menage (menage@google.com)
+ *
+ */
+
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/rcupdate.h>
+
+#include <asm/atomic.h>
+
+static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss,
+ struct cgroup *cont)
+{
+ struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL);
+
+ if (!css)
+ return ERR_PTR(-ENOMEM);
+
+ return css;
+}
+
+static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ kfree(cont->subsys[debug_subsys_id]);
+}
+
+static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft)
+{
+ return atomic_read(&cont->count);
+}
+
+static u64 taskcount_read(struct cgroup *cont, struct cftype *cft)
+{
+ u64 count;
+
+ cgroup_lock();
+ count = cgroup_task_count(cont);
+ cgroup_unlock();
+ return count;
+}
+
+static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft)
+{
+ return (u64)(long)current->cgroups;
+}
+
+static u64 current_css_set_refcount_read(struct cgroup *cont,
+ struct cftype *cft)
+{
+ u64 count;
+
+ rcu_read_lock();
+ count = atomic_read(&current->cgroups->ref.refcount);
+ rcu_read_unlock();
+ return count;
+}
+
+static struct cftype files[] = {
+ {
+ .name = "cgroup_refcount",
+ .read_uint = cgroup_refcount_read,
+ },
+ {
+ .name = "taskcount",
+ .read_uint = taskcount_read,
+ },
+
+ {
+ .name = "current_css_set",
+ .read_uint = current_css_set_read,
+ },
+
+ {
+ .name = "current_css_set_refcount",
+ .read_uint = current_css_set_refcount_read,
+ },
+};
+
+static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+struct cgroup_subsys debug_subsys = {
+ .name = "debug",
+ .create = debug_create,
+ .destroy = debug_destroy,
+ .populate = debug_populate,
+ .subsys_id = debug_subsys_id,
+};
diff --git a/kernel/cpu.c b/kernel/cpu.c
index a21f71af9d8..6b3a0c15144 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -98,7 +98,8 @@ static inline void check_for_tasks(int cpu)
!cputime_eq(p->stime, cputime_zero)))
printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\
(state = %ld, flags = %x) \n",
- p->comm, p->pid, cpu, p->state, p->flags);
+ p->comm, task_pid_nr(p), cpu,
+ p->state, p->flags);
}
write_unlock_irq(&tasklist_lock);
}
@@ -264,6 +265,15 @@ out_notify:
int __cpuinit cpu_up(unsigned int cpu)
{
int err = 0;
+ if (!cpu_isset(cpu, cpu_possible_map)) {
+ printk(KERN_ERR "can't online cpu %d because it is not "
+ "configured as may-hotadd at boot time\n", cpu);
+#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) || defined(CONFIG_S390)
+ printk(KERN_ERR "please check additional_cpus= boot "
+ "parameter\n");
+#endif
+ return -EINVAL;
+ }
mutex_lock(&cpu_add_remove_lock);
if (cpu_hotplug_disabled)
diff --git a/kernel/cpu_acct.c b/kernel/cpu_acct.c
new file mode 100644
index 00000000000..731e47e7f16
--- /dev/null
+++ b/kernel/cpu_acct.c
@@ -0,0 +1,186 @@
+/*
+ * kernel/cpu_acct.c - CPU accounting cgroup subsystem
+ *
+ * Copyright (C) Google Inc, 2006
+ *
+ * Developed by Paul Menage (menage@google.com) and Balbir Singh
+ * (balbir@in.ibm.com)
+ *
+ */
+
+/*
+ * Example cgroup subsystem for reporting total CPU usage of tasks in a
+ * cgroup, along with percentage load over a time interval
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/rcupdate.h>
+
+#include <asm/div64.h>
+
+struct cpuacct {
+ struct cgroup_subsys_state css;
+ spinlock_t lock;
+ /* total time used by this class */
+ cputime64_t time;
+
+ /* time when next load calculation occurs */
+ u64 next_interval_check;
+
+ /* time used in current period */
+ cputime64_t current_interval_time;
+
+ /* time used in last period */
+ cputime64_t last_interval_time;
+};
+
+struct cgroup_subsys cpuacct_subsys;
+
+static inline struct cpuacct *cgroup_ca(struct cgroup *cont)
+{
+ return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id),
+ struct cpuacct, css);
+}
+
+static inline struct cpuacct *task_ca(struct task_struct *task)
+{
+ return container_of(task_subsys_state(task, cpuacct_subsys_id),
+ struct cpuacct, css);
+}
+
+#define INTERVAL (HZ * 10)
+
+static inline u64 next_interval_boundary(u64 now)
+{
+ /* calculate the next interval boundary beyond the
+ * current time */
+ do_div(now, INTERVAL);
+ return (now + 1) * INTERVAL;
+}
+
+static struct cgroup_subsys_state *cpuacct_create(
+ struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
+
+ if (!ca)
+ return ERR_PTR(-ENOMEM);
+ spin_lock_init(&ca->lock);
+ ca->next_interval_check = next_interval_boundary(get_jiffies_64());
+ return &ca->css;
+}
+
+static void cpuacct_destroy(struct cgroup_subsys *ss,
+ struct cgroup *cont)
+{
+ kfree(cgroup_ca(cont));
+}
+
+/* Lazily update the load calculation if necessary. Called with ca locked */
+static void cpuusage_update(struct cpuacct *ca)
+{
+ u64 now = get_jiffies_64();
+
+ /* If we're not due for an update, return */
+ if (ca->next_interval_check > now)
+ return;
+
+ if (ca->next_interval_check <= (now - INTERVAL)) {
+ /* If it's been more than an interval since the last
+ * check, then catch up - the last interval must have
+ * been zero load */
+ ca->last_interval_time = 0;
+ ca->next_interval_check = next_interval_boundary(now);
+ } else {
+ /* If a steal takes the last interval time negative,
+ * then we just ignore it */
+ if ((s64)ca->current_interval_time > 0)
+ ca->last_interval_time = ca->current_interval_time;
+ else
+ ca->last_interval_time = 0;
+ ca->next_interval_check += INTERVAL;
+ }
+ ca->current_interval_time = 0;
+}
+
+static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft)
+{
+ struct cpuacct *ca = cgroup_ca(cont);
+ u64 time;
+
+ spin_lock_irq(&ca->lock);
+ cpuusage_update(ca);
+ time = cputime64_to_jiffies64(ca->time);
+ spin_unlock_irq(&ca->lock);
+
+ /* Convert 64-bit jiffies to seconds */
+ time *= 1000;
+ do_div(time, HZ);
+ return time;
+}
+
+static u64 load_read(struct cgroup *cont, struct cftype *cft)
+{
+ struct cpuacct *ca = cgroup_ca(cont);
+ u64 time;
+
+ /* Find the time used in the previous interval */
+ spin_lock_irq(&ca->lock);
+ cpuusage_update(ca);
+ time = cputime64_to_jiffies64(ca->last_interval_time);
+ spin_unlock_irq(&ca->lock);
+
+ /* Convert time to a percentage, to give the load in the
+ * previous period */
+ time *= 100;
+ do_div(time, INTERVAL);
+
+ return time;
+}
+
+static struct cftype files[] = {
+ {
+ .name = "usage",
+ .read_uint = cpuusage_read,
+ },
+ {
+ .name = "load",
+ .read_uint = load_read,
+ }
+};
+
+static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files));
+}
+
+void cpuacct_charge(struct task_struct *task, cputime_t cputime)
+{
+
+ struct cpuacct *ca;
+ unsigned long flags;
+
+ if (!cpuacct_subsys.active)
+ return;
+ rcu_read_lock();
+ ca = task_ca(task);
+ if (ca) {
+ spin_lock_irqsave(&ca->lock, flags);
+ cpuusage_update(ca);
+ ca->time = cputime64_add(ca->time, cputime);
+ ca->current_interval_time =
+ cputime64_add(ca->current_interval_time, cputime);
+ spin_unlock_irqrestore(&ca->lock, flags);
+ }
+ rcu_read_unlock();
+}
+
+struct cgroup_subsys cpuacct_subsys = {
+ .name = "cpuacct",
+ .create = cpuacct_create,
+ .destroy = cpuacct_destroy,
+ .populate = cpuacct_populate,
+ .subsys_id = cpuacct_subsys_id,
+};
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 64950fa5d32..50f5dc46368 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -4,7 +4,8 @@
* Processor and Memory placement constraints for sets of tasks.
*
* Copyright (C) 2003 BULL SA.
- * Copyright (C) 2004-2006 Silicon Graphics, Inc.
+ * Copyright (C) 2004-2007 Silicon Graphics, Inc.
+ * Copyright (C) 2006 Google, Inc
*
* Portions derived from Patrick Mochel's sysfs code.
* sysfs is Copyright (c) 2001-3 Patrick Mochel
@@ -12,6 +13,7 @@
* 2003-10-10 Written by Simon Derr.
* 2003-10-22 Updates by Stephen Hemminger.
* 2004 May-July Rework by Paul Jackson.
+ * 2006 Rework by Paul Menage to use generic cgroups
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of the Linux
@@ -36,6 +38,7 @@
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/pagemap.h>
+#include <linux/prio_heap.h>
#include <linux/proc_fs.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
@@ -52,8 +55,7 @@
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/mutex.h>
-
-#define CPUSET_SUPER_MAGIC 0x27e0eb
+#include <linux/kfifo.h>
/*
* Tracks how many cpusets are currently defined in system.
@@ -62,6 +64,10 @@
*/
int number_of_cpusets __read_mostly;
+/* Retrieve the cpuset from a cgroup */
+struct cgroup_subsys cpuset_subsys;
+struct cpuset;
+
/* See "Frequency meter" comments, below. */
struct fmeter {
@@ -72,24 +78,13 @@ struct fmeter {
};
struct cpuset {
+ struct cgroup_subsys_state css;
+
unsigned long flags; /* "unsigned long" so bitops work */
cpumask_t cpus_allowed; /* CPUs allowed to tasks in cpuset */
nodemask_t mems_allowed; /* Memory Nodes allowed to tasks */
- /*
- * Count is atomic so can incr (fork) or decr (exit) without a lock.
- */
- atomic_t count; /* count tasks using this cpuset */
-
- /*
- * We link our 'sibling' struct into our parents 'children'.
- * Our children link their 'sibling' into our 'children'.
- */
- struct list_head sibling; /* my parents children */
- struct list_head children; /* my children */
-
struct cpuset *parent; /* my parent */
- struct dentry *dentry; /* cpuset fs entry */
/*
* Copy of global cpuset_mems_generation as of the most
@@ -98,15 +93,32 @@ struct cpuset {
int mems_generation;
struct fmeter fmeter; /* memory_pressure filter */
+
+ /* partition number for rebuild_sched_domains() */
+ int pn;
};
+/* Retrieve the cpuset for a cgroup */
+static inline struct cpuset *cgroup_cs(struct cgroup *cont)
+{
+ return container_of(cgroup_subsys_state(cont, cpuset_subsys_id),
+ struct cpuset, css);
+}
+
+/* Retrieve the cpuset for a task */
+static inline struct cpuset *task_cs(struct task_struct *task)
+{
+ return container_of(task_subsys_state(task, cpuset_subsys_id),
+ struct cpuset, css);
+}
+
+
/* bits in struct cpuset flags field */
typedef enum {
CS_CPU_EXCLUSIVE,
CS_MEM_EXCLUSIVE,
CS_MEMORY_MIGRATE,
- CS_REMOVED,
- CS_NOTIFY_ON_RELEASE,
+ CS_SCHED_LOAD_BALANCE,
CS_SPREAD_PAGE,
CS_SPREAD_SLAB,
} cpuset_flagbits_t;
@@ -122,14 +134,9 @@ static inline int is_mem_exclusive(const struct cpuset *cs)
return test_bit(CS_MEM_EXCLUSIVE, &cs->flags);
}
-static inline int is_removed(const struct cpuset *cs)
+static inline int is_sched_load_balance(const struct cpuset *cs)
{
- return test_bit(CS_REMOVED, &cs->flags);
-}
-
-static inline int notify_on_release(const struct cpuset *cs)
-{
- return test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
+ return test_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
}
static inline int is_memory_migrate(const struct cpuset *cs)
@@ -172,14 +179,8 @@ static struct cpuset top_cpuset = {
.flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)),
.cpus_allowed = CPU_MASK_ALL,
.mems_allowed = NODE_MASK_ALL,
- .count = ATOMIC_INIT(0),
- .sibling = LIST_HEAD_INIT(top_cpuset.sibling),
- .children = LIST_HEAD_INIT(top_cpuset.children),
};
-static struct vfsmount *cpuset_mount;
-static struct super_block *cpuset_sb;
-
/*
* We have two global cpuset mutexes below. They can nest.
* It is ok to first take manage_mutex, then nest callback_mutex. We also
@@ -263,297 +264,33 @@ static struct super_block *cpuset_sb;
* the routine cpuset_update_task_memory_state().
*/
-static DEFINE_MUTEX(manage_mutex);
static DEFINE_MUTEX(callback_mutex);
-/*
- * A couple of forward declarations required, due to cyclic reference loop:
- * cpuset_mkdir -> cpuset_create -> cpuset_populate_dir -> cpuset_add_file
- * -> cpuset_create_file -> cpuset_dir_inode_operations -> cpuset_mkdir.
- */
-
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry);
-
-static struct backing_dev_info cpuset_backing_dev_info = {
- .ra_pages = 0, /* No readahead */
- .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
-};
-
-static struct inode *cpuset_new_inode(mode_t mode)
-{
- struct inode *inode = new_inode(cpuset_sb);
-
- if (inode) {
- inode->i_mode = mode;
- inode->i_uid = current->fsuid;
- inode->i_gid = current->fsgid;
- inode->i_blocks = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_mapping->backing_dev_info = &cpuset_backing_dev_info;
- }
- return inode;
-}
-
-static void cpuset_diput(struct dentry *dentry, struct inode *inode)
-{
- /* is dentry a directory ? if so, kfree() associated cpuset */
- if (S_ISDIR(inode->i_mode)) {
- struct cpuset *cs = dentry->d_fsdata;
- BUG_ON(!(is_removed(cs)));
- kfree(cs);
- }
- iput(inode);
-}
-
-static struct dentry_operations cpuset_dops = {
- .d_iput = cpuset_diput,
-};
-
-static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name)
-{
- struct dentry *d = lookup_one_len(name, parent, strlen(name));
- if (!IS_ERR(d))
- d->d_op = &cpuset_dops;
- return d;
-}
-
-static void remove_dir(struct dentry *d)
-{
- struct dentry *parent = dget(d->d_parent);
-
- d_delete(d);
- simple_rmdir(parent->d_inode, d);
- dput(parent);
-}
-
-/*
- * NOTE : the dentry must have been dget()'ed
- */
-static void cpuset_d_remove_dir(struct dentry *dentry)
-{
- struct list_head *node;
-
- spin_lock(&dcache_lock);
- node = dentry->d_subdirs.next;
- while (node != &dentry->d_subdirs) {
- struct dentry *d = list_entry(node, struct dentry, d_u.d_child);
- list_del_init(node);
- if (d->d_inode) {
- d = dget_locked(d);
- spin_unlock(&dcache_lock);
- d_delete(d);
- simple_unlink(dentry->d_inode, d);
- dput(d);
- spin_lock(&dcache_lock);
- }
- node = dentry->d_subdirs.next;
- }
- list_del_init(&dentry->d_u.d_child);
- spin_unlock(&dcache_lock);
- remove_dir(dentry);
-}
-
-static struct super_operations cpuset_ops = {
- .statfs = simple_statfs,
- .drop_inode = generic_delete_inode,
-};
-
-static int cpuset_fill_super(struct super_block *sb, void *unused_data,
- int unused_silent)
-{
- struct inode *inode;
- struct dentry *root;
-
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
- sb->s_magic = CPUSET_SUPER_MAGIC;
- sb->s_op = &cpuset_ops;
- cpuset_sb = sb;
-
- inode = cpuset_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR);
- if (inode) {
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
- /* directories start off with i_nlink == 2 (for "." entry) */
- inc_nlink(inode);
- } else {
- return -ENOMEM;
- }
-
- root = d_alloc_root(inode);
- if (!root) {
- iput(inode);
- return -ENOMEM;
- }
- sb->s_root = root;
- return 0;
-}
-
+/* This is ugly, but preserves the userspace API for existing cpuset
+ * users. If someone tries to mount the "cpuset" filesystem, we
+ * silently switch it to mount "cgroup" instead */
static int cpuset_get_sb(struct file_system_type *fs_type,
int flags, const char *unused_dev_name,
void *data, struct vfsmount *mnt)
{
- return get_sb_single(fs_type, flags, data, cpuset_fill_super, mnt);
+ struct file_system_type *cgroup_fs = get_fs_type("cgroup");
+ int ret = -ENODEV;
+ if (cgroup_fs) {
+ char mountopts[] =
+ "cpuset,noprefix,"
+ "release_agent=/sbin/cpuset_release_agent";
+ ret = cgroup_fs->get_sb(cgroup_fs, flags,
+ unused_dev_name, mountopts, mnt);
+ put_filesystem(cgroup_fs);
+ }
+ return ret;
}
static struct file_system_type cpuset_fs_type = {
.name = "cpuset",
.get_sb = cpuset_get_sb,
- .kill_sb = kill_litter_super,
};
-/* struct cftype:
- *
- * The files in the cpuset filesystem mostly have a very simple read/write
- * handling, some common function will take care of it. Nevertheless some cases
- * (read tasks) are special and therefore I define this structure for every
- * kind of file.
- *
- *
- * When reading/writing to a file:
- * - the cpuset to use in file->f_path.dentry->d_parent->d_fsdata
- * - the 'cftype' of the file is file->f_path.dentry->d_fsdata
- */
-
-struct cftype {
- char *name;
- int private;
- int (*open) (struct inode *inode, struct file *file);
- ssize_t (*read) (struct file *file, char __user *buf, size_t nbytes,
- loff_t *ppos);
- int (*write) (struct file *file, const char __user *buf, size_t nbytes,
- loff_t *ppos);
- int (*release) (struct inode *inode, struct file *file);
-};
-
-static inline struct cpuset *__d_cs(struct dentry *dentry)
-{
- return dentry->d_fsdata;
-}
-
-static inline struct cftype *__d_cft(struct dentry *dentry)
-{
- return dentry->d_fsdata;
-}
-
-/*
- * Call with manage_mutex held. Writes path of cpuset into buf.
- * Returns 0 on success, -errno on error.
- */
-
-static int cpuset_path(const struct cpuset *cs, char *buf, int buflen)
-{
- char *start;
-
- start = buf + buflen;
-
- *--start = '\0';
- for (;;) {
- int len = cs->dentry->d_name.len;
- if ((start -= len) < buf)
- return -ENAMETOOLONG;
- memcpy(start, cs->dentry->d_name.name, len);
- cs = cs->parent;
- if (!cs)
- break;
- if (!cs->parent)
- continue;
- if (--start < buf)
- return -ENAMETOOLONG;
- *start = '/';
- }
- memmove(buf, start, buf + buflen - start);
- return 0;
-}
-
-/*
- * Notify userspace when a cpuset is released, by running
- * /sbin/cpuset_release_agent with the name of the cpuset (path
- * relative to the root of cpuset file system) as the argument.
- *
- * Most likely, this user command will try to rmdir this cpuset.
- *
- * This races with the possibility that some other task will be
- * attached to this cpuset before it is removed, or that some other
- * user task will 'mkdir' a child cpuset of this cpuset. That's ok.
- * The presumed 'rmdir' will fail quietly if this cpuset is no longer
- * unused, and this cpuset will be reprieved from its death sentence,
- * to continue to serve a useful existence. Next time it's released,
- * we will get notified again, if it still has 'notify_on_release' set.
- *
- * The final arg to call_usermodehelper() is 0, which means don't
- * wait. The separate /sbin/cpuset_release_agent task is forked by
- * call_usermodehelper(), then control in this thread returns here,
- * without waiting for the release agent task. We don't bother to
- * wait because the caller of this routine has no use for the exit
- * status of the /sbin/cpuset_release_agent task, so no sense holding
- * our caller up for that.
- *
- * When we had only one cpuset mutex, we had to call this
- * without holding it, to avoid deadlock when call_usermodehelper()
- * allocated memory. With two locks, we could now call this while
- * holding manage_mutex, but we still don't, so as to minimize
- * the time manage_mutex is held.
- */
-
-static void cpuset_release_agent(const char *pathbuf)
-{
- char *argv[3], *envp[3];
- int i;
-
- if (!pathbuf)
- return;
-
- i = 0;
- argv[i++] = "/sbin/cpuset_release_agent";
- argv[i++] = (char *)pathbuf;
- argv[i] = NULL;
-
- i = 0;
- /* minimal command environment */
- envp[i++] = "HOME=/";
- envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
- envp[i] = NULL;
-
- call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
- kfree(pathbuf);
-}
-
-/*
- * Either cs->count of using tasks transitioned to zero, or the
- * cs->children list of child cpusets just became empty. If this
- * cs is notify_on_release() and now both the user count is zero and
- * the list of children is empty, prepare cpuset path in a kmalloc'd
- * buffer, to be returned via ppathbuf, so that the caller can invoke
- * cpuset_release_agent() with it later on, once manage_mutex is dropped.
- * Call here with manage_mutex held.
- *
- * This check_for_release() routine is responsible for kmalloc'ing
- * pathbuf. The above cpuset_release_agent() is responsible for
- * kfree'ing pathbuf. The caller of these routines is responsible
- * for providing a pathbuf pointer, initialized to NULL, then
- * calling check_for_release() with manage_mutex held and the address
- * of the pathbuf pointer, then dropping manage_mutex, then calling
- * cpuset_release_agent() with pathbuf, as set by check_for_release().
- */
-
-static void check_for_release(struct cpuset *cs, char **ppathbuf)
-{
- if (notify_on_release(cs) && atomic_read(&cs->count) == 0 &&
- list_empty(&cs->children)) {
- char *buf;
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!buf)
- return;
- if (cpuset_path(cs, buf, PAGE_SIZE) < 0)
- kfree(buf);
- else
- *ppathbuf = buf;
- }
-}
-
/*
* Return in *pmask the portion of a cpusets's cpus_allowed that
* are online. If none are online, walk up the cpuset hierarchy
@@ -653,20 +390,19 @@ void cpuset_update_task_memory_state(void)
struct task_struct *tsk = current;
struct cpuset *cs;
- if (tsk->cpuset == &top_cpuset) {
+ if (task_cs(tsk) == &top_cpuset) {
/* Don't need rcu for top_cpuset. It's never freed. */
my_cpusets_mem_gen = top_cpuset.mems_generation;
} else {
rcu_read_lock();
- cs = rcu_dereference(tsk->cpuset);
- my_cpusets_mem_gen = cs->mems_generation;
+ my_cpusets_mem_gen = task_cs(current)->mems_generation;
rcu_read_unlock();
}
if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) {
mutex_lock(&callback_mutex);
task_lock(tsk);
- cs = tsk->cpuset; /* Maybe changed when task not locked */
+ cs = task_cs(tsk); /* Maybe changed when task not locked */
guarantee_online_mems(cs, &tsk->mems_allowed);
tsk->cpuset_mems_generation = cs->mems_generation;
if (is_spread_page(cs))
@@ -721,11 +457,12 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q)
static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
{
+ struct cgroup *cont;
struct cpuset *c, *par;
/* Each of our child cpusets must be a subset of us */
- list_for_each_entry(c, &cur->children, sibling) {
- if (!is_cpuset_subset(c, trial))
+ list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+ if (!is_cpuset_subset(cgroup_cs(cont), trial))
return -EBUSY;
}
@@ -740,7 +477,8 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
return -EACCES;
/* If either I or some sibling (!= me) is exclusive, we can't overlap */
- list_for_each_entry(c, &par->children, sibling) {
+ list_for_each_entry(cont, &par->css.cgroup->children, sibling) {
+ c = cgroup_cs(cont);
if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) &&
c != cur &&
cpus_intersects(trial->cpus_allowed, c->cpus_allowed))
@@ -751,17 +489,265 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
return -EINVAL;
}
+ /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */
+ if (cgroup_task_count(cur->css.cgroup)) {
+ if (cpus_empty(trial->cpus_allowed) ||
+ nodes_empty(trial->mems_allowed)) {
+ return -ENOSPC;
+ }
+ }
+
return 0;
}
/*
+ * Helper routine for rebuild_sched_domains().
+ * Do cpusets a, b have overlapping cpus_allowed masks?
+ */
+
+static int cpusets_overlap(struct cpuset *a, struct cpuset *b)
+{
+ return cpus_intersects(a->cpus_allowed, b->cpus_allowed);
+}
+
+/*
+ * rebuild_sched_domains()
+ *
+ * If the flag 'sched_load_balance' of any cpuset with non-empty
+ * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset
+ * which has that flag enabled, or if any cpuset with a non-empty
+ * 'cpus' is removed, then call this routine to rebuild the
+ * scheduler's dynamic sched domains.
+ *
+ * This routine builds a partial partition of the systems CPUs
+ * (the set of non-overlappping cpumask_t's in the array 'part'
+ * below), and passes that partial partition to the kernel/sched.c
+ * partition_sched_domains() routine, which will rebuild the
+ * schedulers load balancing domains (sched domains) as specified
+ * by that partial partition. A 'partial partition' is a set of
+ * non-overlapping subsets whose union is a subset of that set.
+ *
+ * See "What is sched_load_balance" in Documentation/cpusets.txt
+ * for a background explanation of this.
+ *
+ * Does not return errors, on the theory that the callers of this
+ * routine would rather not worry about failures to rebuild sched
+ * domains when operating in the severe memory shortage situations
+ * that could cause allocation failures below.
+ *
+ * Call with cgroup_mutex held. May take callback_mutex during
+ * call due to the kfifo_alloc() and kmalloc() calls. May nest
+ * a call to the lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
+ * Must not be called holding callback_mutex, because we must not
+ * call lock_cpu_hotplug() while holding callback_mutex. Elsewhere
+ * the kernel nests callback_mutex inside lock_cpu_hotplug() calls.
+ * So the reverse nesting would risk an ABBA deadlock.
+ *
+ * The three key local variables below are:
+ * q - a kfifo queue of cpuset pointers, used to implement a
+ * top-down scan of all cpusets. This scan loads a pointer
+ * to each cpuset marked is_sched_load_balance into the
+ * array 'csa'. For our purposes, rebuilding the schedulers
+ * sched domains, we can ignore !is_sched_load_balance cpusets.
+ * csa - (for CpuSet Array) Array of pointers to all the cpusets
+ * that need to be load balanced, for convenient iterative
+ * access by the subsequent code that finds the best partition,
+ * i.e the set of domains (subsets) of CPUs such that the
+ * cpus_allowed of every cpuset marked is_sched_load_balance
+ * is a subset of one of these domains, while there are as
+ * many such domains as possible, each as small as possible.
+ * doms - Conversion of 'csa' to an array of cpumasks, for passing to
+ * the kernel/sched.c routine partition_sched_domains() in a
+ * convenient format, that can be easily compared to the prior
+ * value to determine what partition elements (sched domains)
+ * were changed (added or removed.)
+ *
+ * Finding the best partition (set of domains):
+ * The triple nested loops below over i, j, k scan over the
+ * load balanced cpusets (using the array of cpuset pointers in
+ * csa[]) looking for pairs of cpusets that have overlapping
+ * cpus_allowed, but which don't have the same 'pn' partition
+ * number and gives them in the same partition number. It keeps
+ * looping on the 'restart' label until it can no longer find
+ * any such pairs.
+ *
+ * The union of the cpus_allowed masks from the set of
+ * all cpusets having the same 'pn' value then form the one
+ * element of the partition (one sched domain) to be passed to
+ * partition_sched_domains().
+ */
+
+static void rebuild_sched_domains(void)
+{
+ struct kfifo *q; /* queue of cpusets to be scanned */
+ struct cpuset *cp; /* scans q */
+ struct cpuset **csa; /* array of all cpuset ptrs */
+ int csn; /* how many cpuset ptrs in csa so far */
+ int i, j, k; /* indices for partition finding loops */
+ cpumask_t *doms; /* resulting partition; i.e. sched domains */
+ int ndoms; /* number of sched domains in result */
+ int nslot; /* next empty doms[] cpumask_t slot */
+
+ q = NULL;
+ csa = NULL;
+ doms = NULL;
+
+ /* Special case for the 99% of systems with one, full, sched domain */
+ if (is_sched_load_balance(&top_cpuset)) {
+ ndoms = 1;
+ doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+ if (!doms)
+ goto rebuild;
+ *doms = top_cpuset.cpus_allowed;
+ goto rebuild;
+ }
+
+ q = kfifo_alloc(number_of_cpusets * sizeof(cp), GFP_KERNEL, NULL);
+ if (IS_ERR(q))
+ goto done;
+ csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL);
+ if (!csa)
+ goto done;
+ csn = 0;
+
+ cp = &top_cpuset;
+ __kfifo_put(q, (void *)&cp, sizeof(cp));
+ while (__kfifo_get(q, (void *)&cp, sizeof(cp))) {
+ struct cgroup *cont;
+ struct cpuset *child; /* scans child cpusets of cp */
+ if (is_sched_load_balance(cp))
+ csa[csn++] = cp;
+ list_for_each_entry(cont, &cp->css.cgroup->children, sibling) {
+ child = cgroup_cs(cont);
+ __kfifo_put(q, (void *)&child, sizeof(cp));
+ }
+ }
+
+ for (i = 0; i < csn; i++)
+ csa[i]->pn = i;
+ ndoms = csn;
+
+restart:
+ /* Find the best partition (set of sched domains) */
+ for (i = 0; i < csn; i++) {
+ struct cpuset *a = csa[i];
+ int apn = a->pn;
+
+ for (j = 0; j < csn; j++) {
+ struct cpuset *b = csa[j];
+ int bpn = b->pn;
+
+ if (apn != bpn && cpusets_overlap(a, b)) {
+ for (k = 0; k < csn; k++) {
+ struct cpuset *c = csa[k];
+
+ if (c->pn == bpn)
+ c->pn = apn;
+ }
+ ndoms--; /* one less element */
+ goto restart;
+ }
+ }
+ }
+
+ /* Convert <csn, csa> to <ndoms, doms> */
+ doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL);
+ if (!doms)
+ goto rebuild;
+
+ for (nslot = 0, i = 0; i < csn; i++) {
+ struct cpuset *a = csa[i];
+ int apn = a->pn;
+
+ if (apn >= 0) {
+ cpumask_t *dp = doms + nslot;
+
+ if (nslot == ndoms) {
+ static int warnings = 10;
+ if (warnings) {
+ printk(KERN_WARNING
+ "rebuild_sched_domains confused:"
+ " nslot %d, ndoms %d, csn %d, i %d,"
+ " apn %d\n",
+ nslot, ndoms, csn, i, apn);
+ warnings--;
+ }
+ continue;
+ }
+
+ cpus_clear(*dp);
+ for (j = i; j < csn; j++) {
+ struct cpuset *b = csa[j];
+
+ if (apn == b->pn) {
+ cpus_or(*dp, *dp, b->cpus_allowed);
+ b->pn = -1;
+ }
+ }
+ nslot++;
+ }
+ }
+ BUG_ON(nslot != ndoms);
+
+rebuild:
+ /* Have scheduler rebuild sched domains */
+ lock_cpu_hotplug();
+ partition_sched_domains(ndoms, doms);
+ unlock_cpu_hotplug();
+
+done:
+ if (q && !IS_ERR(q))
+ kfifo_free(q);
+ kfree(csa);
+ /* Don't kfree(doms) -- partition_sched_domains() does that. */
+}
+
+static inline int started_after_time(struct task_struct *t1,
+ struct timespec *time,
+ struct task_struct *t2)
+{
+ int start_diff = timespec_compare(&t1->start_time, time);
+ if (start_diff > 0) {
+ return 1;
+ } else if (start_diff < 0) {
+ return 0;
+ } else {
+ /*
+ * Arbitrarily, if two processes started at the same
+ * time, we'll say that the lower pointer value
+ * started first. Note that t2 may have exited by now
+ * so this may not be a valid pointer any longer, but
+ * that's fine - it still serves to distinguish
+ * between two tasks started (effectively)
+ * simultaneously.
+ */
+ return t1 > t2;
+ }
+}
+
+static inline int started_after(void *p1, void *p2)
+{
+ struct task_struct *t1 = p1;
+ struct task_struct *t2 = p2;
+ return started_after_time(t1, &t2->start_time, t2);
+}
+
+/*
* Call with manage_mutex held. May take callback_mutex during call.
*/
static int update_cpumask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
- int retval;
+ int retval, i;
+ int is_load_balanced;
+ struct cgroup_iter it;
+ struct cgroup *cgrp = cs->css.cgroup;
+ struct task_struct *p, *dropped;
+ /* Never dereference latest_task, since it's not refcounted */
+ struct task_struct *latest_task = NULL;
+ struct ptr_heap heap;
+ struct timespec latest_time = { 0, 0 };
/* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
if (cs == &top_cpuset)
@@ -770,11 +756,13 @@ static int update_cpumask(struct cpuset *cs, char *buf)
trialcs = *cs;
/*
- * We allow a cpuset's cpus_allowed to be empty; if it has attached
- * tasks, we'll catch it later when we validate the change and return
- * -ENOSPC.
+ * An empty cpus_allowed is ok iff there are no tasks in the cpuset.
+ * Since cpulist_parse() fails on an empty mask, we special case
+ * that parsing. The validate_change() call ensures that cpusets
+ * with tasks have cpus.
*/
- if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ buf = strstrip(buf);
+ if (!*buf) {
cpus_clear(trialcs.cpus_allowed);
} else {
retval = cpulist_parse(buf, trialcs.cpus_allowed);
@@ -782,15 +770,79 @@ static int update_cpumask(struct cpuset *cs, char *buf)
return retval;
}
cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map);
- /* cpus_allowed cannot be empty for a cpuset with attached tasks. */
- if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed))
- return -ENOSPC;
retval = validate_change(cs, &trialcs);
if (retval < 0)
return retval;
+
+ /* Nothing to do if the cpus didn't change */
+ if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
+ return 0;
+ retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after);
+ if (retval)
+ return retval;
+
+ is_load_balanced = is_sched_load_balance(&trialcs);
+
mutex_lock(&callback_mutex);
cs->cpus_allowed = trialcs.cpus_allowed;
mutex_unlock(&callback_mutex);
+
+ again:
+ /*
+ * Scan tasks in the cpuset, and update the cpumasks of any
+ * that need an update. Since we can't call set_cpus_allowed()
+ * while holding tasklist_lock, gather tasks to be processed
+ * in a heap structure. If the statically-sized heap fills up,
+ * overflow tasks that started later, and in future iterations
+ * only consider tasks that started after the latest task in
+ * the previous pass. This guarantees forward progress and
+ * that we don't miss any tasks
+ */
+ heap.size = 0;
+ cgroup_iter_start(cgrp, &it);
+ while ((p = cgroup_iter_next(cgrp, &it))) {
+ /* Only affect tasks that don't have the right cpus_allowed */
+ if (cpus_equal(p->cpus_allowed, cs->cpus_allowed))
+ continue;
+ /*
+ * Only process tasks that started after the last task
+ * we processed
+ */
+ if (!started_after_time(p, &latest_time, latest_task))
+ continue;
+ dropped = heap_insert(&heap, p);
+ if (dropped == NULL) {
+ get_task_struct(p);
+ } else if (dropped != p) {
+ get_task_struct(p);
+ put_task_struct(dropped);
+ }
+ }
+ cgroup_iter_end(cgrp, &it);
+ if (heap.size) {
+ for (i = 0; i < heap.size; i++) {
+ struct task_struct *p = heap.ptrs[i];
+ if (i == 0) {
+ latest_time = p->start_time;
+ latest_task = p;
+ }
+ set_cpus_allowed(p, cs->cpus_allowed);
+ put_task_struct(p);
+ }
+ /*
+ * If we had to process any tasks at all, scan again
+ * in case some of them were in the middle of forking
+ * children that didn't notice the new cpumask
+ * restriction. Not the most efficient way to do it,
+ * but it avoids having to take callback_mutex in the
+ * fork path
+ */
+ goto again;
+ }
+ heap_free(&heap);
+ if (is_load_balanced)
+ rebuild_sched_domains();
+
return 0;
}
@@ -839,7 +891,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL);
mutex_lock(&callback_mutex);
- guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed);
+ guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed);
mutex_unlock(&callback_mutex);
}
@@ -857,16 +909,19 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
* their mempolicies to the cpusets new mems_allowed.
*/
+static void *cpuset_being_rebound;
+
static int update_nodemask(struct cpuset *cs, char *buf)
{
struct cpuset trialcs;
nodemask_t oldmem;
- struct task_struct *g, *p;
+ struct task_struct *p;
struct mm_struct **mmarray;
int i, n, ntasks;
int migrate;
int fudge;
int retval;
+ struct cgroup_iter it;
/*
* top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
@@ -878,29 +933,19 @@ static int update_nodemask(struct cpuset *cs, char *buf)
trialcs = *cs;
/*
- * We allow a cpuset's mems_allowed to be empty; if it has attached
- * tasks, we'll catch it later when we validate the change and return
- * -ENOSPC.
+ * An empty mems_allowed is ok iff there are no tasks in the cpuset.
+ * Since nodelist_parse() fails on an empty mask, we special case
+ * that parsing. The validate_change() call ensures that cpusets
+ * with tasks have memory.
*/
- if (!buf[0] || (buf[0] == '\n' && !buf[1])) {
+ buf = strstrip(buf);
+ if (!*buf) {
nodes_clear(trialcs.mems_allowed);
} else {
retval = nodelist_parse(buf, trialcs.mems_allowed);
if (retval < 0)
goto done;
- if (!nodes_intersects(trialcs.mems_allowed,
- node_states[N_HIGH_MEMORY])) {
- /*
- * error if only memoryless nodes specified.
- */
- retval = -ENOSPC;
- goto done;
- }
}
- /*
- * Exclude memoryless nodes. We know that trialcs.mems_allowed
- * contains at least one node with memory.
- */
nodes_and(trialcs.mems_allowed, trialcs.mems_allowed,
node_states[N_HIGH_MEMORY]);
oldmem = cs->mems_allowed;
@@ -908,11 +953,6 @@ static int update_nodemask(struct cpuset *cs, char *buf)
retval = 0; /* Too easy - nothing to do */
goto done;
}
- /* mems_allowed cannot be empty for a cpuset with attached tasks. */
- if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) {
- retval = -ENOSPC;
- goto done;
- }
retval = validate_change(cs, &trialcs);
if (retval < 0)
goto done;
@@ -922,7 +962,7 @@ static int update_nodemask(struct cpuset *cs, char *buf)
cs->mems_generation = cpuset_mems_generation++;
mutex_unlock(&callback_mutex);
- set_cpuset_being_rebound(cs); /* causes mpol_copy() rebind */
+ cpuset_being_rebound = cs; /* causes mpol_copy() rebind */
fudge = 10; /* spare mmarray[] slots */
fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */
@@ -936,13 +976,13 @@ static int update_nodemask(struct cpuset *cs, char *buf)
* enough mmarray[] w/o using GFP_ATOMIC.
*/
while (1) {
- ntasks = atomic_read(&cs->count); /* guess */
+ ntasks = cgroup_task_count(cs->css.cgroup); /* guess */
ntasks += fudge;
mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL);
if (!mmarray)
goto done;
read_lock(&tasklist_lock); /* block fork */
- if (atomic_read(&cs->count) <= ntasks)
+ if (cgroup_task_count(cs->css.cgroup) <= ntasks)
break; /* got enough */
read_unlock(&tasklist_lock); /* try again */
kfree(mmarray);
@@ -951,21 +991,21 @@ static int update_nodemask(struct cpuset *cs, char *buf)
n = 0;
/* Load up mmarray[] with mm reference for each task in cpuset. */
- do_each_thread(g, p) {
+ cgroup_iter_start(cs->css.cgroup, &it);
+ while ((p = cgroup_iter_next(cs->css.cgroup, &it))) {
struct mm_struct *mm;
if (n >= ntasks) {
printk(KERN_WARNING
"Cpuset mempolicy rebind incomplete.\n");
- continue;
+ break;
}
- if (p->cpuset != cs)
- continue;
mm = get_task_mm(p);
if (!mm)
continue;
mmarray[n++] = mm;
- } while_each_thread(g, p);
+ }
+ cgroup_iter_end(cs->css.cgroup, &it);
read_unlock(&tasklist_lock);
/*
@@ -993,12 +1033,17 @@ static int update_nodemask(struct cpuset *cs, char *buf)
/* We're done rebinding vma's to this cpusets new mems_allowed. */
kfree(mmarray);
- set_cpuset_being_rebound(NULL);
+ cpuset_being_rebound = NULL;
retval = 0;
done:
return retval;
}
+int current_cpuset_is_being_rebound(void)
+{
+ return task_cs(current) == cpuset_being_rebound;
+}
+
/*
* Call with manage_mutex held.
*/
@@ -1015,6 +1060,7 @@ static int update_memory_pressure_enabled(struct cpuset *cs, char *buf)
/*
* update_flag - read a 0 or a 1 in a file and update associated flag
* bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE,
+ * CS_SCHED_LOAD_BALANCE,
* CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE,
* CS_SPREAD_PAGE, CS_SPREAD_SLAB)
* cs: the cpuset to update
@@ -1028,6 +1074,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
int turning_on;
struct cpuset trialcs;
int err;
+ int cpus_nonempty, balance_flag_changed;
turning_on = (simple_strtoul(buf, NULL, 10) != 0);
@@ -1040,10 +1087,18 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
err = validate_change(cs, &trialcs);
if (err < 0)
return err;
+
+ cpus_nonempty = !cpus_empty(trialcs.cpus_allowed);
+ balance_flag_changed = (is_sched_load_balance(cs) !=
+ is_sched_load_balance(&trialcs));
+
mutex_lock(&callback_mutex);
cs->flags = trialcs.flags;
mutex_unlock(&callback_mutex);
+ if (cpus_nonempty && balance_flag_changed)
+ rebuild_sched_domains();
+
return 0;
}
@@ -1145,85 +1200,34 @@ static int fmeter_getrate(struct fmeter *fmp)
return val;
}
-/*
- * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly
- * writing the path of the old cpuset in 'ppathbuf' if it needs to be
- * notified on release.
- *
- * Call holding manage_mutex. May take callback_mutex and task_lock of
- * the task 'pid' during call.
- */
-
-static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
+static int cpuset_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *cont, struct task_struct *tsk)
{
- pid_t pid;
- struct task_struct *tsk;
- struct cpuset *oldcs;
- cpumask_t cpus;
- nodemask_t from, to;
- struct mm_struct *mm;
- int retval;
+ struct cpuset *cs = cgroup_cs(cont);
- if (sscanf(pidbuf, "%d", &pid) != 1)
- return -EIO;
if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
return -ENOSPC;
- if (pid) {
- read_lock(&tasklist_lock);
-
- tsk = find_task_by_pid(pid);
- if (!tsk || tsk->flags & PF_EXITING) {
- read_unlock(&tasklist_lock);
- return -ESRCH;
- }
-
- get_task_struct(tsk);
- read_unlock(&tasklist_lock);
-
- if ((current->euid) && (current->euid != tsk->uid)
- && (current->euid != tsk->suid)) {
- put_task_struct(tsk);
- return -EACCES;
- }
- } else {
- tsk = current;
- get_task_struct(tsk);
- }
+ return security_task_setscheduler(tsk, 0, NULL);
+}
- retval = security_task_setscheduler(tsk, 0, NULL);
- if (retval) {
- put_task_struct(tsk);
- return retval;
- }
+static void cpuset_attach(struct cgroup_subsys *ss,
+ struct cgroup *cont, struct cgroup *oldcont,
+ struct task_struct *tsk)
+{
+ cpumask_t cpus;
+ nodemask_t from, to;
+ struct mm_struct *mm;
+ struct cpuset *cs = cgroup_cs(cont);
+ struct cpuset *oldcs = cgroup_cs(oldcont);
mutex_lock(&callback_mutex);
-
- task_lock(tsk);
- oldcs = tsk->cpuset;
- /*
- * After getting 'oldcs' cpuset ptr, be sure still not exiting.
- * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack
- * then fail this attach_task(), to avoid breaking top_cpuset.count.
- */
- if (tsk->flags & PF_EXITING) {
- task_unlock(tsk);
- mutex_unlock(&callback_mutex);
- put_task_struct(tsk);
- return -ESRCH;
- }
- atomic_inc(&cs->count);
- rcu_assign_pointer(tsk->cpuset, cs);
- task_unlock(tsk);
-
guarantee_online_cpus(cs, &cpus);
set_cpus_allowed(tsk, cpus);
+ mutex_unlock(&callback_mutex);
from = oldcs->mems_allowed;
to = cs->mems_allowed;
-
- mutex_unlock(&callback_mutex);
-
mm = get_task_mm(tsk);
if (mm) {
mpol_rebind_mm(mm, &to);
@@ -1232,44 +1236,36 @@ static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf)
mmput(mm);
}
- put_task_struct(tsk);
- synchronize_rcu();
- if (atomic_dec_and_test(&oldcs->count))
- check_for_release(oldcs, ppathbuf);
- return 0;
}
/* The various types of files and directories in a cpuset file system */
typedef enum {
- FILE_ROOT,
- FILE_DIR,
FILE_MEMORY_MIGRATE,
FILE_CPULIST,
FILE_MEMLIST,
FILE_CPU_EXCLUSIVE,
FILE_MEM_EXCLUSIVE,
- FILE_NOTIFY_ON_RELEASE,
+ FILE_SCHED_LOAD_BALANCE,
FILE_MEMORY_PRESSURE_ENABLED,
FILE_MEMORY_PRESSURE,
FILE_SPREAD_PAGE,
FILE_SPREAD_SLAB,
- FILE_TASKLIST,
} cpuset_filetype_t;
-static ssize_t cpuset_common_file_write(struct file *file,
+static ssize_t cpuset_common_file_write(struct cgroup *cont,
+ struct cftype *cft,
+ struct file *file,
const char __user *userbuf,
size_t nbytes, loff_t *unused_ppos)
{
- struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
- struct cftype *cft = __d_cft(file->f_path.dentry);
+ struct cpuset *cs = cgroup_cs(cont);
cpuset_filetype_t type = cft->private;
char *buffer;
- char *pathbuf = NULL;
int retval = 0;
/* Crude upper limit on largest legitimate cpulist user might write. */
- if (nbytes > 100 + 6 * max(NR_CPUS, MAX_NUMNODES))
+ if (nbytes > 100U + 6 * max(NR_CPUS, MAX_NUMNODES))
return -E2BIG;
/* +1 for nul-terminator */
@@ -1282,9 +1278,9 @@ static ssize_t cpuset_common_file_write(struct file *file,
}
buffer[nbytes] = 0; /* nul-terminate */
- mutex_lock(&manage_mutex);
+ cgroup_lock();
- if (is_removed(cs)) {
+ if (cgroup_is_removed(cont)) {
retval = -ENODEV;
goto out2;
}
@@ -1302,8 +1298,8 @@ static ssize_t cpuset_common_file_write(struct file *file,
case FILE_MEM_EXCLUSIVE:
retval = update_flag(CS_MEM_EXCLUSIVE, cs, buffer);
break;
- case FILE_NOTIFY_ON_RELEASE:
- retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer);
+ case FILE_SCHED_LOAD_BALANCE:
+ retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer);
break;
case FILE_MEMORY_MIGRATE:
retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer);
@@ -1322,9 +1318,6 @@ static ssize_t cpuset_common_file_write(struct file *file,
retval = update_flag(CS_SPREAD_SLAB, cs, buffer);
cs->mems_generation = cpuset_mems_generation++;
break;
- case FILE_TASKLIST:
- retval = attach_task(cs, buffer, &pathbuf);
- break;
default:
retval = -EINVAL;
goto out2;
@@ -1333,30 +1326,12 @@ static ssize_t cpuset_common_file_write(struct file *file,
if (retval == 0)
retval = nbytes;
out2:
- mutex_unlock(&manage_mutex);
- cpuset_release_agent(pathbuf);
+ cgroup_unlock();
out1:
kfree(buffer);
return retval;
}
-static ssize_t cpuset_file_write(struct file *file, const char __user *buf,
- size_t nbytes, loff_t *ppos)
-{
- ssize_t retval = 0;
- struct cftype *cft = __d_cft(file->f_path.dentry);
- if (!cft)
- return -ENODEV;
-
- /* special function ? */
- if (cft->write)
- retval = cft->write(file, buf, nbytes, ppos);
- else
- retval = cpuset_common_file_write(file, buf, nbytes, ppos);
-
- return retval;
-}
-
/*
* These ascii lists should be read in a single call, by using a user
* buffer large enough to hold the entire map. If read in smaller
@@ -1391,11 +1366,13 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs)
return nodelist_scnprintf(page, PAGE_SIZE, mask);
}
-static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
- size_t nbytes, loff_t *ppos)
+static ssize_t cpuset_common_file_read(struct cgroup *cont,
+ struct cftype *cft,
+ struct file *file,
+ char __user *buf,
+ size_t nbytes, loff_t *ppos)
{
- struct cftype *cft = __d_cft(file->f_path.dentry);
- struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
+ struct cpuset *cs = cgroup_cs(cont);
cpuset_filetype_t type = cft->private;
char *page;
ssize_t retval = 0;
@@ -1419,8 +1396,8 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
case FILE_MEM_EXCLUSIVE:
*s++ = is_mem_exclusive(cs) ? '1' : '0';
break;
- case FILE_NOTIFY_ON_RELEASE:
- *s++ = notify_on_release(cs) ? '1' : '0';
+ case FILE_SCHED_LOAD_BALANCE:
+ *s++ = is_sched_load_balance(cs) ? '1' : '0';
break;
case FILE_MEMORY_MIGRATE:
*s++ = is_memory_migrate(cs) ? '1' : '0';
@@ -1449,390 +1426,150 @@ out:
return retval;
}
-static ssize_t cpuset_file_read(struct file *file, char __user *buf, size_t nbytes,
- loff_t *ppos)
-{
- ssize_t retval = 0;
- struct cftype *cft = __d_cft(file->f_path.dentry);
- if (!cft)
- return -ENODEV;
-
- /* special function ? */
- if (cft->read)
- retval = cft->read(file, buf, nbytes, ppos);
- else
- retval = cpuset_common_file_read(file, buf, nbytes, ppos);
-
- return retval;
-}
-
-static int cpuset_file_open(struct inode *inode, struct file *file)
-{
- int err;
- struct cftype *cft;
-
- err = generic_file_open(inode, file);
- if (err)
- return err;
-
- cft = __d_cft(file->f_path.dentry);
- if (!cft)
- return -ENODEV;
- if (cft->open)
- err = cft->open(inode, file);
- else
- err = 0;
-
- return err;
-}
-
-static int cpuset_file_release(struct inode *inode, struct file *file)
-{
- struct cftype *cft = __d_cft(file->f_path.dentry);
- if (cft->release)
- return cft->release(inode, file);
- return 0;
-}
-
-/*
- * cpuset_rename - Only allow simple rename of directories in place.
- */
-static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry,
- struct inode *new_dir, struct dentry *new_dentry)
-{
- if (!S_ISDIR(old_dentry->d_inode->i_mode))
- return -ENOTDIR;
- if (new_dentry->d_inode)
- return -EEXIST;
- if (old_dir != new_dir)
- return -EIO;
- return simple_rename(old_dir, old_dentry, new_dir, new_dentry);
-}
-
-static const struct file_operations cpuset_file_operations = {
- .read = cpuset_file_read,
- .write = cpuset_file_write,
- .llseek = generic_file_llseek,
- .open = cpuset_file_open,
- .release = cpuset_file_release,
-};
-
-static const struct inode_operations cpuset_dir_inode_operations = {
- .lookup = simple_lookup,
- .mkdir = cpuset_mkdir,
- .rmdir = cpuset_rmdir,
- .rename = cpuset_rename,
-};
-
-static int cpuset_create_file(struct dentry *dentry, int mode)
-{
- struct inode *inode;
-
- if (!dentry)
- return -ENOENT;
- if (dentry->d_inode)
- return -EEXIST;
-
- inode = cpuset_new_inode(mode);
- if (!inode)
- return -ENOMEM;
-
- if (S_ISDIR(mode)) {
- inode->i_op = &cpuset_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
-
- /* start off with i_nlink == 2 (for "." entry) */
- inc_nlink(inode);
- } else if (S_ISREG(mode)) {
- inode->i_size = 0;
- inode->i_fop = &cpuset_file_operations;
- }
-
- d_instantiate(dentry, inode);
- dget(dentry); /* Extra count - pin the dentry in core */
- return 0;
-}
-
-/*
- * cpuset_create_dir - create a directory for an object.
- * cs: the cpuset we create the directory for.
- * It must have a valid ->parent field
- * And we are going to fill its ->dentry field.
- * name: The name to give to the cpuset directory. Will be copied.
- * mode: mode to set on new directory.
- */
-
-static int cpuset_create_dir(struct cpuset *cs, const char *name, int mode)
-{
- struct dentry *dentry = NULL;
- struct dentry *parent;
- int error = 0;
-
- parent = cs->parent->dentry;
- dentry = cpuset_get_dentry(parent, name);
- if (IS_ERR(dentry))
- return PTR_ERR(dentry);
- error = cpuset_create_file(dentry, S_IFDIR | mode);
- if (!error) {
- dentry->d_fsdata = cs;
- inc_nlink(parent->d_inode);
- cs->dentry = dentry;
- }
- dput(dentry);
-
- return error;
-}
-
-static int cpuset_add_file(struct dentry *dir, const struct cftype *cft)
-{
- struct dentry *dentry;
- int error;
-
- mutex_lock(&dir->d_inode->i_mutex);
- dentry = cpuset_get_dentry(dir, cft->name);
- if (!IS_ERR(dentry)) {
- error = cpuset_create_file(dentry, 0644 | S_IFREG);
- if (!error)
- dentry->d_fsdata = (void *)cft;
- dput(dentry);
- } else
- error = PTR_ERR(dentry);
- mutex_unlock(&dir->d_inode->i_mutex);
- return error;
-}
-
-/*
- * Stuff for reading the 'tasks' file.
- *
- * Reading this file can return large amounts of data if a cpuset has
- * *lots* of attached tasks. So it may need several calls to read(),
- * but we cannot guarantee that the information we produce is correct
- * unless we produce it entirely atomically.
- *
- * Upon tasks file open(), a struct ctr_struct is allocated, that
- * will have a pointer to an array (also allocated here). The struct
- * ctr_struct * is stored in file->private_data. Its resources will
- * be freed by release() when the file is closed. The array is used
- * to sprintf the PIDs and then used by read().
- */
-
-/* cpusets_tasks_read array */
-
-struct ctr_struct {
- char *buf;
- int bufsz;
-};
-
-/*
- * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'.
- * Return actual number of pids loaded. No need to task_lock(p)
- * when reading out p->cpuset, as we don't really care if it changes
- * on the next cycle, and we are not going to try to dereference it.
- */
-static int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs)
-{
- int n = 0;
- struct task_struct *g, *p;
-
- read_lock(&tasklist_lock);
-
- do_each_thread(g, p) {
- if (p->cpuset == cs) {
- if (unlikely(n == npids))
- goto array_full;
- pidarray[n++] = p->pid;
- }
- } while_each_thread(g, p);
-
-array_full:
- read_unlock(&tasklist_lock);
- return n;
-}
-
-static int cmppid(const void *a, const void *b)
-{
- return *(pid_t *)a - *(pid_t *)b;
-}
-
-/*
- * Convert array 'a' of 'npids' pid_t's to a string of newline separated
- * decimal pids in 'buf'. Don't write more than 'sz' chars, but return
- * count 'cnt' of how many chars would be written if buf were large enough.
- */
-static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
-{
- int cnt = 0;
- int i;
-
- for (i = 0; i < npids; i++)
- cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
- return cnt;
-}
-
-/*
- * Handle an open on 'tasks' file. Prepare a buffer listing the
- * process id's of tasks currently attached to the cpuset being opened.
- *
- * Does not require any specific cpuset mutexes, and does not take any.
- */
-static int cpuset_tasks_open(struct inode *unused, struct file *file)
-{
- struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent);
- struct ctr_struct *ctr;
- pid_t *pidarray;
- int npids;
- char c;
-
- if (!(file->f_mode & FMODE_READ))
- return 0;
-
- ctr = kmalloc(sizeof(*ctr), GFP_KERNEL);
- if (!ctr)
- goto err0;
-
- /*
- * If cpuset gets more users after we read count, we won't have
- * enough space - tough. This race is indistinguishable to the
- * caller from the case that the additional cpuset users didn't
- * show up until sometime later on.
- */
- npids = atomic_read(&cs->count);
- pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
- if (!pidarray)
- goto err1;
-
- npids = pid_array_load(pidarray, npids, cs);
- sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
-
- /* Call pid_array_to_buf() twice, first just to get bufsz */
- ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1;
- ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL);
- if (!ctr->buf)
- goto err2;
- ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids);
-
- kfree(pidarray);
- file->private_data = ctr;
- return 0;
-
-err2:
- kfree(pidarray);
-err1:
- kfree(ctr);
-err0:
- return -ENOMEM;
-}
-
-static ssize_t cpuset_tasks_read(struct file *file, char __user *buf,
- size_t nbytes, loff_t *ppos)
-{
- struct ctr_struct *ctr = file->private_data;
- return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
-}
-static int cpuset_tasks_release(struct inode *unused_inode, struct file *file)
-{
- struct ctr_struct *ctr;
- if (file->f_mode & FMODE_READ) {
- ctr = file->private_data;
- kfree(ctr->buf);
- kfree(ctr);
- }
- return 0;
-}
/*
* for the common functions, 'private' gives the type of file
*/
-static struct cftype cft_tasks = {
- .name = "tasks",
- .open = cpuset_tasks_open,
- .read = cpuset_tasks_read,
- .release = cpuset_tasks_release,
- .private = FILE_TASKLIST,
-};
-
static struct cftype cft_cpus = {
.name = "cpus",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_CPULIST,
};
static struct cftype cft_mems = {
.name = "mems",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_MEMLIST,
};
static struct cftype cft_cpu_exclusive = {
.name = "cpu_exclusive",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_CPU_EXCLUSIVE,
};
static struct cftype cft_mem_exclusive = {
.name = "mem_exclusive",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_MEM_EXCLUSIVE,
};
-static struct cftype cft_notify_on_release = {
- .name = "notify_on_release",
- .private = FILE_NOTIFY_ON_RELEASE,
+static struct cftype cft_sched_load_balance = {
+ .name = "sched_load_balance",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
+ .private = FILE_SCHED_LOAD_BALANCE,
};
static struct cftype cft_memory_migrate = {
.name = "memory_migrate",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_MEMORY_MIGRATE,
};
static struct cftype cft_memory_pressure_enabled = {
.name = "memory_pressure_enabled",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_MEMORY_PRESSURE_ENABLED,
};
static struct cftype cft_memory_pressure = {
.name = "memory_pressure",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_MEMORY_PRESSURE,
};
static struct cftype cft_spread_page = {
.name = "memory_spread_page",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_SPREAD_PAGE,
};
static struct cftype cft_spread_slab = {
.name = "memory_spread_slab",
+ .read = cpuset_common_file_read,
+ .write = cpuset_common_file_write,
.private = FILE_SPREAD_SLAB,
};
-static int cpuset_populate_dir(struct dentry *cs_dentry)
+static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont)
{
int err;
- if ((err = cpuset_add_file(cs_dentry, &cft_cpus)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_cpus)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_mems)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_mems)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_cpu_exclusive)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_cpu_exclusive)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_mem_exclusive)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_mem_exclusive)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_memory_migrate)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_sched_load_balance)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_memory_pressure)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_spread_page)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_spread_page)) < 0)
return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_spread_slab)) < 0)
- return err;
- if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0)
+ if ((err = cgroup_add_file(cont, ss, &cft_spread_slab)) < 0)
return err;
+ /* memory_pressure_enabled is in root cpuset only */
+ if (err == 0 && !cont->parent)
+ err = cgroup_add_file(cont, ss,
+ &cft_memory_pressure_enabled);
return 0;
}
/*
+ * post_clone() is called at the end of cgroup_clone().
+ * 'cgroup' was just created automatically as a result of
+ * a cgroup_clone(), and the current task is about to
+ * be moved into 'cgroup'.
+ *
+ * Currently we refuse to set up the cgroup - thereby
+ * refusing the task to be entered, and as a result refusing
+ * the sys_unshare() or clone() which initiated it - if any
+ * sibling cpusets have exclusive cpus or mem.
+ *
+ * If this becomes a problem for some users who wish to
+ * allow that scenario, then cpuset_post_clone() could be
+ * changed to grant parent->cpus_allowed-sibling_cpus_exclusive
+ * (and likewise for mems) to the new cgroup.
+ */
+static void cpuset_post_clone(struct cgroup_subsys *ss,
+ struct cgroup *cgroup)
+{
+ struct cgroup *parent, *child;
+ struct cpuset *cs, *parent_cs;
+
+ parent = cgroup->parent;
+ list_for_each_entry(child, &parent->children, sibling) {
+ cs = cgroup_cs(child);
+ if (is_mem_exclusive(cs) || is_cpu_exclusive(cs))
+ return;
+ }
+ cs = cgroup_cs(cgroup);
+ parent_cs = cgroup_cs(parent);
+
+ cs->mems_allowed = parent_cs->mems_allowed;
+ cs->cpus_allowed = parent_cs->cpus_allowed;
+ return;
+}
+
+/*
* cpuset_create - create a cpuset
* parent: cpuset that will be parent of the new cpuset.
* name: name of the new cpuset. Will be strcpy'ed.
@@ -1841,106 +1578,77 @@ static int cpuset_populate_dir(struct dentry *cs_dentry)
* Must be called with the mutex on the parent inode held
*/
-static long cpuset_create(struct cpuset *parent, const char *name, int mode)
+static struct cgroup_subsys_state *cpuset_create(
+ struct cgroup_subsys *ss,
+ struct cgroup *cont)
{
struct cpuset *cs;
- int err;
+ struct cpuset *parent;
+ if (!cont->parent) {
+ /* This is early initialization for the top cgroup */
+ top_cpuset.mems_generation = cpuset_mems_generation++;
+ return &top_cpuset.css;
+ }
+ parent = cgroup_cs(cont->parent);
cs = kmalloc(sizeof(*cs), GFP_KERNEL);
if (!cs)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
- mutex_lock(&manage_mutex);
cpuset_update_task_memory_state();
cs->flags = 0;
- if (notify_on_release(parent))
- set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags);
if (is_spread_page(parent))
set_bit(CS_SPREAD_PAGE, &cs->flags);
if (is_spread_slab(parent))
set_bit(CS_SPREAD_SLAB, &cs->flags);
+ set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags);
cs->cpus_allowed = CPU_MASK_NONE;
cs->mems_allowed = NODE_MASK_NONE;
- atomic_set(&cs->count, 0);
- INIT_LIST_HEAD(&cs->sibling);
- INIT_LIST_HEAD(&cs->children);
cs->mems_generation = cpuset_mems_generation++;
fmeter_init(&cs->fmeter);
cs->parent = parent;
-
- mutex_lock(&callback_mutex);
- list_add(&cs->sibling, &cs->parent->children);
number_of_cpusets++;
- mutex_unlock(&callback_mutex);
-
- err = cpuset_create_dir(cs, name, mode);
- if (err < 0)
- goto err;
-
- /*
- * Release manage_mutex before cpuset_populate_dir() because it
- * will down() this new directory's i_mutex and if we race with
- * another mkdir, we might deadlock.
- */
- mutex_unlock(&manage_mutex);
-
- err = cpuset_populate_dir(cs->dentry);
- /* If err < 0, we have a half-filled directory - oh well ;) */
- return 0;
-err:
- list_del(&cs->sibling);
- mutex_unlock(&manage_mutex);
- kfree(cs);
- return err;
+ return &cs->css ;
}
-static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-{
- struct cpuset *c_parent = dentry->d_parent->d_fsdata;
-
- /* the vfs holds inode->i_mutex already */
- return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
-}
+/*
+ * Locking note on the strange update_flag() call below:
+ *
+ * If the cpuset being removed has its flag 'sched_load_balance'
+ * enabled, then simulate turning sched_load_balance off, which
+ * will call rebuild_sched_domains(). The lock_cpu_hotplug()
+ * call in rebuild_sched_domains() must not be made while holding
+ * callback_mutex. Elsewhere the kernel nests callback_mutex inside
+ * lock_cpu_hotplug() calls. So the reverse nesting would risk an
+ * ABBA deadlock.
+ */
-static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
+static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont)
{
- struct cpuset *cs = dentry->d_fsdata;
- struct dentry *d;
- struct cpuset *parent;
- char *pathbuf = NULL;
+ struct cpuset *cs = cgroup_cs(cont);
- /* the vfs holds both inode->i_mutex already */
-
- mutex_lock(&manage_mutex);
cpuset_update_task_memory_state();
- if (atomic_read(&cs->count) > 0) {
- mutex_unlock(&manage_mutex);
- return -EBUSY;
- }
- if (!list_empty(&cs->children)) {
- mutex_unlock(&manage_mutex);
- return -EBUSY;
- }
- parent = cs->parent;
- mutex_lock(&callback_mutex);
- set_bit(CS_REMOVED, &cs->flags);
- list_del(&cs->sibling); /* delete my sibling from parent->children */
- spin_lock(&cs->dentry->d_lock);
- d = dget(cs->dentry);
- cs->dentry = NULL;
- spin_unlock(&d->d_lock);
- cpuset_d_remove_dir(d);
- dput(d);
+
+ if (is_sched_load_balance(cs))
+ update_flag(CS_SCHED_LOAD_BALANCE, cs, "0");
+
number_of_cpusets--;
- mutex_unlock(&callback_mutex);
- if (list_empty(&parent->children))
- check_for_release(parent, &pathbuf);
- mutex_unlock(&manage_mutex);
- cpuset_release_agent(pathbuf);
- return 0;
+ kfree(cs);
}
+struct cgroup_subsys cpuset_subsys = {
+ .name = "cpuset",
+ .create = cpuset_create,
+ .destroy = cpuset_destroy,
+ .can_attach = cpuset_can_attach,
+ .attach = cpuset_attach,
+ .populate = cpuset_populate,
+ .post_clone = cpuset_post_clone,
+ .subsys_id = cpuset_subsys_id,
+ .early_init = 1,
+};
+
/*
* cpuset_init_early - just enough so that the calls to
* cpuset_update_task_memory_state() in early init code
@@ -1949,13 +1657,11 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
int __init cpuset_init_early(void)
{
- struct task_struct *tsk = current;
-
- tsk->cpuset = &top_cpuset;
- tsk->cpuset->mems_generation = cpuset_mems_generation++;
+ top_cpuset.mems_generation = cpuset_mems_generation++;
return 0;
}
+
/**
* cpuset_init - initialize cpusets at system boot
*
@@ -1964,39 +1670,21 @@ int __init cpuset_init_early(void)
int __init cpuset_init(void)
{
- struct dentry *root;
- int err;
+ int err = 0;
top_cpuset.cpus_allowed = CPU_MASK_ALL;
top_cpuset.mems_allowed = NODE_MASK_ALL;
fmeter_init(&top_cpuset.fmeter);
top_cpuset.mems_generation = cpuset_mems_generation++;
-
- init_task.cpuset = &top_cpuset;
+ set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags);
err = register_filesystem(&cpuset_fs_type);
if (err < 0)
- goto out;
- cpuset_mount = kern_mount(&cpuset_fs_type);
- if (IS_ERR(cpuset_mount)) {
- printk(KERN_ERR "cpuset: could not mount!\n");
- err = PTR_ERR(cpuset_mount);
- cpuset_mount = NULL;
- goto out;
- }
- root = cpuset_mount->mnt_sb->s_root;
- root->d_fsdata = &top_cpuset;
- inc_nlink(root->d_inode);
- top_cpuset.dentry = root;
- root->d_inode->i_op = &cpuset_dir_inode_operations;
+ return err;
+
number_of_cpusets = 1;
- err = cpuset_populate_dir(root);
- /* memory_pressure_enabled is in root cpuset only */
- if (err == 0)
- err = cpuset_add_file(root, &cft_memory_pressure_enabled);
-out:
- return err;
+ return 0;
}
/*
@@ -2022,10 +1710,12 @@ out:
static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
{
+ struct cgroup *cont;
struct cpuset *c;
/* Each of our child cpusets mems must be online */
- list_for_each_entry(c, &cur->children, sibling) {
+ list_for_each_entry(cont, &cur->css.cgroup->children, sibling) {
+ c = cgroup_cs(cont);
guarantee_online_cpus_mems_in_subtree(c);
if (!cpus_empty(c->cpus_allowed))
guarantee_online_cpus(c, &c->cpus_allowed);
@@ -2053,7 +1743,7 @@ static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
static void common_cpu_mem_hotplug_unplug(void)
{
- mutex_lock(&manage_mutex);
+ cgroup_lock();
mutex_lock(&callback_mutex);
guarantee_online_cpus_mems_in_subtree(&top_cpuset);
@@ -2061,7 +1751,7 @@ static void common_cpu_mem_hotplug_unplug(void)
top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
mutex_unlock(&callback_mutex);
- mutex_unlock(&manage_mutex);
+ cgroup_unlock();
}
/*
@@ -2074,8 +1764,8 @@ static void common_cpu_mem_hotplug_unplug(void)
* cpu_online_map on each CPU hotplug (cpuhp) event.
*/
-static int cpuset_handle_cpuhp(struct notifier_block *nb,
- unsigned long phase, void *cpu)
+static int cpuset_handle_cpuhp(struct notifier_block *unused_nb,
+ unsigned long phase, void *unused_cpu)
{
if (phase == CPU_DYING || phase == CPU_DYING_FROZEN)
return NOTIFY_DONE;
@@ -2113,109 +1803,7 @@ void __init cpuset_init_smp(void)
}
/**
- * cpuset_fork - attach newly forked task to its parents cpuset.
- * @tsk: pointer to task_struct of forking parent process.
- *
- * Description: A task inherits its parent's cpuset at fork().
- *
- * A pointer to the shared cpuset was automatically copied in fork.c
- * by dup_task_struct(). However, we ignore that copy, since it was
- * not made under the protection of task_lock(), so might no longer be
- * a valid cpuset pointer. attach_task() might have already changed
- * current->cpuset, allowing the previously referenced cpuset to
- * be removed and freed. Instead, we task_lock(current) and copy
- * its present value of current->cpuset for our freshly forked child.
- *
- * At the point that cpuset_fork() is called, 'current' is the parent
- * task, and the passed argument 'child' points to the child task.
- **/
-
-void cpuset_fork(struct task_struct *child)
-{
- task_lock(current);
- child->cpuset = current->cpuset;
- atomic_inc(&child->cpuset->count);
- task_unlock(current);
-}
-
-/**
- * cpuset_exit - detach cpuset from exiting task
- * @tsk: pointer to task_struct of exiting process
- *
- * Description: Detach cpuset from @tsk and release it.
- *
- * Note that cpusets marked notify_on_release force every task in
- * them to take the global manage_mutex mutex when exiting.
- * This could impact scaling on very large systems. Be reluctant to
- * use notify_on_release cpusets where very high task exit scaling
- * is required on large systems.
- *
- * Don't even think about derefencing 'cs' after the cpuset use count
- * goes to zero, except inside a critical section guarded by manage_mutex
- * or callback_mutex. Otherwise a zero cpuset use count is a license to
- * any other task to nuke the cpuset immediately, via cpuset_rmdir().
- *
- * This routine has to take manage_mutex, not callback_mutex, because
- * it is holding that mutex while calling check_for_release(),
- * which calls kmalloc(), so can't be called holding callback_mutex().
- *
- * the_top_cpuset_hack:
- *
- * Set the exiting tasks cpuset to the root cpuset (top_cpuset).
- *
- * Don't leave a task unable to allocate memory, as that is an
- * accident waiting to happen should someone add a callout in
- * do_exit() after the cpuset_exit() call that might allocate.
- * If a task tries to allocate memory with an invalid cpuset,
- * it will oops in cpuset_update_task_memory_state().
- *
- * We call cpuset_exit() while the task is still competent to
- * handle notify_on_release(), then leave the task attached to
- * the root cpuset (top_cpuset) for the remainder of its exit.
- *
- * To do this properly, we would increment the reference count on
- * top_cpuset, and near the very end of the kernel/exit.c do_exit()
- * code we would add a second cpuset function call, to drop that
- * reference. This would just create an unnecessary hot spot on
- * the top_cpuset reference count, to no avail.
- *
- * Normally, holding a reference to a cpuset without bumping its
- * count is unsafe. The cpuset could go away, or someone could
- * attach us to a different cpuset, decrementing the count on
- * the first cpuset that we never incremented. But in this case,
- * top_cpuset isn't going away, and either task has PF_EXITING set,
- * which wards off any attach_task() attempts, or task is a failed
- * fork, never visible to attach_task.
- *
- * Another way to do this would be to set the cpuset pointer
- * to NULL here, and check in cpuset_update_task_memory_state()
- * for a NULL pointer. This hack avoids that NULL check, for no
- * cost (other than this way too long comment ;).
- **/
-void cpuset_exit(struct task_struct *tsk)
-{
- struct cpuset *cs;
-
- task_lock(current);
- cs = tsk->cpuset;
- tsk->cpuset = &top_cpuset; /* the_top_cpuset_hack - see above */
- task_unlock(current);
-
- if (notify_on_release(cs)) {
- char *pathbuf = NULL;
-
- mutex_lock(&manage_mutex);
- if (atomic_dec_and_test(&cs->count))
- check_for_release(cs, &pathbuf);
- mutex_unlock(&manage_mutex);
- cpuset_release_agent(pathbuf);
- } else {
- atomic_dec(&cs->count);
- }
-}
-
-/**
* cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset.
* @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed.
*
@@ -2230,10 +1818,23 @@ cpumask_t cpuset_cpus_allowed(struct task_struct *tsk)
cpumask_t mask;
mutex_lock(&callback_mutex);
+ mask = cpuset_cpus_allowed_locked(tsk);
+ mutex_unlock(&callback_mutex);
+
+ return mask;
+}
+
+/**
+ * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset.
+ * Must be called with callback_mutex held.
+ **/
+cpumask_t cpuset_cpus_allowed_locked(struct task_struct *tsk)
+{
+ cpumask_t mask;
+
task_lock(tsk);
- guarantee_online_cpus(tsk->cpuset, &mask);
+ guarantee_online_cpus(task_cs(tsk), &mask);
task_unlock(tsk);
- mutex_unlock(&callback_mutex);
return mask;
}
@@ -2259,7 +1860,7 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk)
mutex_lock(&callback_mutex);
task_lock(tsk);
- guarantee_online_mems(tsk->cpuset, &mask);
+ guarantee_online_mems(task_cs(tsk), &mask);
task_unlock(tsk);
mutex_unlock(&callback_mutex);
@@ -2390,7 +1991,7 @@ int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask)
mutex_lock(&callback_mutex);
task_lock(current);
- cs = nearest_exclusive_ancestor(current->cpuset);
+ cs = nearest_exclusive_ancestor(task_cs(current));
task_unlock(current);
allowed = node_isset(node, cs->mems_allowed);
@@ -2550,14 +2151,12 @@ int cpuset_memory_pressure_enabled __read_mostly;
void __cpuset_memory_pressure_bump(void)
{
- struct cpuset *cs;
-
task_lock(current);
- cs = current->cpuset;
- fmeter_markevent(&cs->fmeter);
+ fmeter_markevent(&task_cs(current)->fmeter);
task_unlock(current);
}
+#ifdef CONFIG_PROC_PID_CPUSET
/*
* proc_cpuset_show()
* - Print tasks cpuset path into seq_file.
@@ -2569,11 +2168,12 @@ void __cpuset_memory_pressure_bump(void)
* the_top_cpuset_hack in cpuset_exit(), which sets an exiting tasks
* cpuset to top_cpuset.
*/
-static int proc_cpuset_show(struct seq_file *m, void *v)
+static int proc_cpuset_show(struct seq_file *m, void *unused_v)
{
struct pid *pid;
struct task_struct *tsk;
char *buf;
+ struct cgroup_subsys_state *css;
int retval;
retval = -ENOMEM;
@@ -2588,15 +2188,15 @@ static int proc_cpuset_show(struct seq_file *m, void *v)
goto out_free;
retval = -EINVAL;
- mutex_lock(&manage_mutex);
-
- retval = cpuset_path(tsk->cpuset, buf, PAGE_SIZE);
+ cgroup_lock();
+ css = task_subsys_state(tsk, cpuset_subsys_id);
+ retval = cgroup_path(css->cgroup, buf, PAGE_SIZE);
if (retval < 0)
goto out_unlock;
seq_puts(m, buf);
seq_putc(m, '\n');
out_unlock:
- mutex_unlock(&manage_mutex);
+ cgroup_unlock();
put_task_struct(tsk);
out_free:
kfree(buf);
@@ -2616,6 +2216,7 @@ const struct file_operations proc_cpuset_operations = {
.llseek = seq_lseek,
.release = single_release,
};
+#endif /* CONFIG_PROC_PID_CPUSET */
/* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */
char *cpuset_task_status_allowed(struct task_struct *task, char *buffer)
diff --git a/kernel/die_notifier.c b/kernel/die_notifier.c
deleted file mode 100644
index 0d98827887a..00000000000
--- a/kernel/die_notifier.c
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#include <linux/module.h>
-#include <linux/notifier.h>
-#include <linux/vmalloc.h>
-#include <linux/kdebug.h>
-
-
-static ATOMIC_NOTIFIER_HEAD(die_chain);
-
-int notify_die(enum die_val val, const char *str,
- struct pt_regs *regs, long err, int trap, int sig)
-{
- struct die_args args = {
- .regs = regs,
- .str = str,
- .err = err,
- .trapnr = trap,
- .signr = sig,
-
- };
-
- return atomic_notifier_call_chain(&die_chain, val, &args);
-}
-
-int register_die_notifier(struct notifier_block *nb)
-{
- vmalloc_sync_all();
- return atomic_notifier_chain_register(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(register_die_notifier);
-
-int unregister_die_notifier(struct notifier_block *nb)
-{
- return atomic_notifier_chain_unregister(&die_chain, nb);
-}
-EXPORT_SYMBOL_GPL(unregister_die_notifier);
-
-
diff --git a/kernel/exit.c b/kernel/exit.c
index 2c704c86edb..f1aec27f1df 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -31,7 +31,7 @@
#include <linux/taskstats_kern.h>
#include <linux/delayacct.h>
#include <linux/freezer.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
#include <linux/posix-timers.h>
@@ -148,6 +148,7 @@ void release_task(struct task_struct * p)
int zap_leader;
repeat:
atomic_dec(&p->user->processes);
+ proc_flush_task(p);
write_lock_irq(&tasklist_lock);
ptrace_unlink(p);
BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
@@ -175,7 +176,6 @@ repeat:
}
write_unlock_irq(&tasklist_lock);
- proc_flush_task(p);
release_thread(p);
call_rcu(&p->rcu, delayed_put_task_struct);
@@ -221,7 +221,7 @@ static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignor
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
if (p == ignored_task
|| p->exit_state
- || is_init(p->real_parent))
+ || is_global_init(p->real_parent))
continue;
if (task_pgrp(p->real_parent) != pgrp &&
task_session(p->real_parent) == task_session(p)) {
@@ -299,14 +299,14 @@ void __set_special_pids(pid_t session, pid_t pgrp)
{
struct task_struct *curr = current->group_leader;
- if (process_session(curr) != session) {
+ if (task_session_nr(curr) != session) {
detach_pid(curr, PIDTYPE_SID);
- set_signal_session(curr->signal, session);
+ set_task_session(curr, session);
attach_pid(curr, PIDTYPE_SID, find_pid(session));
}
- if (process_group(curr) != pgrp) {
+ if (task_pgrp_nr(curr) != pgrp) {
detach_pid(curr, PIDTYPE_PGID);
- curr->signal->pgrp = pgrp;
+ set_task_pgrp(curr, pgrp);
attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
}
}
@@ -400,11 +400,12 @@ void daemonize(const char *name, ...)
current->fs = fs;
atomic_inc(&fs->count);
- exit_task_namespaces(current);
- current->nsproxy = init_task.nsproxy;
- get_task_namespaces(current);
+ if (current->nsproxy != init_task.nsproxy) {
+ get_nsproxy(init_task.nsproxy);
+ switch_task_namespaces(current, init_task.nsproxy);
+ }
- exit_files(current);
+ exit_files(current);
current->files = init_task.files;
atomic_inc(&current->files->count);
@@ -492,7 +493,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
}
EXPORT_SYMBOL(reset_files_struct);
-static inline void __exit_files(struct task_struct *tsk)
+static void __exit_files(struct task_struct *tsk)
{
struct files_struct * files = tsk->files;
@@ -509,7 +510,7 @@ void exit_files(struct task_struct *tsk)
__exit_files(tsk);
}
-static inline void __put_fs_struct(struct fs_struct *fs)
+static void __put_fs_struct(struct fs_struct *fs)
{
/* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) {
@@ -530,7 +531,7 @@ void put_fs_struct(struct fs_struct *fs)
__put_fs_struct(fs);
}
-static inline void __exit_fs(struct task_struct *tsk)
+static void __exit_fs(struct task_struct *tsk)
{
struct fs_struct * fs = tsk->fs;
@@ -665,19 +666,22 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
* the child reaper process (ie "init") in our pid
* space.
*/
-static void
-forget_original_parent(struct task_struct *father, struct list_head *to_release)
+static void forget_original_parent(struct task_struct *father)
{
- struct task_struct *p, *reaper = father;
- struct list_head *_p, *_n;
+ struct task_struct *p, *n, *reaper = father;
+ struct list_head ptrace_dead;
+
+ INIT_LIST_HEAD(&ptrace_dead);
+
+ write_lock_irq(&tasklist_lock);
do {
reaper = next_thread(reaper);
if (reaper == father) {
- reaper = child_reaper(father);
+ reaper = task_child_reaper(father);
break;
}
- } while (reaper->exit_state);
+ } while (reaper->flags & PF_EXITING);
/*
* There are only two places where our children can be:
@@ -687,9 +691,8 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
*
* Search them and reparent children.
*/
- list_for_each_safe(_p, _n, &father->children) {
+ list_for_each_entry_safe(p, n, &father->children, sibling) {
int ptrace;
- p = list_entry(_p, struct task_struct, sibling);
ptrace = p->ptrace;
@@ -715,13 +718,23 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
* while it was being traced by us, to be able to see it in wait4.
*/
if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
- list_add(&p->ptrace_list, to_release);
+ list_add(&p->ptrace_list, &ptrace_dead);
}
- list_for_each_safe(_p, _n, &father->ptrace_children) {
- p = list_entry(_p, struct task_struct, ptrace_list);
+
+ list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) {
p->real_parent = reaper;
reparent_thread(p, father, 1);
}
+
+ write_unlock_irq(&tasklist_lock);
+ BUG_ON(!list_empty(&father->children));
+ BUG_ON(!list_empty(&father->ptrace_children));
+
+ list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) {
+ list_del_init(&p->ptrace_list);
+ release_task(p);
+ }
+
}
/*
@@ -732,7 +745,6 @@ static void exit_notify(struct task_struct *tsk)
{
int state;
struct task_struct *t;
- struct list_head ptrace_dead, *_p, *_n;
struct pid *pgrp;
if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
@@ -753,8 +765,6 @@ static void exit_notify(struct task_struct *tsk)
spin_unlock_irq(&tsk->sighand->siglock);
}
- write_lock_irq(&tasklist_lock);
-
/*
* This does two things:
*
@@ -763,12 +773,10 @@ static void exit_notify(struct task_struct *tsk)
* as a result of our exiting, and if they have any stopped
* jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
*/
+ forget_original_parent(tsk);
+ exit_task_namespaces(tsk);
- INIT_LIST_HEAD(&ptrace_dead);
- forget_original_parent(tsk, &ptrace_dead);
- BUG_ON(!list_empty(&tsk->children));
- BUG_ON(!list_empty(&tsk->ptrace_children));
-
+ write_lock_irq(&tasklist_lock);
/*
* Check to see if any process groups have become orphaned
* as a result of our exiting, and if they have any stopped
@@ -792,7 +800,7 @@ static void exit_notify(struct task_struct *tsk)
/* Let father know we died
*
* Thread signals are configurable, but you aren't going to use
- * that to send signals to arbitary processes.
+ * that to send signals to arbitary processes.
* That stops right now.
*
* If the parent exec id doesn't match the exec id we saved
@@ -833,12 +841,6 @@ static void exit_notify(struct task_struct *tsk)
write_unlock_irq(&tasklist_lock);
- list_for_each_safe(_p, _n, &ptrace_dead) {
- list_del_init(_p);
- t = list_entry(_p, struct task_struct, ptrace_list);
- release_task(t);
- }
-
/* If the process is dead, release it - nobody will wait for it */
if (state == EXIT_DEAD)
release_task(tsk);
@@ -874,10 +876,35 @@ static inline void check_stack_usage(void) {}
static inline void exit_child_reaper(struct task_struct *tsk)
{
- if (likely(tsk->group_leader != child_reaper(tsk)))
+ if (likely(tsk->group_leader != task_child_reaper(tsk)))
return;
- panic("Attempted to kill init!");
+ if (tsk->nsproxy->pid_ns == &init_pid_ns)
+ panic("Attempted to kill init!");
+
+ /*
+ * @tsk is the last thread in the 'cgroup-init' and is exiting.
+ * Terminate all remaining processes in the namespace and reap them
+ * before exiting @tsk.
+ *
+ * Note that @tsk (last thread of cgroup-init) may not necessarily
+ * be the child-reaper (i.e main thread of cgroup-init) of the
+ * namespace i.e the child_reaper may have already exited.
+ *
+ * Even after a child_reaper exits, we let it inherit orphaned children,
+ * because, pid_ns->child_reaper remains valid as long as there is
+ * at least one living sub-thread in the cgroup init.
+
+ * This living sub-thread of the cgroup-init will be notified when
+ * a child inherited by the 'child-reaper' exits (do_notify_parent()
+ * uses __group_send_sig_info()). Further, when reaping child processes,
+ * do_wait() iterates over children of all living sub threads.
+
+ * i.e even though 'child_reaper' thread is listed as the parent of the
+ * orphaned children, any living sub-thread in the cgroup-init can
+ * perform the role of the child_reaper.
+ */
+ zap_pid_ns_processes(tsk->nsproxy->pid_ns);
}
fastcall NORET_TYPE void do_exit(long code)
@@ -932,7 +959,7 @@ fastcall NORET_TYPE void do_exit(long code)
if (unlikely(in_atomic()))
printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
- current->comm, current->pid,
+ current->comm, task_pid_nr(current),
preempt_count());
acct_update_integrals(tsk);
@@ -972,7 +999,7 @@ fastcall NORET_TYPE void do_exit(long code)
__exit_fs(tsk);
check_stack_usage();
exit_thread();
- cpuset_exit(tsk);
+ cgroup_exit(tsk, 1);
exit_keys(tsk);
if (group_dead && tsk->signal->leader)
@@ -983,7 +1010,6 @@ fastcall NORET_TYPE void do_exit(long code)
module_put(tsk->binfmt->module);
proc_exit_connector(tsk);
- exit_task_namespaces(tsk);
exit_notify(tsk);
#ifdef CONFIG_NUMA
mpol_free(tsk->mempolicy);
@@ -1086,15 +1112,17 @@ asmlinkage void sys_exit_group(int error_code)
static int eligible_child(pid_t pid, int options, struct task_struct *p)
{
int err;
+ struct pid_namespace *ns;
+ ns = current->nsproxy->pid_ns;
if (pid > 0) {
- if (p->pid != pid)
+ if (task_pid_nr_ns(p, ns) != pid)
return 0;
} else if (!pid) {
- if (process_group(p) != process_group(current))
+ if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current))
return 0;
} else if (pid != -1) {
- if (process_group(p) != -pid)
+ if (task_pgrp_nr_ns(p, ns) != -pid)
return 0;
}
@@ -1164,9 +1192,12 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
{
unsigned long state;
int retval, status, traced;
+ struct pid_namespace *ns;
+
+ ns = current->nsproxy->pid_ns;
if (unlikely(noreap)) {
- pid_t pid = p->pid;
+ pid_t pid = task_pid_nr_ns(p, ns);
uid_t uid = p->uid;
int exit_code = p->exit_code;
int why, status;
@@ -1285,11 +1316,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
retval = put_user(status, &infop->si_status);
}
if (!retval && infop)
- retval = put_user(p->pid, &infop->si_pid);
+ retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
if (!retval)
- retval = p->pid;
+ retval = task_pid_nr_ns(p, ns);
if (traced) {
write_lock_irq(&tasklist_lock);
@@ -1326,6 +1357,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
int __user *stat_addr, struct rusage __user *ru)
{
int retval, exit_code;
+ struct pid_namespace *ns;
if (!p->exit_code)
return 0;
@@ -1344,11 +1376,12 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
* keep holding onto the tasklist_lock while we call getrusage and
* possibly take page faults for user memory.
*/
+ ns = current->nsproxy->pid_ns;
get_task_struct(p);
read_unlock(&tasklist_lock);
if (unlikely(noreap)) {
- pid_t pid = p->pid;
+ pid_t pid = task_pid_nr_ns(p, ns);
uid_t uid = p->uid;
int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
@@ -1419,11 +1452,11 @@ bail_ref:
if (!retval && infop)
retval = put_user(exit_code, &infop->si_status);
if (!retval && infop)
- retval = put_user(p->pid, &infop->si_pid);
+ retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
if (!retval)
- retval = p->pid;
+ retval = task_pid_nr_ns(p, ns);
put_task_struct(p);
BUG_ON(!retval);
@@ -1443,6 +1476,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
int retval;
pid_t pid;
uid_t uid;
+ struct pid_namespace *ns;
if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
return 0;
@@ -1457,7 +1491,8 @@ static int wait_task_continued(struct task_struct *p, int noreap,
p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
spin_unlock_irq(&p->sighand->siglock);
- pid = p->pid;
+ ns = current->nsproxy->pid_ns;
+ pid = task_pid_nr_ns(p, ns);
uid = p->uid;
get_task_struct(p);
read_unlock(&tasklist_lock);
@@ -1468,7 +1503,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
if (!retval && stat_addr)
retval = put_user(0xffff, stat_addr);
if (!retval)
- retval = p->pid;
+ retval = task_pid_nr_ns(p, ns);
} else {
retval = wait_noreap_copyout(p, pid, uid,
CLD_CONTINUED, SIGCONT,
@@ -1517,12 +1552,9 @@ repeat:
tsk = current;
do {
struct task_struct *p;
- struct list_head *_p;
int ret;
- list_for_each(_p,&tsk->children) {
- p = list_entry(_p, struct task_struct, sibling);
-
+ list_for_each_entry(p, &tsk->children, sibling) {
ret = eligible_child(pid, options, p);
if (!ret)
continue;
@@ -1604,9 +1636,8 @@ check_continued:
}
}
if (!flag) {
- list_for_each(_p, &tsk->ptrace_children) {
- p = list_entry(_p, struct task_struct,
- ptrace_list);
+ list_for_each_entry(p, &tsk->ptrace_children,
+ ptrace_list) {
if (!eligible_child(pid, options, p))
continue;
flag = 1;
diff --git a/kernel/fork.c b/kernel/fork.c
index 2ce28f165e3..ddafdfac945 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -29,7 +29,7 @@
#include <linux/nsproxy.h>
#include <linux/capability.h>
#include <linux/cpu.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
#include <linux/security.h>
#include <linux/swap.h>
#include <linux/syscalls.h>
@@ -50,6 +50,7 @@
#include <linux/taskstats_kern.h>
#include <linux/random.h>
#include <linux/tty.h>
+#include <linux/proc_fs.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -116,7 +117,7 @@ EXPORT_SYMBOL(free_task);
void __put_task_struct(struct task_struct *tsk)
{
- WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
+ WARN_ON(!tsk->exit_state);
WARN_ON(atomic_read(&tsk->usage));
WARN_ON(tsk == current);
@@ -205,7 +206,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
}
#ifdef CONFIG_MMU
-static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
+static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
struct vm_area_struct *mpnt, *tmp, **pprev;
struct rb_node **rb_link, *rb_parent;
@@ -583,7 +584,7 @@ fail_nomem:
return retval;
}
-static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old)
+static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
{
struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL);
/* We don't need to lock fs - think why ;-) */
@@ -615,7 +616,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
EXPORT_SYMBOL_GPL(copy_fs_struct);
-static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
{
if (clone_flags & CLONE_FS) {
atomic_inc(&current->fs->count);
@@ -818,7 +819,7 @@ int unshare_files(void)
EXPORT_SYMBOL(unshare_files);
-static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
{
struct sighand_struct *sig;
@@ -841,7 +842,7 @@ void __cleanup_sighand(struct sighand_struct *sighand)
kmem_cache_free(sighand_cachep, sighand);
}
-static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk)
+static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
{
struct signal_struct *sig;
int ret;
@@ -923,7 +924,7 @@ void __cleanup_signal(struct signal_struct *sig)
kmem_cache_free(signal_cachep, sig);
}
-static inline void cleanup_signal(struct task_struct *tsk)
+static void cleanup_signal(struct task_struct *tsk)
{
struct signal_struct *sig = tsk->signal;
@@ -933,7 +934,7 @@ static inline void cleanup_signal(struct task_struct *tsk)
__cleanup_signal(sig);
}
-static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
+static void copy_flags(unsigned long clone_flags, struct task_struct *p)
{
unsigned long new_flags = p->flags;
@@ -949,10 +950,10 @@ asmlinkage long sys_set_tid_address(int __user *tidptr)
{
current->clear_child_tid = tidptr;
- return current->pid;
+ return task_pid_vnr(current);
}
-static inline void rt_mutex_init_task(struct task_struct *p)
+static void rt_mutex_init_task(struct task_struct *p)
{
spin_lock_init(&p->pi_lock);
#ifdef CONFIG_RT_MUTEXES
@@ -973,12 +974,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
- int __user *parent_tidptr,
int __user *child_tidptr,
struct pid *pid)
{
int retval;
- struct task_struct *p = NULL;
+ struct task_struct *p;
+ int cgroup_callbacks_done = 0;
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
return ERR_PTR(-EINVAL);
@@ -1042,12 +1043,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->did_exec = 0;
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
copy_flags(clone_flags, p);
- p->pid = pid_nr(pid);
- retval = -EFAULT;
- if (clone_flags & CLONE_PARENT_SETTID)
- if (put_user(p->pid, parent_tidptr))
- goto bad_fork_cleanup_delays_binfmt;
-
INIT_LIST_HEAD(&p->children);
INIT_LIST_HEAD(&p->sibling);
p->vfork_done = NULL;
@@ -1087,13 +1082,13 @@ static struct task_struct *copy_process(unsigned long clone_flags,
#endif
p->io_context = NULL;
p->audit_context = NULL;
- cpuset_fork(p);
+ cgroup_fork(p);
#ifdef CONFIG_NUMA
p->mempolicy = mpol_copy(p->mempolicy);
if (IS_ERR(p->mempolicy)) {
retval = PTR_ERR(p->mempolicy);
p->mempolicy = NULL;
- goto bad_fork_cleanup_cpuset;
+ goto bad_fork_cleanup_cgroup;
}
mpol_fix_fork_child_flag(p);
#endif
@@ -1126,10 +1121,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->blocked_on = NULL; /* not blocked yet */
#endif
- p->tgid = p->pid;
- if (clone_flags & CLONE_THREAD)
- p->tgid = current->tgid;
-
if ((retval = security_task_alloc(p)))
goto bad_fork_cleanup_policy;
if ((retval = audit_alloc(p)))
@@ -1155,6 +1146,24 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if (retval)
goto bad_fork_cleanup_namespaces;
+ if (pid != &init_struct_pid) {
+ retval = -ENOMEM;
+ pid = alloc_pid(task_active_pid_ns(p));
+ if (!pid)
+ goto bad_fork_cleanup_namespaces;
+
+ if (clone_flags & CLONE_NEWPID) {
+ retval = pid_ns_prepare_proc(task_active_pid_ns(p));
+ if (retval < 0)
+ goto bad_fork_free_pid;
+ }
+ }
+
+ p->pid = pid_nr(pid);
+ p->tgid = p->pid;
+ if (clone_flags & CLONE_THREAD)
+ p->tgid = current->tgid;
+
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
/*
* Clear TID on mm_release()?
@@ -1204,6 +1213,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
/* Perform scheduler related setup. Assign this task to a CPU. */
sched_fork(p, clone_flags);
+ /* Now that the task is set up, run cgroup callbacks if
+ * necessary. We need to run them before the task is visible
+ * on the tasklist. */
+ cgroup_fork_callbacks(p);
+ cgroup_callbacks_done = 1;
+
/* Need tasklist lock for parent etc handling! */
write_lock_irq(&tasklist_lock);
@@ -1246,7 +1261,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
retval = -ERESTARTNOINTR;
- goto bad_fork_cleanup_namespaces;
+ goto bad_fork_free_pid;
}
if (clone_flags & CLONE_THREAD) {
@@ -1275,11 +1290,22 @@ static struct task_struct *copy_process(unsigned long clone_flags,
__ptrace_link(p, current->parent);
if (thread_group_leader(p)) {
- p->signal->tty = current->signal->tty;
- p->signal->pgrp = process_group(current);
- set_signal_session(p->signal, process_session(current));
- attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
- attach_pid(p, PIDTYPE_SID, task_session(current));
+ if (clone_flags & CLONE_NEWPID) {
+ p->nsproxy->pid_ns->child_reaper = p;
+ p->signal->tty = NULL;
+ set_task_pgrp(p, p->pid);
+ set_task_session(p, p->pid);
+ attach_pid(p, PIDTYPE_PGID, pid);
+ attach_pid(p, PIDTYPE_SID, pid);
+ } else {
+ p->signal->tty = current->signal->tty;
+ set_task_pgrp(p, task_pgrp_nr(current));
+ set_task_session(p, task_session_nr(current));
+ attach_pid(p, PIDTYPE_PGID,
+ task_pgrp(current));
+ attach_pid(p, PIDTYPE_SID,
+ task_session(current));
+ }
list_add_tail_rcu(&p->tasks, &init_task.tasks);
__get_cpu_var(process_counts)++;
@@ -1292,8 +1318,12 @@ static struct task_struct *copy_process(unsigned long clone_flags,
spin_unlock(&current->sighand->siglock);
write_unlock_irq(&tasklist_lock);
proc_fork_connector(p);
+ cgroup_post_fork(p);
return p;
+bad_fork_free_pid:
+ if (pid != &init_struct_pid)
+ free_pid(pid);
bad_fork_cleanup_namespaces:
exit_task_namespaces(p);
bad_fork_cleanup_keys:
@@ -1318,10 +1348,9 @@ bad_fork_cleanup_security:
bad_fork_cleanup_policy:
#ifdef CONFIG_NUMA
mpol_free(p->mempolicy);
-bad_fork_cleanup_cpuset:
+bad_fork_cleanup_cgroup:
#endif
- cpuset_exit(p);
-bad_fork_cleanup_delays_binfmt:
+ cgroup_exit(p, cgroup_callbacks_done);
delayacct_tsk_free(p);
if (p->binfmt)
module_put(p->binfmt->module);
@@ -1348,7 +1377,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
struct task_struct *task;
struct pt_regs regs;
- task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL, NULL,
+ task = copy_process(CLONE_VM, 0, idle_regs(&regs), 0, NULL,
&init_struct_pid);
if (!IS_ERR(task))
init_idle(task, cpu);
@@ -1356,7 +1385,7 @@ struct task_struct * __cpuinit fork_idle(int cpu)
return task;
}
-static inline int fork_traceflag (unsigned clone_flags)
+static int fork_traceflag(unsigned clone_flags)
{
if (clone_flags & CLONE_UNTRACED)
return 0;
@@ -1387,19 +1416,16 @@ long do_fork(unsigned long clone_flags,
{
struct task_struct *p;
int trace = 0;
- struct pid *pid = alloc_pid();
long nr;
- if (!pid)
- return -EAGAIN;
- nr = pid->nr;
if (unlikely(current->ptrace)) {
trace = fork_traceflag (clone_flags);
if (trace)
clone_flags |= CLONE_PTRACE;
}
- p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid);
+ p = copy_process(clone_flags, stack_start, regs, stack_size,
+ child_tidptr, NULL);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
@@ -1407,6 +1433,17 @@ long do_fork(unsigned long clone_flags,
if (!IS_ERR(p)) {
struct completion vfork;
+ /*
+ * this is enough to call pid_nr_ns here, but this if
+ * improves optimisation of regular fork()
+ */
+ nr = (clone_flags & CLONE_NEWPID) ?
+ task_pid_nr_ns(p, current->nsproxy->pid_ns) :
+ task_pid_vnr(p);
+
+ if (clone_flags & CLONE_PARENT_SETTID)
+ put_user(nr, parent_tidptr);
+
if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
@@ -1440,7 +1477,6 @@ long do_fork(unsigned long clone_flags,
}
}
} else {
- free_pid(pid);
nr = PTR_ERR(p);
}
return nr;
@@ -1485,7 +1521,7 @@ void __init proc_caches_init(void)
* Check constraints on flags passed to the unshare system call and
* force unsharing of additional process context as appropriate.
*/
-static inline void check_unshare_flags(unsigned long *flags_ptr)
+static void check_unshare_flags(unsigned long *flags_ptr)
{
/*
* If unsharing a thread from a thread group, must also
@@ -1617,7 +1653,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL;
struct files_struct *fd, *new_fd = NULL;
struct sem_undo_list *new_ulist = NULL;
- struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL;
+ struct nsproxy *new_nsproxy = NULL;
check_unshare_flags(&unshare_flags);
@@ -1647,14 +1683,13 @@ asmlinkage long sys_unshare(unsigned long unshare_flags)
if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) {
- task_lock(current);
-
if (new_nsproxy) {
- old_nsproxy = current->nsproxy;
- current->nsproxy = new_nsproxy;
- new_nsproxy = old_nsproxy;
+ switch_task_namespaces(current, new_nsproxy);
+ new_nsproxy = NULL;
}
+ task_lock(current);
+
if (new_fs) {
fs = current->fs;
current->fs = new_fs;
diff --git a/kernel/futex.c b/kernel/futex.c
index e45a65e4168..32710451dc2 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -53,6 +53,9 @@
#include <linux/signal.h>
#include <linux/module.h>
#include <linux/magic.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
+
#include <asm/futex.h>
#include "rtmutex_common.h"
@@ -443,8 +446,7 @@ static struct task_struct * futex_find_get_task(pid_t pid)
struct task_struct *p;
rcu_read_lock();
- p = find_task_by_pid(pid);
-
+ p = find_task_by_vpid(pid);
if (!p || ((current->euid != p->euid) && (current->euid != p->uid)))
p = ERR_PTR(-ESRCH);
else
@@ -653,7 +655,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
if (!(uval & FUTEX_OWNER_DIED)) {
int ret = 0;
- newval = FUTEX_WAITERS | new_owner->pid;
+ newval = FUTEX_WAITERS | task_pid_vnr(new_owner);
curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
@@ -1106,7 +1108,7 @@ static void unqueue_me_pi(struct futex_q *q)
static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
struct task_struct *curr)
{
- u32 newtid = curr->pid | FUTEX_WAITERS;
+ u32 newtid = task_pid_vnr(curr) | FUTEX_WAITERS;
struct futex_pi_state *pi_state = q->pi_state;
u32 uval, curval, newval;
int ret;
@@ -1368,7 +1370,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
* (by doing a 0 -> TID atomic cmpxchg), while holding all
* the locks. It will most likely not succeed.
*/
- newval = current->pid;
+ newval = task_pid_vnr(current);
curval = cmpxchg_futex_value_locked(uaddr, 0, newval);
@@ -1379,7 +1381,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
* Detect deadlocks. In case of REQUEUE_PI this is a valid
* situation and we return success to user space.
*/
- if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) {
+ if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) {
ret = -EDEADLK;
goto out_unlock_release_sem;
}
@@ -1408,7 +1410,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
*/
if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) {
/* Keep the OWNER_DIED bit */
- newval = (curval & ~FUTEX_TID_MASK) | current->pid;
+ newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(current);
ownerdied = 0;
lock_taken = 1;
}
@@ -1587,7 +1589,7 @@ retry:
/*
* We release only a lock we actually own:
*/
- if ((uval & FUTEX_TID_MASK) != current->pid)
+ if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current))
return -EPERM;
/*
* First take all the futex related locks:
@@ -1608,7 +1610,7 @@ retry_unlocked:
* anyone else up:
*/
if (!(uval & FUTEX_OWNER_DIED))
- uval = cmpxchg_futex_value_locked(uaddr, current->pid, 0);
+ uval = cmpxchg_futex_value_locked(uaddr, task_pid_vnr(current), 0);
if (unlikely(uval == -EFAULT))
@@ -1617,7 +1619,7 @@ retry_unlocked:
* Rare case: we managed to release the lock atomically,
* no need to wake anyone else up:
*/
- if (unlikely(uval == current->pid))
+ if (unlikely(uval == task_pid_vnr(current)))
goto out_unlock;
/*
@@ -1854,7 +1856,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr,
ret = -ESRCH;
rcu_read_lock();
- p = find_task_by_pid(pid);
+ p = find_task_by_vpid(pid);
if (!p)
goto err_unlock;
ret = -EPERM;
@@ -1887,7 +1889,7 @@ retry:
if (get_user(uval, uaddr))
return -1;
- if ((uval & FUTEX_TID_MASK) == curr->pid) {
+ if ((uval & FUTEX_TID_MASK) == task_pid_vnr(curr)) {
/*
* Ok, this dying thread is truly holding a futex
* of interest. Set the OWNER_DIED bit atomically
diff --git a/kernel/futex_compat.c b/kernel/futex_compat.c
index 2c2e2954b71..00b572666cc 100644
--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -8,6 +8,7 @@
#include <linux/linkage.h>
#include <linux/compat.h>
+#include <linux/nsproxy.h>
#include <linux/futex.h>
#include <asm/uaccess.h>
@@ -124,7 +125,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
ret = -ESRCH;
read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
+ p = find_task_by_vpid(pid);
if (!p)
goto err_unlock;
ret = -EPERM;
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index b2b2c2b0a49..b6d2ff7e37e 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -412,7 +412,7 @@ static int hrtimer_reprogram(struct hrtimer *timer,
/*
* When the callback is running, we do not reprogram the clock event
* device. The timer callback is either running on a different CPU or
- * the callback is executed in the hrtimer_interupt context. The
+ * the callback is executed in the hrtimer_interrupt context. The
* reprogramming is handled either by the softirq, which called the
* callback or at the end of the hrtimer_interrupt.
*/
@@ -638,7 +638,7 @@ void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, void *addr)
#endif
/*
- * Counterpart to lock_timer_base above:
+ * Counterpart to lock_hrtimer_base above:
*/
static inline
void unlock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index e9f1b4ea504..aa74a1ef2da 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -51,7 +51,7 @@ struct resource crashk_res = {
int kexec_should_crash(struct task_struct *p)
{
- if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops)
+ if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops)
return 1;
return 0;
}
@@ -1146,6 +1146,172 @@ static int __init crash_notes_memory_init(void)
}
module_init(crash_notes_memory_init)
+
+/*
+ * parsing the "crashkernel" commandline
+ *
+ * this code is intended to be called from architecture specific code
+ */
+
+
+/*
+ * This function parses command lines in the format
+ *
+ * crashkernel=ramsize-range:size[,...][@offset]
+ *
+ * The function returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_mem(char *cmdline,
+ unsigned long long system_ram,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base)
+{
+ char *cur = cmdline, *tmp;
+
+ /* for each entry of the comma-separated list */
+ do {
+ unsigned long long start, end = ULLONG_MAX, size;
+
+ /* get the start of the range */
+ start = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warning("crashkernel: Memory value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (*cur != '-') {
+ pr_warning("crashkernel: '-' expected\n");
+ return -EINVAL;
+ }
+ cur++;
+
+ /* if no ':' is here, than we read the end */
+ if (*cur != ':') {
+ end = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warning("crashkernel: Memory "
+ "value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (end <= start) {
+ pr_warning("crashkernel: end <= start\n");
+ return -EINVAL;
+ }
+ }
+
+ if (*cur != ':') {
+ pr_warning("crashkernel: ':' expected\n");
+ return -EINVAL;
+ }
+ cur++;
+
+ size = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warning("Memory value expected\n");
+ return -EINVAL;
+ }
+ cur = tmp;
+ if (size >= system_ram) {
+ pr_warning("crashkernel: invalid size\n");
+ return -EINVAL;
+ }
+
+ /* match ? */
+ if (system_ram >= start && system_ram <= end) {
+ *crash_size = size;
+ break;
+ }
+ } while (*cur++ == ',');
+
+ if (*crash_size > 0) {
+ while (*cur != ' ' && *cur != '@')
+ cur++;
+ if (*cur == '@') {
+ cur++;
+ *crash_base = memparse(cur, &tmp);
+ if (cur == tmp) {
+ pr_warning("Memory value expected "
+ "after '@'\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * That function parses "simple" (old) crashkernel command lines like
+ *
+ * crashkernel=size[@offset]
+ *
+ * It returns 0 on success and -EINVAL on failure.
+ */
+static int __init parse_crashkernel_simple(char *cmdline,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base)
+{
+ char *cur = cmdline;
+
+ *crash_size = memparse(cmdline, &cur);
+ if (cmdline == cur) {
+ pr_warning("crashkernel: memory value expected\n");
+ return -EINVAL;
+ }
+
+ if (*cur == '@')
+ *crash_base = memparse(cur+1, &cur);
+
+ return 0;
+}
+
+/*
+ * That function is the entry point for command line parsing and should be
+ * called from the arch-specific code.
+ */
+int __init parse_crashkernel(char *cmdline,
+ unsigned long long system_ram,
+ unsigned long long *crash_size,
+ unsigned long long *crash_base)
+{
+ char *p = cmdline, *ck_cmdline = NULL;
+ char *first_colon, *first_space;
+
+ BUG_ON(!crash_size || !crash_base);
+ *crash_size = 0;
+ *crash_base = 0;
+
+ /* find crashkernel and use the last one if there are more */
+ p = strstr(p, "crashkernel=");
+ while (p) {
+ ck_cmdline = p;
+ p = strstr(p+1, "crashkernel=");
+ }
+
+ if (!ck_cmdline)
+ return -EINVAL;
+
+ ck_cmdline += 12; /* strlen("crashkernel=") */
+
+ /*
+ * if the commandline contains a ':', then that's the extended
+ * syntax -- if not, it must be the classic syntax
+ */
+ first_colon = strchr(ck_cmdline, ':');
+ first_space = strchr(ck_cmdline, ' ');
+ if (first_colon && (!first_space || first_colon < first_space))
+ return parse_crashkernel_mem(ck_cmdline, system_ram,
+ crash_size, crash_base);
+ else
+ return parse_crashkernel_simple(ck_cmdline, crash_size,
+ crash_base);
+
+ return 0;
+}
+
+
+
void crash_save_vmcoreinfo(void)
{
u32 *buf;
diff --git a/kernel/lockdep.c b/kernel/lockdep.c
index a6f1ee9c92d..55fe0c7cd95 100644
--- a/kernel/lockdep.c
+++ b/kernel/lockdep.c
@@ -511,11 +511,11 @@ static void lockdep_print_held_locks(struct task_struct *curr)
int i, depth = curr->lockdep_depth;
if (!depth) {
- printk("no locks held by %s/%d.\n", curr->comm, curr->pid);
+ printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr));
return;
}
printk("%d lock%s held by %s/%d:\n",
- depth, depth > 1 ? "s" : "", curr->comm, curr->pid);
+ depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr));
for (i = 0; i < depth; i++) {
printk(" #%d: ", i);
@@ -904,7 +904,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth)
print_kernel_version();
printk( "-------------------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
print_lock(check_source);
printk("\nbut task is already holding lock:\n");
print_lock(check_target);
@@ -1085,7 +1085,7 @@ print_bad_irq_dependency(struct task_struct *curr,
print_kernel_version();
printk( "------------------------------------------------------\n");
printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n",
- curr->comm, curr->pid,
+ curr->comm, task_pid_nr(curr),
curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT,
curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT,
curr->hardirqs_enabled,
@@ -1237,7 +1237,7 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev,
print_kernel_version();
printk( "---------------------------------------------\n");
printk("%s/%d is trying to acquire lock:\n",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
print_lock(next);
printk("\nbut task is already holding lock:\n");
print_lock(prev);
@@ -1521,7 +1521,7 @@ cache_hit:
}
static int validate_chain(struct task_struct *curr, struct lockdep_map *lock,
- struct held_lock *hlock, int chain_head, u64 chain_key)
+ struct held_lock *hlock, int chain_head, u64 chain_key)
{
/*
* Trylock needs to maintain the stack of held locks, but it
@@ -1641,7 +1641,7 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this,
usage_str[prev_bit], usage_str[new_bit]);
printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n",
- curr->comm, curr->pid,
+ curr->comm, task_pid_nr(curr),
trace_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT,
trace_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT,
trace_hardirqs_enabled(curr),
@@ -1694,7 +1694,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other,
print_kernel_version();
printk( "---------------------------------------------------------\n");
printk("%s/%d just changed the state of lock:\n",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
print_lock(this);
if (forwards)
printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass);
@@ -2487,7 +2487,7 @@ print_unlock_inbalance_bug(struct task_struct *curr, struct lockdep_map *lock,
printk( "[ BUG: bad unlock balance detected! ]\n");
printk( "-------------------------------------\n");
printk("%s/%d is trying to release lock (",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
print_lockdep_cache(lock);
printk(") at:\n");
print_ip_sym(ip);
@@ -2737,7 +2737,7 @@ print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock,
printk( "[ BUG: bad contention detected! ]\n");
printk( "---------------------------------\n");
printk("%s/%d is trying to contend lock (",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
print_lockdep_cache(lock);
printk(") at:\n");
print_ip_sym(ip);
@@ -3072,7 +3072,7 @@ print_freed_lock_bug(struct task_struct *curr, const void *mem_from,
printk( "[ BUG: held lock freed! ]\n");
printk( "-------------------------\n");
printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n",
- curr->comm, curr->pid, mem_from, mem_to-1);
+ curr->comm, task_pid_nr(curr), mem_from, mem_to-1);
print_lock(hlock);
lockdep_print_held_locks(curr);
@@ -3125,7 +3125,7 @@ static void print_held_locks_bug(struct task_struct *curr)
printk( "[ BUG: lock held at task exit time! ]\n");
printk( "-------------------------------------\n");
printk("%s/%d is exiting with locks still held!\n",
- curr->comm, curr->pid);
+ curr->comm, task_pid_nr(curr));
lockdep_print_held_locks(curr);
printk("\nstack backtrace:\n");
diff --git a/kernel/marker.c b/kernel/marker.c
new file mode 100644
index 00000000000..ccb48d9a365
--- /dev/null
+++ b/kernel/marker.c
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2007 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/jhash.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/marker.h>
+#include <linux/err.h>
+
+extern struct marker __start___markers[];
+extern struct marker __stop___markers[];
+
+/*
+ * module_mutex nests inside markers_mutex. Markers mutex protects the builtin
+ * and module markers, the hash table and deferred_sync.
+ */
+static DEFINE_MUTEX(markers_mutex);
+
+/*
+ * Marker deferred synchronization.
+ * Upon marker probe_unregister, we delay call to synchronize_sched() to
+ * accelerate mass unregistration (only when there is no more reference to a
+ * given module do we call synchronize_sched()). However, we need to make sure
+ * every critical region has ended before we re-arm a marker that has been
+ * unregistered and then registered back with a different probe data.
+ */
+static int deferred_sync;
+
+/*
+ * Marker hash table, containing the active markers.
+ * Protected by module_mutex.
+ */
+#define MARKER_HASH_BITS 6
+#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS)
+
+struct marker_entry {
+ struct hlist_node hlist;
+ char *format;
+ marker_probe_func *probe;
+ void *private;
+ int refcount; /* Number of times armed. 0 if disarmed. */
+ char name[0]; /* Contains name'\0'format'\0' */
+};
+
+static struct hlist_head marker_table[MARKER_TABLE_SIZE];
+
+/**
+ * __mark_empty_function - Empty probe callback
+ * @mdata: pointer of type const struct marker
+ * @fmt: format string
+ * @...: variable argument list
+ *
+ * Empty callback provided as a probe to the markers. By providing this to a
+ * disabled marker, we make sure the execution flow is always valid even
+ * though the function pointer change and the marker enabling are two distinct
+ * operations that modifies the execution flow of preemptible code.
+ */
+void __mark_empty_function(const struct marker *mdata, void *private,
+ const char *fmt, ...)
+{
+}
+EXPORT_SYMBOL_GPL(__mark_empty_function);
+
+/*
+ * Get marker if the marker is present in the marker hash table.
+ * Must be called with markers_mutex held.
+ * Returns NULL if not present.
+ */
+static struct marker_entry *get_marker(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct marker_entry *e;
+ u32 hash = jhash(name, strlen(name), 0);
+
+ head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name))
+ return e;
+ }
+ return NULL;
+}
+
+/*
+ * Add the marker to the marker hash table. Must be called with markers_mutex
+ * held.
+ */
+static int add_marker(const char *name, const char *format,
+ marker_probe_func *probe, void *private)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct marker_entry *e;
+ size_t name_len = strlen(name) + 1;
+ size_t format_len = 0;
+ u32 hash = jhash(name, name_len-1, 0);
+
+ if (format)
+ format_len = strlen(format) + 1;
+ head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name)) {
+ printk(KERN_NOTICE
+ "Marker %s busy, probe %p already installed\n",
+ name, e->probe);
+ return -EBUSY; /* Already there */
+ }
+ }
+ /*
+ * Using kmalloc here to allocate a variable length element. Could
+ * cause some memory fragmentation if overused.
+ */
+ e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+ GFP_KERNEL);
+ if (!e)
+ return -ENOMEM;
+ memcpy(&e->name[0], name, name_len);
+ if (format) {
+ e->format = &e->name[name_len];
+ memcpy(e->format, format, format_len);
+ trace_mark(core_marker_format, "name %s format %s",
+ e->name, e->format);
+ } else
+ e->format = NULL;
+ e->probe = probe;
+ e->private = private;
+ e->refcount = 0;
+ hlist_add_head(&e->hlist, head);
+ return 0;
+}
+
+/*
+ * Remove the marker from the marker hash table. Must be called with mutex_lock
+ * held.
+ */
+static void *remove_marker(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct marker_entry *e;
+ int found = 0;
+ size_t len = strlen(name) + 1;
+ void *private = NULL;
+ u32 hash = jhash(name, len-1, 0);
+
+ head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name)) {
+ found = 1;
+ break;
+ }
+ }
+ if (found) {
+ private = e->private;
+ hlist_del(&e->hlist);
+ kfree(e);
+ }
+ return private;
+}
+
+/*
+ * Set the mark_entry format to the format found in the element.
+ */
+static int marker_set_format(struct marker_entry **entry, const char *format)
+{
+ struct marker_entry *e;
+ size_t name_len = strlen((*entry)->name) + 1;
+ size_t format_len = strlen(format) + 1;
+
+ e = kmalloc(sizeof(struct marker_entry) + name_len + format_len,
+ GFP_KERNEL);
+ if (!e)
+ return -ENOMEM;
+ memcpy(&e->name[0], (*entry)->name, name_len);
+ e->format = &e->name[name_len];
+ memcpy(e->format, format, format_len);
+ e->probe = (*entry)->probe;
+ e->private = (*entry)->private;
+ e->refcount = (*entry)->refcount;
+ hlist_add_before(&e->hlist, &(*entry)->hlist);
+ hlist_del(&(*entry)->hlist);
+ kfree(*entry);
+ *entry = e;
+ trace_mark(core_marker_format, "name %s format %s",
+ e->name, e->format);
+ return 0;
+}
+
+/*
+ * Sets the probe callback corresponding to one marker.
+ */
+static int set_marker(struct marker_entry **entry, struct marker *elem)
+{
+ int ret;
+ WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+
+ if ((*entry)->format) {
+ if (strcmp((*entry)->format, elem->format) != 0) {
+ printk(KERN_NOTICE
+ "Format mismatch for probe %s "
+ "(%s), marker (%s)\n",
+ (*entry)->name,
+ (*entry)->format,
+ elem->format);
+ return -EPERM;
+ }
+ } else {
+ ret = marker_set_format(entry, elem->format);
+ if (ret)
+ return ret;
+ }
+ elem->call = (*entry)->probe;
+ elem->private = (*entry)->private;
+ elem->state = 1;
+ return 0;
+}
+
+/*
+ * Disable a marker and its probe callback.
+ * Note: only after a synchronize_sched() issued after setting elem->call to the
+ * empty function insures that the original callback is not used anymore. This
+ * insured by preemption disabling around the call site.
+ */
+static void disable_marker(struct marker *elem)
+{
+ elem->state = 0;
+ elem->call = __mark_empty_function;
+ /*
+ * Leave the private data and id there, because removal is racy and
+ * should be done only after a synchronize_sched(). These are never used
+ * until the next initialization anyway.
+ */
+}
+
+/**
+ * marker_update_probe_range - Update a probe range
+ * @begin: beginning of the range
+ * @end: end of the range
+ * @probe_module: module address of the probe being updated
+ * @refcount: number of references left to the given probe_module (out)
+ *
+ * Updates the probe callback corresponding to a range of markers.
+ * Must be called with markers_mutex held.
+ */
+void marker_update_probe_range(struct marker *begin,
+ struct marker *end, struct module *probe_module,
+ int *refcount)
+{
+ struct marker *iter;
+ struct marker_entry *mark_entry;
+
+ for (iter = begin; iter < end; iter++) {
+ mark_entry = get_marker(iter->name);
+ if (mark_entry && mark_entry->refcount) {
+ set_marker(&mark_entry, iter);
+ /*
+ * ignore error, continue
+ */
+ if (probe_module)
+ if (probe_module ==
+ __module_text_address((unsigned long)mark_entry->probe))
+ (*refcount)++;
+ } else {
+ disable_marker(iter);
+ }
+ }
+}
+
+/*
+ * Update probes, removing the faulty probes.
+ * Issues a synchronize_sched() when no reference to the module passed
+ * as parameter is found in the probes so the probe module can be
+ * safely unloaded from now on.
+ */
+static void marker_update_probes(struct module *probe_module)
+{
+ int refcount = 0;
+
+ mutex_lock(&markers_mutex);
+ /* Core kernel markers */
+ marker_update_probe_range(__start___markers,
+ __stop___markers, probe_module, &refcount);
+ /* Markers in modules. */
+ module_update_markers(probe_module, &refcount);
+ if (probe_module && refcount == 0) {
+ synchronize_sched();
+ deferred_sync = 0;
+ }
+ mutex_unlock(&markers_mutex);
+}
+
+/**
+ * marker_probe_register - Connect a probe to a marker
+ * @name: marker name
+ * @format: format string
+ * @probe: probe handler
+ * @private: probe private data
+ *
+ * private data must be a valid allocated memory address, or NULL.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_probe_register(const char *name, const char *format,
+ marker_probe_func *probe, void *private)
+{
+ struct marker_entry *entry;
+ int ret = 0, need_update = 0;
+
+ mutex_lock(&markers_mutex);
+ entry = get_marker(name);
+ if (entry && entry->refcount) {
+ ret = -EBUSY;
+ goto end;
+ }
+ if (deferred_sync) {
+ synchronize_sched();
+ deferred_sync = 0;
+ }
+ ret = add_marker(name, format, probe, private);
+ if (ret)
+ goto end;
+ need_update = 1;
+end:
+ mutex_unlock(&markers_mutex);
+ if (need_update)
+ marker_update_probes(NULL);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(marker_probe_register);
+
+/**
+ * marker_probe_unregister - Disconnect a probe from a marker
+ * @name: marker name
+ *
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister(const char *name)
+{
+ struct module *probe_module;
+ struct marker_entry *entry;
+ void *private;
+ int need_update = 0;
+
+ mutex_lock(&markers_mutex);
+ entry = get_marker(name);
+ if (!entry) {
+ private = ERR_PTR(-ENOENT);
+ goto end;
+ }
+ entry->refcount = 0;
+ /* In what module is the probe handler ? */
+ probe_module = __module_text_address((unsigned long)entry->probe);
+ private = remove_marker(name);
+ deferred_sync = 1;
+ need_update = 1;
+end:
+ mutex_unlock(&markers_mutex);
+ if (need_update)
+ marker_update_probes(probe_module);
+ return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister);
+
+/**
+ * marker_probe_unregister_private_data - Disconnect a probe from a marker
+ * @private: probe private data
+ *
+ * Unregister a marker by providing the registered private data.
+ * Returns the private data given to marker_probe_register, or an ERR_PTR().
+ */
+void *marker_probe_unregister_private_data(void *private)
+{
+ struct module *probe_module;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct marker_entry *entry;
+ int found = 0;
+ unsigned int i;
+ int need_update = 0;
+
+ mutex_lock(&markers_mutex);
+ for (i = 0; i < MARKER_TABLE_SIZE; i++) {
+ head = &marker_table[i];
+ hlist_for_each_entry(entry, node, head, hlist) {
+ if (entry->private == private) {
+ found = 1;
+ goto iter_end;
+ }
+ }
+ }
+iter_end:
+ if (!found) {
+ private = ERR_PTR(-ENOENT);
+ goto end;
+ }
+ entry->refcount = 0;
+ /* In what module is the probe handler ? */
+ probe_module = __module_text_address((unsigned long)entry->probe);
+ private = remove_marker(entry->name);
+ deferred_sync = 1;
+ need_update = 1;
+end:
+ mutex_unlock(&markers_mutex);
+ if (need_update)
+ marker_update_probes(probe_module);
+ return private;
+}
+EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data);
+
+/**
+ * marker_arm - Arm a marker
+ * @name: marker name
+ *
+ * Activate a marker. It keeps a reference count of the number of
+ * arming/disarming done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_arm(const char *name)
+{
+ struct marker_entry *entry;
+ int ret = 0, need_update = 0;
+
+ mutex_lock(&markers_mutex);
+ entry = get_marker(name);
+ if (!entry) {
+ ret = -ENOENT;
+ goto end;
+ }
+ /*
+ * Only need to update probes when refcount passes from 0 to 1.
+ */
+ if (entry->refcount++)
+ goto end;
+ need_update = 1;
+end:
+ mutex_unlock(&markers_mutex);
+ if (need_update)
+ marker_update_probes(NULL);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(marker_arm);
+
+/**
+ * marker_disarm - Disarm a marker
+ * @name: marker name
+ *
+ * Disarm a marker. It keeps a reference count of the number of arming/disarming
+ * done.
+ * Returns 0 if ok, error value on error.
+ */
+int marker_disarm(const char *name)
+{
+ struct marker_entry *entry;
+ int ret = 0, need_update = 0;
+
+ mutex_lock(&markers_mutex);
+ entry = get_marker(name);
+ if (!entry) {
+ ret = -ENOENT;
+ goto end;
+ }
+ /*
+ * Only permit decrement refcount if higher than 0.
+ * Do probe update only on 1 -> 0 transition.
+ */
+ if (entry->refcount) {
+ if (--entry->refcount)
+ goto end;
+ } else {
+ ret = -EPERM;
+ goto end;
+ }
+ need_update = 1;
+end:
+ mutex_unlock(&markers_mutex);
+ if (need_update)
+ marker_update_probes(NULL);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(marker_disarm);
+
+/**
+ * marker_get_private_data - Get a marker's probe private data
+ * @name: marker name
+ *
+ * Returns the private data pointer, or an ERR_PTR.
+ * The private data pointer should _only_ be dereferenced if the caller is the
+ * owner of the data, or its content could vanish. This is mostly used to
+ * confirm that a caller is the owner of a registered probe.
+ */
+void *marker_get_private_data(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct marker_entry *e;
+ size_t name_len = strlen(name) + 1;
+ u32 hash = jhash(name, name_len-1, 0);
+ int found = 0;
+
+ head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name)) {
+ found = 1;
+ return e->private;
+ }
+ }
+ return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL_GPL(marker_get_private_data);
diff --git a/kernel/module.c b/kernel/module.c
index 7734595bd32..3202c995007 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1673,6 +1673,8 @@ static struct module *load_module(void __user *umod,
unsigned int unusedcrcindex;
unsigned int unusedgplindex;
unsigned int unusedgplcrcindex;
+ unsigned int markersindex;
+ unsigned int markersstringsindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -1939,6 +1941,9 @@ static struct module *load_module(void __user *umod,
add_taint_module(mod, TAINT_FORCED_MODULE);
}
#endif
+ markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
+ markersstringsindex = find_sec(hdr, sechdrs, secstrings,
+ "__markers_strings");
/* Now do relocations. */
for (i = 1; i < hdr->e_shnum; i++) {
@@ -1961,6 +1966,11 @@ static struct module *load_module(void __user *umod,
if (err < 0)
goto cleanup;
}
+#ifdef CONFIG_MARKERS
+ mod->markers = (void *)sechdrs[markersindex].sh_addr;
+ mod->num_markers =
+ sechdrs[markersindex].sh_size / sizeof(*mod->markers);
+#endif
/* Find duplicate symbols */
err = verify_export_symbols(mod);
@@ -1979,6 +1989,11 @@ static struct module *load_module(void __user *umod,
add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
+#ifdef CONFIG_MARKERS
+ if (!mod->taints)
+ marker_update_probe_range(mod->markers,
+ mod->markers + mod->num_markers, NULL, NULL);
+#endif
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
@@ -2570,3 +2585,18 @@ EXPORT_SYMBOL(module_remove_driver);
void struct_module(struct module *mod) { return; }
EXPORT_SYMBOL(struct_module);
#endif
+
+#ifdef CONFIG_MARKERS
+void module_update_markers(struct module *probe_module, int *refcount)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list)
+ if (!mod->taints)
+ marker_update_probe_range(mod->markers,
+ mod->markers + mod->num_markers,
+ probe_module, refcount);
+ mutex_unlock(&module_mutex);
+}
+#endif
diff --git a/kernel/notifier.c b/kernel/notifier.c
new file mode 100644
index 00000000000..4253f472f06
--- /dev/null
+++ b/kernel/notifier.c
@@ -0,0 +1,539 @@
+#include <linux/kdebug.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/rcupdate.h>
+#include <linux/vmalloc.h>
+
+/*
+ * Notifier list for kernel code which wants to be called
+ * at shutdown. This is used to stop any idling DMA operations
+ * and the like.
+ */
+BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
+
+/*
+ * Notifier chain core routines. The exported routines below
+ * are layered on top of these, with appropriate locking added.
+ */
+
+static int notifier_chain_register(struct notifier_block **nl,
+ struct notifier_block *n)
+{
+ while ((*nl) != NULL) {
+ if (n->priority > (*nl)->priority)
+ break;
+ nl = &((*nl)->next);
+ }
+ n->next = *nl;
+ rcu_assign_pointer(*nl, n);
+ return 0;
+}
+
+static int notifier_chain_unregister(struct notifier_block **nl,
+ struct notifier_block *n)
+{
+ while ((*nl) != NULL) {
+ if ((*nl) == n) {
+ rcu_assign_pointer(*nl, n->next);
+ return 0;
+ }
+ nl = &((*nl)->next);
+ }
+ return -ENOENT;
+}
+
+/**
+ * notifier_call_chain - Informs the registered notifiers about an event.
+ * @nl: Pointer to head of the blocking notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: Number of notifier functions to be called. Don't care
+ * value of this parameter is -1.
+ * @nr_calls: Records the number of notifications sent. Don't care
+ * value of this field is NULL.
+ * @returns: notifier_call_chain returns the value returned by the
+ * last notifier function called.
+ */
+static int __kprobes notifier_call_chain(struct notifier_block **nl,
+ unsigned long val, void *v,
+ int nr_to_call, int *nr_calls)
+{
+ int ret = NOTIFY_DONE;
+ struct notifier_block *nb, *next_nb;
+
+ nb = rcu_dereference(*nl);
+
+ while (nb && nr_to_call) {
+ next_nb = rcu_dereference(nb->next);
+ ret = nb->notifier_call(nb, val, v);
+
+ if (nr_calls)
+ (*nr_calls)++;
+
+ if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
+ break;
+ nb = next_nb;
+ nr_to_call--;
+ }
+ return ret;
+}
+
+/*
+ * Atomic notifier chain routines. Registration and unregistration
+ * use a spinlock, and call_chain is synchronized by RCU (no locks).
+ */
+
+/**
+ * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
+ * @nh: Pointer to head of the atomic notifier chain
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to an atomic notifier chain.
+ *
+ * Currently always returns zero.
+ */
+int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
+ struct notifier_block *n)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&nh->lock, flags);
+ ret = notifier_chain_register(&nh->head, n);
+ spin_unlock_irqrestore(&nh->lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
+
+/**
+ * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
+ * @nh: Pointer to head of the atomic notifier chain
+ * @n: Entry to remove from notifier chain
+ *
+ * Removes a notifier from an atomic notifier chain.
+ *
+ * Returns zero on success or %-ENOENT on failure.
+ */
+int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
+ struct notifier_block *n)
+{
+ unsigned long flags;
+ int ret;
+
+ spin_lock_irqsave(&nh->lock, flags);
+ ret = notifier_chain_unregister(&nh->head, n);
+ spin_unlock_irqrestore(&nh->lock, flags);
+ synchronize_rcu();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
+
+/**
+ * __atomic_notifier_call_chain - Call functions in an atomic notifier chain
+ * @nh: Pointer to head of the atomic notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: See the comment for notifier_call_chain.
+ * @nr_calls: See the comment for notifier_call_chain.
+ *
+ * Calls each function in a notifier chain in turn. The functions
+ * run in an atomic context, so they must not block.
+ * This routine uses RCU to synchronize with changes to the chain.
+ *
+ * If the return value of the notifier can be and'ed
+ * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise the return value is the return value
+ * of the last notifier function called.
+ */
+int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+ unsigned long val, void *v,
+ int nr_to_call, int *nr_calls)
+{
+ int ret;
+
+ rcu_read_lock();
+ ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
+
+int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
+ unsigned long val, void *v)
+{
+ return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
+
+/*
+ * Blocking notifier chain routines. All access to the chain is
+ * synchronized by an rwsem.
+ */
+
+/**
+ * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
+ * @nh: Pointer to head of the blocking notifier chain
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to a blocking notifier chain.
+ * Must be called in process context.
+ *
+ * Currently always returns zero.
+ */
+int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
+ struct notifier_block *n)
+{
+ int ret;
+
+ /*
+ * This code gets used during boot-up, when task switching is
+ * not yet working and interrupts must remain disabled. At
+ * such times we must not call down_write().
+ */
+ if (unlikely(system_state == SYSTEM_BOOTING))
+ return notifier_chain_register(&nh->head, n);
+
+ down_write(&nh->rwsem);
+ ret = notifier_chain_register(&nh->head, n);
+ up_write(&nh->rwsem);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
+
+/**
+ * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
+ * @nh: Pointer to head of the blocking notifier chain
+ * @n: Entry to remove from notifier chain
+ *
+ * Removes a notifier from a blocking notifier chain.
+ * Must be called from process context.
+ *
+ * Returns zero on success or %-ENOENT on failure.
+ */
+int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
+ struct notifier_block *n)
+{
+ int ret;
+
+ /*
+ * This code gets used during boot-up, when task switching is
+ * not yet working and interrupts must remain disabled. At
+ * such times we must not call down_write().
+ */
+ if (unlikely(system_state == SYSTEM_BOOTING))
+ return notifier_chain_unregister(&nh->head, n);
+
+ down_write(&nh->rwsem);
+ ret = notifier_chain_unregister(&nh->head, n);
+ up_write(&nh->rwsem);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
+
+/**
+ * __blocking_notifier_call_chain - Call functions in a blocking notifier chain
+ * @nh: Pointer to head of the blocking notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: See comment for notifier_call_chain.
+ * @nr_calls: See comment for notifier_call_chain.
+ *
+ * Calls each function in a notifier chain in turn. The functions
+ * run in a process context, so they are allowed to block.
+ *
+ * If the return value of the notifier can be and'ed
+ * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise the return value is the return value
+ * of the last notifier function called.
+ */
+int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+ unsigned long val, void *v,
+ int nr_to_call, int *nr_calls)
+{
+ int ret = NOTIFY_DONE;
+
+ /*
+ * We check the head outside the lock, but if this access is
+ * racy then it does not matter what the result of the test
+ * is, we re-check the list after having taken the lock anyway:
+ */
+ if (rcu_dereference(nh->head)) {
+ down_read(&nh->rwsem);
+ ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
+ nr_calls);
+ up_read(&nh->rwsem);
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
+
+int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
+ unsigned long val, void *v)
+{
+ return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
+
+/*
+ * Raw notifier chain routines. There is no protection;
+ * the caller must provide it. Use at your own risk!
+ */
+
+/**
+ * raw_notifier_chain_register - Add notifier to a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to a raw notifier chain.
+ * All locking must be provided by the caller.
+ *
+ * Currently always returns zero.
+ */
+int raw_notifier_chain_register(struct raw_notifier_head *nh,
+ struct notifier_block *n)
+{
+ return notifier_chain_register(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
+
+/**
+ * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @n: Entry to remove from notifier chain
+ *
+ * Removes a notifier from a raw notifier chain.
+ * All locking must be provided by the caller.
+ *
+ * Returns zero on success or %-ENOENT on failure.
+ */
+int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
+ struct notifier_block *n)
+{
+ return notifier_chain_unregister(&nh->head, n);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
+
+/**
+ * __raw_notifier_call_chain - Call functions in a raw notifier chain
+ * @nh: Pointer to head of the raw notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: See comment for notifier_call_chain.
+ * @nr_calls: See comment for notifier_call_chain
+ *
+ * Calls each function in a notifier chain in turn. The functions
+ * run in an undefined context.
+ * All locking must be provided by the caller.
+ *
+ * If the return value of the notifier can be and'ed
+ * with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise the return value is the return value
+ * of the last notifier function called.
+ */
+int __raw_notifier_call_chain(struct raw_notifier_head *nh,
+ unsigned long val, void *v,
+ int nr_to_call, int *nr_calls)
+{
+ return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+}
+EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
+
+int raw_notifier_call_chain(struct raw_notifier_head *nh,
+ unsigned long val, void *v)
+{
+ return __raw_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
+
+/*
+ * SRCU notifier chain routines. Registration and unregistration
+ * use a mutex, and call_chain is synchronized by SRCU (no locks).
+ */
+
+/**
+ * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
+ * @nh: Pointer to head of the SRCU notifier chain
+ * @n: New entry in notifier chain
+ *
+ * Adds a notifier to an SRCU notifier chain.
+ * Must be called in process context.
+ *
+ * Currently always returns zero.
+ */
+int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
+ struct notifier_block *n)
+{
+ int ret;
+
+ /*
+ * This code gets used during boot-up, when task switching is
+ * not yet working and interrupts must remain disabled. At
+ * such times we must not call mutex_lock().
+ */
+ if (unlikely(system_state == SYSTEM_BOOTING))
+ return notifier_chain_register(&nh->head, n);
+
+ mutex_lock(&nh->mutex);
+ ret = notifier_chain_register(&nh->head, n);
+ mutex_unlock(&nh->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
+
+/**
+ * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
+ * @nh: Pointer to head of the SRCU notifier chain
+ * @n: Entry to remove from notifier chain
+ *
+ * Removes a notifier from an SRCU notifier chain.
+ * Must be called from process context.
+ *
+ * Returns zero on success or %-ENOENT on failure.
+ */
+int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
+ struct notifier_block *n)
+{
+ int ret;
+
+ /*
+ * This code gets used during boot-up, when task switching is
+ * not yet working and interrupts must remain disabled. At
+ * such times we must not call mutex_lock().
+ */
+ if (unlikely(system_state == SYSTEM_BOOTING))
+ return notifier_chain_unregister(&nh->head, n);
+
+ mutex_lock(&nh->mutex);
+ ret = notifier_chain_unregister(&nh->head, n);
+ mutex_unlock(&nh->mutex);
+ synchronize_srcu(&nh->srcu);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
+
+/**
+ * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
+ * @nh: Pointer to head of the SRCU notifier chain
+ * @val: Value passed unmodified to notifier function
+ * @v: Pointer passed unmodified to notifier function
+ * @nr_to_call: See comment for notifier_call_chain.
+ * @nr_calls: See comment for notifier_call_chain
+ *
+ * Calls each function in a notifier chain in turn. The functions
+ * run in a process context, so they are allowed to block.
+ *
+ * If the return value of the notifier can be and'ed
+ * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
+ * will return immediately, with the return value of
+ * the notifier function which halted execution.
+ * Otherwise the return value is the return value
+ * of the last notifier function called.
+ */
+int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+ unsigned long val, void *v,
+ int nr_to_call, int *nr_calls)
+{
+ int ret;
+ int idx;
+
+ idx = srcu_read_lock(&nh->srcu);
+ ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
+ srcu_read_unlock(&nh->srcu, idx);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
+
+int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
+ unsigned long val, void *v)
+{
+ return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
+}
+EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
+
+/**
+ * srcu_init_notifier_head - Initialize an SRCU notifier head
+ * @nh: Pointer to head of the srcu notifier chain
+ *
+ * Unlike other sorts of notifier heads, SRCU notifier heads require
+ * dynamic initialization. Be sure to call this routine before
+ * calling any of the other SRCU notifier routines for this head.
+ *
+ * If an SRCU notifier head is deallocated, it must first be cleaned
+ * up by calling srcu_cleanup_notifier_head(). Otherwise the head's
+ * per-cpu data (used by the SRCU mechanism) will leak.
+ */
+void srcu_init_notifier_head(struct srcu_notifier_head *nh)
+{
+ mutex_init(&nh->mutex);
+ if (init_srcu_struct(&nh->srcu) < 0)
+ BUG();
+ nh->head = NULL;
+}
+EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
+
+/**
+ * register_reboot_notifier - Register function to be called at reboot time
+ * @nb: Info about notifier function to be called
+ *
+ * Registers a function with the list of functions
+ * to be called at reboot time.
+ *
+ * Currently always returns zero, as blocking_notifier_chain_register()
+ * always returns zero.
+ */
+int register_reboot_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(register_reboot_notifier);
+
+/**
+ * unregister_reboot_notifier - Unregister previously registered reboot notifier
+ * @nb: Hook to be unregistered
+ *
+ * Unregisters a previously registered reboot
+ * notifier function.
+ *
+ * Returns zero on success, or %-ENOENT on failure.
+ */
+int unregister_reboot_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
+}
+EXPORT_SYMBOL(unregister_reboot_notifier);
+
+static ATOMIC_NOTIFIER_HEAD(die_chain);
+
+int notify_die(enum die_val val, const char *str,
+ struct pt_regs *regs, long err, int trap, int sig)
+{
+ struct die_args args = {
+ .regs = regs,
+ .str = str,
+ .err = err,
+ .trapnr = trap,
+ .signr = sig,
+
+ };
+ return atomic_notifier_call_chain(&die_chain, val, &args);
+}
+
+int register_die_notifier(struct notifier_block *nb)
+{
+ vmalloc_sync_all();
+ return atomic_notifier_chain_register(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(register_die_notifier);
+
+int unregister_die_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&die_chain, nb);
+}
+EXPORT_SYMBOL_GPL(unregister_die_notifier);
diff --git a/kernel/ns_cgroup.c b/kernel/ns_cgroup.c
new file mode 100644
index 00000000000..aead4d69f62
--- /dev/null
+++ b/kernel/ns_cgroup.c
@@ -0,0 +1,100 @@
+/*
+ * ns_cgroup.c - namespace cgroup subsystem
+ *
+ * Copyright 2006, 2007 IBM Corp
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+
+struct ns_cgroup {
+ struct cgroup_subsys_state css;
+ spinlock_t lock;
+};
+
+struct cgroup_subsys ns_subsys;
+
+static inline struct ns_cgroup *cgroup_to_ns(
+ struct cgroup *cgroup)
+{
+ return container_of(cgroup_subsys_state(cgroup, ns_subsys_id),
+ struct ns_cgroup, css);
+}
+
+int ns_cgroup_clone(struct task_struct *task)
+{
+ return cgroup_clone(task, &ns_subsys);
+}
+
+/*
+ * Rules:
+ * 1. you can only enter a cgroup which is a child of your current
+ * cgroup
+ * 2. you can only place another process into a cgroup if
+ * a. you have CAP_SYS_ADMIN
+ * b. your cgroup is an ancestor of task's destination cgroup
+ * (hence either you are in the same cgroup as task, or in an
+ * ancestor cgroup thereof)
+ */
+static int ns_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *new_cgroup, struct task_struct *task)
+{
+ struct cgroup *orig;
+
+ if (current != task) {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!cgroup_is_descendant(new_cgroup))
+ return -EPERM;
+ }
+
+ if (atomic_read(&new_cgroup->count) != 0)
+ return -EPERM;
+
+ orig = task_cgroup(task, ns_subsys_id);
+ if (orig && orig != new_cgroup->parent)
+ return -EPERM;
+
+ return 0;
+}
+
+/*
+ * Rules: you can only create a cgroup if
+ * 1. you are capable(CAP_SYS_ADMIN)
+ * 2. the target cgroup is a descendant of your own cgroup
+ */
+static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss,
+ struct cgroup *cgroup)
+{
+ struct ns_cgroup *ns_cgroup;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return ERR_PTR(-EPERM);
+ if (!cgroup_is_descendant(cgroup))
+ return ERR_PTR(-EPERM);
+
+ ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL);
+ if (!ns_cgroup)
+ return ERR_PTR(-ENOMEM);
+ spin_lock_init(&ns_cgroup->lock);
+ return &ns_cgroup->css;
+}
+
+static void ns_destroy(struct cgroup_subsys *ss,
+ struct cgroup *cgroup)
+{
+ struct ns_cgroup *ns_cgroup;
+
+ ns_cgroup = cgroup_to_ns(cgroup);
+ kfree(ns_cgroup);
+}
+
+struct cgroup_subsys ns_subsys = {
+ .name = "ns",
+ .can_attach = ns_can_attach,
+ .create = ns_create,
+ .destroy = ns_destroy,
+ .subsys_id = ns_subsys_id,
+};
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c
index 049e7c0ac56..79f871bc0ef 100644
--- a/kernel/nsproxy.c
+++ b/kernel/nsproxy.c
@@ -26,19 +26,6 @@ static struct kmem_cache *nsproxy_cachep;
struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy);
-static inline void get_nsproxy(struct nsproxy *ns)
-{
- atomic_inc(&ns->count);
-}
-
-void get_task_namespaces(struct task_struct *tsk)
-{
- struct nsproxy *ns = tsk->nsproxy;
- if (ns) {
- get_nsproxy(ns);
- }
-}
-
/*
* creates a copy of "orig" with refcount 1.
*/
@@ -87,7 +74,7 @@ static struct nsproxy *create_new_namespaces(unsigned long flags,
goto out_ipc;
}
- new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns);
+ new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk));
if (IS_ERR(new_nsp->pid_ns)) {
err = PTR_ERR(new_nsp->pid_ns);
goto out_pid;
@@ -142,7 +129,8 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
get_nsproxy(old_ns);
- if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET)))
+ if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC |
+ CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET)))
return 0;
if (!capable(CAP_SYS_ADMIN)) {
@@ -156,7 +144,14 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk)
goto out;
}
+ err = ns_cgroup_clone(tsk);
+ if (err) {
+ put_nsproxy(new_ns);
+ goto out;
+ }
+
tsk->nsproxy = new_ns;
+
out:
put_nsproxy(old_ns);
return err;
@@ -196,11 +191,46 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags,
*new_nsp = create_new_namespaces(unshare_flags, current,
new_fs ? new_fs : current->fs);
- if (IS_ERR(*new_nsp))
+ if (IS_ERR(*new_nsp)) {
err = PTR_ERR(*new_nsp);
+ goto out;
+ }
+
+ err = ns_cgroup_clone(current);
+ if (err)
+ put_nsproxy(*new_nsp);
+
+out:
return err;
}
+void switch_task_namespaces(struct task_struct *p, struct nsproxy *new)
+{
+ struct nsproxy *ns;
+
+ might_sleep();
+
+ ns = p->nsproxy;
+
+ rcu_assign_pointer(p->nsproxy, new);
+
+ if (ns && atomic_dec_and_test(&ns->count)) {
+ /*
+ * wait for others to get what they want from this nsproxy.
+ *
+ * cannot release this nsproxy via the call_rcu() since
+ * put_mnt_ns() will want to sleep
+ */
+ synchronize_rcu();
+ free_nsproxy(ns);
+ }
+}
+
+void exit_task_namespaces(struct task_struct *p)
+{
+ switch_task_namespaces(p, NULL);
+}
+
static int __init nsproxy_cache_init(void)
{
nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC);
diff --git a/kernel/panic.c b/kernel/panic.c
index 3886bd8230f..6f6e03e9159 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -148,7 +148,7 @@ EXPORT_SYMBOL(panic);
* 'F' - Module has been forcibly loaded.
* 'S' - SMP with CPUs not designed for SMP.
* 'R' - User forced a module unload.
- * 'M' - Machine had a machine check experience.
+ * 'M' - System experienced a machine check exception.
* 'B' - System has hit bad_page.
* 'U' - Userspace-defined naughtiness.
*
diff --git a/kernel/pid.c b/kernel/pid.c
index c6e3f9ffff8..d1db36b9467 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -18,6 +18,12 @@
* allocation scenario when all but one out of 1 million PIDs possible are
* allocated already: the scanning of 32 list entries and at most PAGE_SIZE
* bytes. The typical fastpath is a single successful setbit. Freeing is O(1).
+ *
+ * Pid namespaces:
+ * (C) 2007 Pavel Emelyanov <xemul@openvz.org>, OpenVZ, SWsoft Inc.
+ * (C) 2007 Sukadev Bhattiprolu <sukadev@us.ibm.com>, IBM
+ * Many thanks to Oleg Nesterov for comments and help
+ *
*/
#include <linux/mm.h>
@@ -28,12 +34,14 @@
#include <linux/hash.h>
#include <linux/pid_namespace.h>
#include <linux/init_task.h>
+#include <linux/syscalls.h>
-#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
+#define pid_hashfn(nr, ns) \
+ hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
static struct hlist_head *pid_hash;
static int pidhash_shift;
-static struct kmem_cache *pid_cachep;
struct pid init_struct_pid = INIT_STRUCT_PID;
+static struct kmem_cache *pid_ns_cachep;
int pid_max = PID_MAX_DEFAULT;
@@ -68,8 +76,25 @@ struct pid_namespace init_pid_ns = {
[ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL }
},
.last_pid = 0,
- .child_reaper = &init_task
+ .level = 0,
+ .child_reaper = &init_task,
};
+EXPORT_SYMBOL_GPL(init_pid_ns);
+
+int is_container_init(struct task_struct *tsk)
+{
+ int ret = 0;
+ struct pid *pid;
+
+ rcu_read_lock();
+ pid = task_pid(tsk);
+ if (pid != NULL && pid->numbers[pid->level].nr == 1)
+ ret = 1;
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(is_container_init);
/*
* Note: disable interrupts while the pidmap_lock is held as an
@@ -176,11 +201,17 @@ static int next_pidmap(struct pid_namespace *pid_ns, int last)
fastcall void put_pid(struct pid *pid)
{
+ struct pid_namespace *ns;
+
if (!pid)
return;
+
+ ns = pid->numbers[pid->level].ns;
if ((atomic_read(&pid->count) == 1) ||
- atomic_dec_and_test(&pid->count))
- kmem_cache_free(pid_cachep, pid);
+ atomic_dec_and_test(&pid->count)) {
+ kmem_cache_free(ns->pid_cachep, pid);
+ put_pid_ns(ns);
+ }
}
EXPORT_SYMBOL_GPL(put_pid);
@@ -193,60 +224,94 @@ static void delayed_put_pid(struct rcu_head *rhp)
fastcall void free_pid(struct pid *pid)
{
/* We can be called with write_lock_irq(&tasklist_lock) held */
+ int i;
unsigned long flags;
spin_lock_irqsave(&pidmap_lock, flags);
- hlist_del_rcu(&pid->pid_chain);
+ for (i = 0; i <= pid->level; i++)
+ hlist_del_rcu(&pid->numbers[i].pid_chain);
spin_unlock_irqrestore(&pidmap_lock, flags);
- free_pidmap(&init_pid_ns, pid->nr);
+ for (i = 0; i <= pid->level; i++)
+ free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
call_rcu(&pid->rcu, delayed_put_pid);
}
-struct pid *alloc_pid(void)
+struct pid *alloc_pid(struct pid_namespace *ns)
{
struct pid *pid;
enum pid_type type;
- int nr = -1;
+ int i, nr;
+ struct pid_namespace *tmp;
+ struct upid *upid;
- pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL);
+ pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
if (!pid)
goto out;
- nr = alloc_pidmap(current->nsproxy->pid_ns);
- if (nr < 0)
- goto out_free;
+ tmp = ns;
+ for (i = ns->level; i >= 0; i--) {
+ nr = alloc_pidmap(tmp);
+ if (nr < 0)
+ goto out_free;
+
+ pid->numbers[i].nr = nr;
+ pid->numbers[i].ns = tmp;
+ tmp = tmp->parent;
+ }
+ get_pid_ns(ns);
+ pid->level = ns->level;
atomic_set(&pid->count, 1);
- pid->nr = nr;
for (type = 0; type < PIDTYPE_MAX; ++type)
INIT_HLIST_HEAD(&pid->tasks[type]);
spin_lock_irq(&pidmap_lock);
- hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]);
+ for (i = ns->level; i >= 0; i--) {
+ upid = &pid->numbers[i];
+ hlist_add_head_rcu(&upid->pid_chain,
+ &pid_hash[pid_hashfn(upid->nr, upid->ns)]);
+ }
spin_unlock_irq(&pidmap_lock);
out:
return pid;
out_free:
- kmem_cache_free(pid_cachep, pid);
+ for (i++; i <= ns->level; i++)
+ free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr);
+
+ kmem_cache_free(ns->pid_cachep, pid);
pid = NULL;
goto out;
}
-struct pid * fastcall find_pid(int nr)
+struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
{
struct hlist_node *elem;
- struct pid *pid;
+ struct upid *pnr;
+
+ hlist_for_each_entry_rcu(pnr, elem,
+ &pid_hash[pid_hashfn(nr, ns)], pid_chain)
+ if (pnr->nr == nr && pnr->ns == ns)
+ return container_of(pnr, struct pid,
+ numbers[ns->level]);
- hlist_for_each_entry_rcu(pid, elem,
- &pid_hash[pid_hashfn(nr)], pid_chain) {
- if (pid->nr == nr)
- return pid;
- }
return NULL;
}
+EXPORT_SYMBOL_GPL(find_pid_ns);
+
+struct pid *find_vpid(int nr)
+{
+ return find_pid_ns(nr, current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL_GPL(find_vpid);
+
+struct pid *find_pid(int nr)
+{
+ return find_pid_ns(nr, &init_pid_ns);
+}
EXPORT_SYMBOL_GPL(find_pid);
/*
@@ -307,12 +372,32 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
/*
* Must be called under rcu_read_lock() or with tasklist_lock read-held.
*/
-struct task_struct *find_task_by_pid_type(int type, int nr)
+struct task_struct *find_task_by_pid_type_ns(int type, int nr,
+ struct pid_namespace *ns)
{
- return pid_task(find_pid(nr), type);
+ return pid_task(find_pid_ns(nr, ns), type);
}
-EXPORT_SYMBOL(find_task_by_pid_type);
+EXPORT_SYMBOL(find_task_by_pid_type_ns);
+
+struct task_struct *find_task_by_pid(pid_t nr)
+{
+ return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_pid);
+
+struct task_struct *find_task_by_vpid(pid_t vnr)
+{
+ return find_task_by_pid_type_ns(PIDTYPE_PID, vnr,
+ current->nsproxy->pid_ns);
+}
+EXPORT_SYMBOL(find_task_by_vpid);
+
+struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns)
+{
+ return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns);
+}
+EXPORT_SYMBOL(find_task_by_pid_ns);
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
{
@@ -339,45 +424,239 @@ struct pid *find_get_pid(pid_t nr)
struct pid *pid;
rcu_read_lock();
- pid = get_pid(find_pid(nr));
+ pid = get_pid(find_vpid(nr));
rcu_read_unlock();
return pid;
}
+pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
+{
+ struct upid *upid;
+ pid_t nr = 0;
+
+ if (pid && ns->level <= pid->level) {
+ upid = &pid->numbers[ns->level];
+ if (upid->ns == ns)
+ nr = upid->nr;
+ }
+ return nr;
+}
+
+pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return pid_nr_ns(task_pid(tsk), ns);
+}
+EXPORT_SYMBOL(task_pid_nr_ns);
+
+pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return pid_nr_ns(task_tgid(tsk), ns);
+}
+EXPORT_SYMBOL(task_tgid_nr_ns);
+
+pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return pid_nr_ns(task_pgrp(tsk), ns);
+}
+EXPORT_SYMBOL(task_pgrp_nr_ns);
+
+pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return pid_nr_ns(task_session(tsk), ns);
+}
+EXPORT_SYMBOL(task_session_nr_ns);
+
/*
* Used by proc to find the first pid that is greater then or equal to nr.
*
* If there is a pid at nr this function is exactly the same as find_pid.
*/
-struct pid *find_ge_pid(int nr)
+struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
{
struct pid *pid;
do {
- pid = find_pid(nr);
+ pid = find_pid_ns(nr, ns);
if (pid)
break;
- nr = next_pidmap(current->nsproxy->pid_ns, nr);
+ nr = next_pidmap(ns, nr);
} while (nr > 0);
return pid;
}
EXPORT_SYMBOL_GPL(find_get_pid);
+struct pid_cache {
+ int nr_ids;
+ char name[16];
+ struct kmem_cache *cachep;
+ struct list_head list;
+};
+
+static LIST_HEAD(pid_caches_lh);
+static DEFINE_MUTEX(pid_caches_mutex);
+
+/*
+ * creates the kmem cache to allocate pids from.
+ * @nr_ids: the number of numerical ids this pid will have to carry
+ */
+
+static struct kmem_cache *create_pid_cachep(int nr_ids)
+{
+ struct pid_cache *pcache;
+ struct kmem_cache *cachep;
+
+ mutex_lock(&pid_caches_mutex);
+ list_for_each_entry (pcache, &pid_caches_lh, list)
+ if (pcache->nr_ids == nr_ids)
+ goto out;
+
+ pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL);
+ if (pcache == NULL)
+ goto err_alloc;
+
+ snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids);
+ cachep = kmem_cache_create(pcache->name,
+ sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid),
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (cachep == NULL)
+ goto err_cachep;
+
+ pcache->nr_ids = nr_ids;
+ pcache->cachep = cachep;
+ list_add(&pcache->list, &pid_caches_lh);
+out:
+ mutex_unlock(&pid_caches_mutex);
+ return pcache->cachep;
+
+err_cachep:
+ kfree(pcache);
+err_alloc:
+ mutex_unlock(&pid_caches_mutex);
+ return NULL;
+}
+
+static struct pid_namespace *create_pid_namespace(int level)
+{
+ struct pid_namespace *ns;
+ int i;
+
+ ns = kmem_cache_alloc(pid_ns_cachep, GFP_KERNEL);
+ if (ns == NULL)
+ goto out;
+
+ ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!ns->pidmap[0].page)
+ goto out_free;
+
+ ns->pid_cachep = create_pid_cachep(level + 1);
+ if (ns->pid_cachep == NULL)
+ goto out_free_map;
+
+ kref_init(&ns->kref);
+ ns->last_pid = 0;
+ ns->child_reaper = NULL;
+ ns->level = level;
+
+ set_bit(0, ns->pidmap[0].page);
+ atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1);
+
+ for (i = 1; i < PIDMAP_ENTRIES; i++) {
+ ns->pidmap[i].page = 0;
+ atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE);
+ }
+
+ return ns;
+
+out_free_map:
+ kfree(ns->pidmap[0].page);
+out_free:
+ kmem_cache_free(pid_ns_cachep, ns);
+out:
+ return ERR_PTR(-ENOMEM);
+}
+
+static void destroy_pid_namespace(struct pid_namespace *ns)
+{
+ int i;
+
+ for (i = 0; i < PIDMAP_ENTRIES; i++)
+ kfree(ns->pidmap[i].page);
+ kmem_cache_free(pid_ns_cachep, ns);
+}
+
struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns)
{
+ struct pid_namespace *new_ns;
+
BUG_ON(!old_ns);
- get_pid_ns(old_ns);
- return old_ns;
+ new_ns = get_pid_ns(old_ns);
+ if (!(flags & CLONE_NEWPID))
+ goto out;
+
+ new_ns = ERR_PTR(-EINVAL);
+ if (flags & CLONE_THREAD)
+ goto out_put;
+
+ new_ns = create_pid_namespace(old_ns->level + 1);
+ if (!IS_ERR(new_ns))
+ new_ns->parent = get_pid_ns(old_ns);
+
+out_put:
+ put_pid_ns(old_ns);
+out:
+ return new_ns;
}
void free_pid_ns(struct kref *kref)
{
- struct pid_namespace *ns;
+ struct pid_namespace *ns, *parent;
ns = container_of(kref, struct pid_namespace, kref);
- kfree(ns);
+
+ parent = ns->parent;
+ destroy_pid_namespace(ns);
+
+ if (parent != NULL)
+ put_pid_ns(parent);
+}
+
+void zap_pid_ns_processes(struct pid_namespace *pid_ns)
+{
+ int nr;
+ int rc;
+
+ /*
+ * The last thread in the cgroup-init thread group is terminating.
+ * Find remaining pid_ts in the namespace, signal and wait for them
+ * to exit.
+ *
+ * Note: This signals each threads in the namespace - even those that
+ * belong to the same thread group, To avoid this, we would have
+ * to walk the entire tasklist looking a processes in this
+ * namespace, but that could be unnecessarily expensive if the
+ * pid namespace has just a few processes. Or we need to
+ * maintain a tasklist for each pid namespace.
+ *
+ */
+ read_lock(&tasklist_lock);
+ nr = next_pidmap(pid_ns, 1);
+ while (nr > 0) {
+ kill_proc_info(SIGKILL, SEND_SIG_PRIV, nr);
+ nr = next_pidmap(pid_ns, nr);
+ }
+ read_unlock(&tasklist_lock);
+
+ do {
+ clear_thread_flag(TIF_SIGPENDING);
+ rc = sys_wait4(-1, NULL, __WALL, NULL);
+ } while (rc != -ECHILD);
+
+
+ /* Child reaper for the pid namespace is going away */
+ pid_ns->child_reaper = NULL;
+ return;
}
/*
@@ -412,5 +691,9 @@ void __init pidmap_init(void)
set_bit(0, init_pid_ns.pidmap[0].page);
atomic_dec(&init_pid_ns.pidmap[0].nr_free);
- pid_cachep = KMEM_CACHE(pid, SLAB_PANIC);
+ init_pid_ns.pid_cachep = create_pid_cachep(1);
+ if (init_pid_ns.pid_cachep == NULL)
+ panic("Can't create pid_1 cachep\n");
+
+ pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC);
}
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index b53c8fcd9d8..68c96376e84 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -21,8 +21,8 @@ static int check_clock(const clockid_t which_clock)
read_lock(&tasklist_lock);
p = find_task_by_pid(pid);
- if (!p || (CPUCLOCK_PERTHREAD(which_clock) ?
- p->tgid != current->tgid : p->tgid != pid)) {
+ if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ?
+ same_thread_group(p, current) : thread_group_leader(p))) {
error = -EINVAL;
}
read_unlock(&tasklist_lock);
@@ -308,13 +308,13 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
p = find_task_by_pid(pid);
if (p) {
if (CPUCLOCK_PERTHREAD(which_clock)) {
- if (p->tgid == current->tgid) {
+ if (same_thread_group(p, current)) {
error = cpu_clock_sample(which_clock,
p, &rtn);
}
} else {
read_lock(&tasklist_lock);
- if (p->tgid == pid && p->signal) {
+ if (thread_group_leader(p) && p->signal) {
error =
cpu_clock_sample_group(which_clock,
p, &rtn);
@@ -355,7 +355,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
p = current;
} else {
p = find_task_by_pid(pid);
- if (p && p->tgid != current->tgid)
+ if (p && !same_thread_group(p, current))
p = NULL;
}
} else {
@@ -363,7 +363,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer)
p = current->group_leader;
} else {
p = find_task_by_pid(pid);
- if (p && p->tgid != pid)
+ if (p && !thread_group_leader(p))
p = NULL;
}
}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index d11f579d189..35b4bbfc78f 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -404,7 +404,7 @@ static struct task_struct * good_sigevent(sigevent_t * event)
if ((event->sigev_notify & SIGEV_THREAD_ID ) &&
(!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) ||
- rtn->tgid != current->tgid ||
+ !same_thread_group(rtn, current) ||
(event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL))
return NULL;
@@ -608,7 +608,7 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
spin_lock(&timr->it_lock);
if ((timr->it_id != timer_id) || !(timr->it_process) ||
- timr->it_process->tgid != current->tgid) {
+ !same_thread_group(timr->it_process, current)) {
spin_unlock(&timr->it_lock);
spin_unlock_irqrestore(&idr_lock, *flags);
timr = NULL;
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index ccc95ac07be..78039b477d2 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1005,11 +1005,12 @@ copy_data_pages(struct memory_bitmap *copy_bm, struct memory_bitmap *orig_bm)
}
memory_bm_position_reset(orig_bm);
memory_bm_position_reset(copy_bm);
- do {
+ for(;;) {
pfn = memory_bm_next_pfn(orig_bm);
- if (likely(pfn != BM_END_OF_MAP))
- copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
- } while (pfn != BM_END_OF_MAP);
+ if (unlikely(pfn == BM_END_OF_MAP))
+ break;
+ copy_data_page(memory_bm_next_pfn(copy_bm), pfn);
+ }
}
/* Total number of image pages */
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index a73ebd3b9d4..7c76f2ffaea 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -19,6 +19,7 @@
#include <linux/security.h>
#include <linux/signal.h>
#include <linux/audit.h>
+#include <linux/pid_namespace.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -168,7 +169,7 @@ int ptrace_attach(struct task_struct *task)
retval = -EPERM;
if (task->pid <= 1)
goto out;
- if (task->tgid == current->tgid)
+ if (same_thread_group(task, current))
goto out;
repeat:
@@ -443,7 +444,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
return ERR_PTR(-EPERM);
read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
+ child = find_task_by_vpid(pid);
if (child)
get_task_struct(child);
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c
index 6b0703db152..56d73cb8826 100644
--- a/kernel/rtmutex-debug.c
+++ b/kernel/rtmutex-debug.c
@@ -87,7 +87,7 @@ static int rt_trace_on = 1;
static void printk_task(struct task_struct *p)
{
if (p)
- printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio);
+ printk("%16s:%5d [%p, %3d]", p->comm, task_pid_nr(p), p, p->prio);
else
printk("<none>");
}
@@ -152,22 +152,25 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter)
printk( "[ BUG: circular locking deadlock detected! ]\n");
printk( "--------------------------------------------\n");
printk("%s/%d is deadlocking current task %s/%d\n\n",
- task->comm, task->pid, current->comm, current->pid);
+ task->comm, task_pid_nr(task),
+ current->comm, task_pid_nr(current));
printk("\n1) %s/%d is trying to acquire this lock:\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
printk_lock(waiter->lock, 1);
- printk("\n2) %s/%d is blocked on this lock:\n", task->comm, task->pid);
+ printk("\n2) %s/%d is blocked on this lock:\n",
+ task->comm, task_pid_nr(task));
printk_lock(waiter->deadlock_lock, 1);
debug_show_held_locks(current);
debug_show_held_locks(task);
- printk("\n%s/%d's [blocked] stackdump:\n\n", task->comm, task->pid);
+ printk("\n%s/%d's [blocked] stackdump:\n\n",
+ task->comm, task_pid_nr(task));
show_stack(task, NULL);
printk("\n%s/%d's [current] stackdump:\n\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
dump_stack();
debug_show_all_locks();
diff --git a/kernel/rtmutex.c b/kernel/rtmutex.c
index 8cd9bd2cdb3..0deef71ff8d 100644
--- a/kernel/rtmutex.c
+++ b/kernel/rtmutex.c
@@ -185,7 +185,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task,
prev_max = max_lock_depth;
printk(KERN_WARNING "Maximum lock depth %d reached "
"task: %s (%d)\n", max_lock_depth,
- top_task->comm, top_task->pid);
+ top_task->comm, task_pid_nr(top_task));
}
put_task_struct(task);
diff --git a/kernel/sched.c b/kernel/sched.c
index ed90be46fb3..2810e562a99 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -44,6 +44,7 @@
#include <linux/vmalloc.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
+#include <linux/pid_namespace.h>
#include <linux/smp.h>
#include <linux/threads.h>
#include <linux/timer.h>
@@ -51,6 +52,7 @@
#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/percpu.h>
+#include <linux/cpu_acct.h>
#include <linux/kthread.h>
#include <linux/seq_file.h>
#include <linux/sysctl.h>
@@ -153,10 +155,15 @@ struct rt_prio_array {
#ifdef CONFIG_FAIR_GROUP_SCHED
+#include <linux/cgroup.h>
+
struct cfs_rq;
/* task group related information */
struct task_group {
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+ struct cgroup_subsys_state css;
+#endif
/* schedulable entities of this group on each cpu */
struct sched_entity **se;
/* runqueue "owned" by this group on each cpu */
@@ -197,6 +204,9 @@ static inline struct task_group *task_group(struct task_struct *p)
#ifdef CONFIG_FAIR_USER_SCHED
tg = p->user->tg;
+#elif defined(CONFIG_FAIR_CGROUP_SCHED)
+ tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id),
+ struct task_group, css);
#else
tg = &init_task_group;
#endif
@@ -1875,7 +1885,7 @@ asmlinkage void schedule_tail(struct task_struct *prev)
preempt_enable();
#endif
if (current->set_child_tid)
- put_user(current->pid, current->set_child_tid);
+ put_user(task_pid_vnr(current), current->set_child_tid);
}
/*
@@ -3300,16 +3310,19 @@ unsigned long long task_sched_runtime(struct task_struct *p)
/*
* Account user cpu time to a process.
* @p: the process that the cpu time gets accounted to
- * @hardirq_offset: the offset to subtract from hardirq_count()
* @cputime: the cpu time spent in user space since the last update
*/
void account_user_time(struct task_struct *p, cputime_t cputime)
{
struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
cputime64_t tmp;
+ struct rq *rq = this_rq();
p->utime = cputime_add(p->utime, cputime);
+ if (p != rq->idle)
+ cpuacct_charge(p, cputime);
+
/* Add user time to cpustat. */
tmp = cputime_to_cputime64(cputime);
if (TASK_NICE(p) > 0)
@@ -3362,7 +3375,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
if (p->flags & PF_VCPU) {
account_guest_time(p, cputime);
- p->flags &= ~PF_VCPU;
return;
}
@@ -3374,9 +3386,10 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
cpustat->irq = cputime64_add(cpustat->irq, tmp);
else if (softirq_count())
cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
- else if (p != rq->idle)
+ else if (p != rq->idle) {
cpustat->system = cputime64_add(cpustat->system, tmp);
- else if (atomic_read(&rq->nr_iowait) > 0)
+ cpuacct_charge(p, cputime);
+ } else if (atomic_read(&rq->nr_iowait) > 0)
cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
else
cpustat->idle = cputime64_add(cpustat->idle, tmp);
@@ -3412,8 +3425,10 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
else
cpustat->idle = cputime64_add(cpustat->idle, tmp);
- } else
+ } else {
cpustat->steal = cputime64_add(cpustat->steal, tmp);
+ cpuacct_charge(p, -tmp);
+ }
}
/*
@@ -3493,7 +3508,7 @@ EXPORT_SYMBOL(sub_preempt_count);
static noinline void __schedule_bug(struct task_struct *prev)
{
printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
- prev->comm, preempt_count(), prev->pid);
+ prev->comm, preempt_count(), task_pid_nr(prev));
debug_show_held_locks(prev);
if (irqs_disabled())
print_irqtrace_events(prev);
@@ -4159,7 +4174,7 @@ struct task_struct *idle_task(int cpu)
*/
static struct task_struct *find_process_by_pid(pid_t pid)
{
- return pid ? find_task_by_pid(pid) : current;
+ return pid ? find_task_by_vpid(pid) : current;
}
/* Actually do priority change: must hold rq lock. */
@@ -4462,8 +4477,21 @@ long sched_setaffinity(pid_t pid, cpumask_t new_mask)
cpus_allowed = cpuset_cpus_allowed(p);
cpus_and(new_mask, new_mask, cpus_allowed);
+ again:
retval = set_cpus_allowed(p, new_mask);
+ if (!retval) {
+ cpus_allowed = cpuset_cpus_allowed(p);
+ if (!cpus_subset(new_mask, cpus_allowed)) {
+ /*
+ * We must have raced with a concurrent cpuset
+ * update. Just reset the cpus_allowed to the
+ * cpuset's cpus_allowed
+ */
+ new_mask = cpus_allowed;
+ goto again;
+ }
+ }
out_unlock:
put_task_struct(p);
mutex_unlock(&sched_hotcpu_mutex);
@@ -4843,7 +4871,8 @@ static void show_task(struct task_struct *p)
free = (unsigned long)n - (unsigned long)end_of_stack(p);
}
#endif
- printk(KERN_CONT "%5lu %5d %6d\n", free, p->pid, p->parent->pid);
+ printk(KERN_CONT "%5lu %5d %6d\n", free,
+ task_pid_nr(p), task_pid_nr(p->parent));
if (state != TASK_RUNNING)
show_stack(p, NULL);
@@ -5115,7 +5144,7 @@ static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu)
}
/*
- * Figure out where task on dead CPU should go, use force if neccessary.
+ * Figure out where task on dead CPU should go, use force if necessary.
* NOTE: interrupts should be disabled by the caller
*/
static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
@@ -5137,8 +5166,16 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
/* No more Mr. Nice Guy. */
if (dest_cpu == NR_CPUS) {
+ cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p);
+ /*
+ * Try to stay on the same cpuset, where the
+ * current cpuset may be a subset of all cpus.
+ * The cpuset_cpus_allowed_locked() variant of
+ * cpuset_cpus_allowed() will not block. It must be
+ * called within calls to cpuset_lock/cpuset_unlock.
+ */
rq = task_rq_lock(p, &flags);
- cpus_setall(p->cpus_allowed);
+ p->cpus_allowed = cpus_allowed;
dest_cpu = any_online_cpu(p->cpus_allowed);
task_rq_unlock(rq, &flags);
@@ -5150,7 +5187,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p)
if (p->mm && printk_ratelimit())
printk(KERN_INFO "process %d (%s) no "
"longer affine to cpu%d\n",
- p->pid, p->comm, dead_cpu);
+ task_pid_nr(p), p->comm, dead_cpu);
}
} while (!__migrate_task_irq(p, dead_cpu, dest_cpu));
}
@@ -5257,7 +5294,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p)
struct rq *rq = cpu_rq(dead_cpu);
/* Must be exiting, otherwise would be on tasklist. */
- BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD);
+ BUG_ON(!p->exit_state);
/* Cannot have done final schedule yet: would have vanished. */
BUG_ON(p->state == TASK_DEAD);
@@ -5486,7 +5523,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- /* Strictly unneccessary, as first user will wake it. */
+ /* Strictly unnecessary, as first user will wake it. */
wake_up_process(cpu_rq(cpu)->migration_thread);
break;
@@ -5504,6 +5541,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
case CPU_DEAD:
case CPU_DEAD_FROZEN:
+ cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */
migrate_live_tasks(cpu);
rq = cpu_rq(cpu);
kthread_stop(rq->migration_thread);
@@ -5517,6 +5555,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
rq->idle->sched_class = &idle_sched_class;
migrate_dead_tasks(cpu);
spin_unlock_irq(&rq->lock);
+ cpuset_unlock();
migrate_nr_uninterruptible(rq);
BUG_ON(rq->nr_running != 0);
@@ -6367,26 +6406,31 @@ error:
return -ENOMEM;
#endif
}
+
+static cpumask_t *doms_cur; /* current sched domains */
+static int ndoms_cur; /* number of sched domains in 'doms_cur' */
+
+/*
+ * Special case: If a kmalloc of a doms_cur partition (array of
+ * cpumask_t) fails, then fallback to a single sched domain,
+ * as determined by the single cpumask_t fallback_doms.
+ */
+static cpumask_t fallback_doms;
+
/*
* Set up scheduler domains and groups. Callers must hold the hotplug lock.
+ * For now this just excludes isolated cpus, but could be used to
+ * exclude other special cases in the future.
*/
static int arch_init_sched_domains(const cpumask_t *cpu_map)
{
- cpumask_t cpu_default_map;
- int err;
-
- /*
- * Setup mask for cpus without special case scheduling requirements.
- * For now this just excludes isolated cpus, but could be used to
- * exclude other special cases in the future.
- */
- cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map);
-
- err = build_sched_domains(&cpu_default_map);
-
+ ndoms_cur = 1;
+ doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
+ if (!doms_cur)
+ doms_cur = &fallback_doms;
+ cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map);
register_sched_domain_sysctl();
-
- return err;
+ return build_sched_domains(doms_cur);
}
static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
@@ -6410,6 +6454,68 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
arch_destroy_sched_domains(cpu_map);
}
+/*
+ * Partition sched domains as specified by the 'ndoms_new'
+ * cpumasks in the array doms_new[] of cpumasks. This compares
+ * doms_new[] to the current sched domain partitioning, doms_cur[].
+ * It destroys each deleted domain and builds each new domain.
+ *
+ * 'doms_new' is an array of cpumask_t's of length 'ndoms_new'.
+ * The masks don't intersect (don't overlap.) We should setup one
+ * sched domain for each mask. CPUs not in any of the cpumasks will
+ * not be load balanced. If the same cpumask appears both in the
+ * current 'doms_cur' domains and in the new 'doms_new', we can leave
+ * it as it is.
+ *
+ * The passed in 'doms_new' should be kmalloc'd. This routine takes
+ * ownership of it and will kfree it when done with it. If the caller
+ * failed the kmalloc call, then it can pass in doms_new == NULL,
+ * and partition_sched_domains() will fallback to the single partition
+ * 'fallback_doms'.
+ *
+ * Call with hotplug lock held
+ */
+void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
+{
+ int i, j;
+
+ if (doms_new == NULL) {
+ ndoms_new = 1;
+ doms_new = &fallback_doms;
+ cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map);
+ }
+
+ /* Destroy deleted domains */
+ for (i = 0; i < ndoms_cur; i++) {
+ for (j = 0; j < ndoms_new; j++) {
+ if (cpus_equal(doms_cur[i], doms_new[j]))
+ goto match1;
+ }
+ /* no match - a current sched domain not in new doms_new[] */
+ detach_destroy_domains(doms_cur + i);
+match1:
+ ;
+ }
+
+ /* Build new domains */
+ for (i = 0; i < ndoms_new; i++) {
+ for (j = 0; j < ndoms_cur; j++) {
+ if (cpus_equal(doms_new[i], doms_cur[j]))
+ goto match2;
+ }
+ /* no match - add a new doms_new */
+ build_sched_domains(doms_new + i);
+match2:
+ ;
+ }
+
+ /* Remember the new sched domains */
+ if (doms_cur != &fallback_doms)
+ kfree(doms_cur);
+ doms_cur = doms_new;
+ ndoms_cur = ndoms_new;
+}
+
#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
static int arch_reinit_sched_domains(void)
{
@@ -6991,3 +7097,116 @@ unsigned long sched_group_shares(struct task_group *tg)
}
#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+#ifdef CONFIG_FAIR_CGROUP_SCHED
+
+/* return corresponding task_group object of a cgroup */
+static inline struct task_group *cgroup_tg(struct cgroup *cont)
+{
+ return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id),
+ struct task_group, css);
+}
+
+static struct cgroup_subsys_state *
+cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ struct task_group *tg;
+
+ if (!cont->parent) {
+ /* This is early initialization for the top cgroup */
+ init_task_group.css.cgroup = cont;
+ return &init_task_group.css;
+ }
+
+ /* we support only 1-level deep hierarchical scheduler atm */
+ if (cont->parent->parent)
+ return ERR_PTR(-EINVAL);
+
+ tg = sched_create_group();
+ if (IS_ERR(tg))
+ return ERR_PTR(-ENOMEM);
+
+ /* Bind the cgroup to task_group object we just created */
+ tg->css.cgroup = cont;
+
+ return &tg->css;
+}
+
+static void cpu_cgroup_destroy(struct cgroup_subsys *ss,
+ struct cgroup *cont)
+{
+ struct task_group *tg = cgroup_tg(cont);
+
+ sched_destroy_group(tg);
+}
+
+static int cpu_cgroup_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *cont, struct task_struct *tsk)
+{
+ /* We don't support RT-tasks being in separate groups */
+ if (tsk->sched_class != &fair_sched_class)
+ return -EINVAL;
+
+ return 0;
+}
+
+static void
+cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+ struct cgroup *old_cont, struct task_struct *tsk)
+{
+ sched_move_task(tsk);
+}
+
+static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype,
+ struct file *file, const char __user *userbuf,
+ size_t nbytes, loff_t *ppos)
+{
+ unsigned long shareval;
+ struct task_group *tg = cgroup_tg(cont);
+ char buffer[2*sizeof(unsigned long) + 1];
+ int rc;
+
+ if (nbytes > 2*sizeof(unsigned long)) /* safety check */
+ return -E2BIG;
+
+ if (copy_from_user(buffer, userbuf, nbytes))
+ return -EFAULT;
+
+ buffer[nbytes] = 0; /* nul-terminate */
+ shareval = simple_strtoul(buffer, NULL, 10);
+
+ rc = sched_group_set_shares(tg, shareval);
+
+ return (rc < 0 ? rc : nbytes);
+}
+
+static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft)
+{
+ struct task_group *tg = cgroup_tg(cont);
+
+ return (u64) tg->shares;
+}
+
+static struct cftype cpu_shares = {
+ .name = "shares",
+ .read_uint = cpu_shares_read_uint,
+ .write = cpu_shares_write,
+};
+
+static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont)
+{
+ return cgroup_add_file(cont, ss, &cpu_shares);
+}
+
+struct cgroup_subsys cpu_cgroup_subsys = {
+ .name = "cpu",
+ .create = cpu_cgroup_create,
+ .destroy = cpu_cgroup_destroy,
+ .can_attach = cpu_cgroup_can_attach,
+ .attach = cpu_cgroup_attach,
+ .populate = cpu_cgroup_populate,
+ .subsys_id = cpu_cgroup_subsys_id,
+ .early_init = 1,
+};
+
+#endif /* CONFIG_FAIR_CGROUP_SCHED */
diff --git a/kernel/signal.c b/kernel/signal.c
index e4f059cd986..12006308c7e 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -256,7 +256,7 @@ flush_signal_handlers(struct task_struct *t, int force_default)
int unhandled_signal(struct task_struct *tsk, int sig)
{
- if (is_init(tsk))
+ if (is_global_init(tsk))
return 1;
if (tsk->ptrace & PT_PTRACED)
return 0;
@@ -536,7 +536,7 @@ static int check_kill_permission(int sig, struct siginfo *info,
return error;
error = -EPERM;
if (((sig != SIGCONT) ||
- (process_session(current) != process_session(t)))
+ (task_session_nr(current) != task_session_nr(t)))
&& (current->euid ^ t->suid) && (current->euid ^ t->uid)
&& (current->uid ^ t->suid) && (current->uid ^ t->uid)
&& !capable(CAP_KILL))
@@ -694,7 +694,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
q->info.si_signo = sig;
q->info.si_errno = 0;
q->info.si_code = SI_USER;
- q->info.si_pid = current->pid;
+ q->info.si_pid = task_pid_vnr(current);
q->info.si_uid = current->uid;
break;
case (unsigned long) SEND_SIG_PRIV:
@@ -730,7 +730,7 @@ int print_fatal_signals;
static void print_fatal_signal(struct pt_regs *regs, int signr)
{
printk("%s/%d: potentially unexpected fatal signal %d.\n",
- current->comm, current->pid, signr);
+ current->comm, task_pid_nr(current), signr);
#ifdef __i386__
printk("code at %08lx: ", regs->eip);
@@ -1089,7 +1089,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid)
{
int error;
rcu_read_lock();
- error = kill_pid_info(sig, info, find_pid(pid));
+ error = kill_pid_info(sig, info, find_vpid(pid));
rcu_read_unlock();
return error;
}
@@ -1150,7 +1150,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
read_lock(&tasklist_lock);
for_each_process(p) {
- if (p->pid > 1 && p->tgid != current->tgid) {
+ if (p->pid > 1 && !same_thread_group(p, current)) {
int err = group_send_sig_info(sig, info, p);
++count;
if (err != -EPERM)
@@ -1160,9 +1160,9 @@ static int kill_something_info(int sig, struct siginfo *info, int pid)
read_unlock(&tasklist_lock);
ret = count ? retval : -ESRCH;
} else if (pid < 0) {
- ret = kill_pgrp_info(sig, info, find_pid(-pid));
+ ret = kill_pgrp_info(sig, info, find_vpid(-pid));
} else {
- ret = kill_pid_info(sig, info, find_pid(pid));
+ ret = kill_pid_info(sig, info, find_vpid(pid));
}
rcu_read_unlock();
return ret;
@@ -1266,7 +1266,12 @@ EXPORT_SYMBOL(kill_pid);
int
kill_proc(pid_t pid, int sig, int priv)
{
- return kill_proc_info(sig, __si_special(priv), pid);
+ int ret;
+
+ rcu_read_lock();
+ ret = kill_pid_info(sig, __si_special(priv), find_pid(pid));
+ rcu_read_unlock();
+ return ret;
}
/*
@@ -1443,7 +1448,22 @@ void do_notify_parent(struct task_struct *tsk, int sig)
info.si_signo = sig;
info.si_errno = 0;
- info.si_pid = tsk->pid;
+ /*
+ * we are under tasklist_lock here so our parent is tied to
+ * us and cannot exit and release its namespace.
+ *
+ * the only it can is to switch its nsproxy with sys_unshare,
+ * bu uncharing pid namespaces is not allowed, so we'll always
+ * see relevant namespace
+ *
+ * write_lock() currently calls preempt_disable() which is the
+ * same as rcu_read_lock(), but according to Oleg, this is not
+ * correct to rely on this
+ */
+ rcu_read_lock();
+ info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+ rcu_read_unlock();
+
info.si_uid = tsk->uid;
/* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1508,7 +1528,13 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
info.si_signo = SIGCHLD;
info.si_errno = 0;
- info.si_pid = tsk->pid;
+ /*
+ * see comment in do_notify_parent() abot the following 3 lines
+ */
+ rcu_read_lock();
+ info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
+ rcu_read_unlock();
+
info.si_uid = tsk->uid;
/* FIXME: find out whether or not this is supposed to be c*time. */
@@ -1634,7 +1660,7 @@ void ptrace_notify(int exit_code)
memset(&info, 0, sizeof info);
info.si_signo = SIGTRAP;
info.si_code = exit_code;
- info.si_pid = current->pid;
+ info.si_pid = task_pid_vnr(current);
info.si_uid = current->uid;
/* Let the debugger run. */
@@ -1804,7 +1830,7 @@ relock:
info->si_signo = signr;
info->si_errno = 0;
info->si_code = SI_USER;
- info->si_pid = current->parent->pid;
+ info->si_pid = task_pid_vnr(current->parent);
info->si_uid = current->parent->uid;
}
@@ -1835,11 +1861,9 @@ relock:
continue;
/*
- * Init of a pid space gets no signals it doesn't want from
- * within that pid space. It can of course get signals from
- * its parent pid space.
+ * Global init gets no signals it doesn't want.
*/
- if (current == child_reaper(current))
+ if (is_global_init(current))
continue;
if (sig_kernel_stop(signr)) {
@@ -2193,7 +2217,7 @@ sys_kill(int pid, int sig)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_USER;
- info.si_pid = current->tgid;
+ info.si_pid = task_tgid_vnr(current);
info.si_uid = current->uid;
return kill_something_info(sig, &info, pid);
@@ -2209,12 +2233,12 @@ static int do_tkill(int tgid, int pid, int sig)
info.si_signo = sig;
info.si_errno = 0;
info.si_code = SI_TKILL;
- info.si_pid = current->tgid;
+ info.si_pid = task_tgid_vnr(current);
info.si_uid = current->uid;
read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
- if (p && (tgid <= 0 || p->tgid == tgid)) {
+ p = find_task_by_vpid(pid);
+ if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
error = check_kill_permission(sig, &info, p);
/*
* The null signal is a permissions and process existence
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index edeeef3a6a3..11df812263c 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -113,7 +113,7 @@ void softlockup_tick(void)
spin_lock(&print_lock);
printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n",
this_cpu, now - touch_timestamp,
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
if (regs)
show_regs(regs);
else
diff --git a/kernel/sys.c b/kernel/sys.c
index bc8879c822a..304b5410d74 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -106,537 +106,6 @@ EXPORT_SYMBOL(cad_pid);
void (*pm_power_off_prepare)(void);
-/*
- * Notifier list for kernel code which wants to be called
- * at shutdown. This is used to stop any idling DMA operations
- * and the like.
- */
-
-static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list);
-
-/*
- * Notifier chain core routines. The exported routines below
- * are layered on top of these, with appropriate locking added.
- */
-
-static int notifier_chain_register(struct notifier_block **nl,
- struct notifier_block *n)
-{
- while ((*nl) != NULL) {
- if (n->priority > (*nl)->priority)
- break;
- nl = &((*nl)->next);
- }
- n->next = *nl;
- rcu_assign_pointer(*nl, n);
- return 0;
-}
-
-static int notifier_chain_unregister(struct notifier_block **nl,
- struct notifier_block *n)
-{
- while ((*nl) != NULL) {
- if ((*nl) == n) {
- rcu_assign_pointer(*nl, n->next);
- return 0;
- }
- nl = &((*nl)->next);
- }
- return -ENOENT;
-}
-
-/**
- * notifier_call_chain - Informs the registered notifiers about an event.
- * @nl: Pointer to head of the blocking notifier chain
- * @val: Value passed unmodified to notifier function
- * @v: Pointer passed unmodified to notifier function
- * @nr_to_call: Number of notifier functions to be called. Don't care
- * value of this parameter is -1.
- * @nr_calls: Records the number of notifications sent. Don't care
- * value of this field is NULL.
- * @returns: notifier_call_chain returns the value returned by the
- * last notifier function called.
- */
-
-static int __kprobes notifier_call_chain(struct notifier_block **nl,
- unsigned long val, void *v,
- int nr_to_call, int *nr_calls)
-{
- int ret = NOTIFY_DONE;
- struct notifier_block *nb, *next_nb;
-
- nb = rcu_dereference(*nl);
-
- while (nb && nr_to_call) {
- next_nb = rcu_dereference(nb->next);
- ret = nb->notifier_call(nb, val, v);
-
- if (nr_calls)
- (*nr_calls)++;
-
- if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)
- break;
- nb = next_nb;
- nr_to_call--;
- }
- return ret;
-}
-
-/*
- * Atomic notifier chain routines. Registration and unregistration
- * use a spinlock, and call_chain is synchronized by RCU (no locks).
- */
-
-/**
- * atomic_notifier_chain_register - Add notifier to an atomic notifier chain
- * @nh: Pointer to head of the atomic notifier chain
- * @n: New entry in notifier chain
- *
- * Adds a notifier to an atomic notifier chain.
- *
- * Currently always returns zero.
- */
-
-int atomic_notifier_chain_register(struct atomic_notifier_head *nh,
- struct notifier_block *n)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&nh->lock, flags);
- ret = notifier_chain_register(&nh->head, n);
- spin_unlock_irqrestore(&nh->lock, flags);
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_register);
-
-/**
- * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain
- * @nh: Pointer to head of the atomic notifier chain
- * @n: Entry to remove from notifier chain
- *
- * Removes a notifier from an atomic notifier chain.
- *
- * Returns zero on success or %-ENOENT on failure.
- */
-int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh,
- struct notifier_block *n)
-{
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&nh->lock, flags);
- ret = notifier_chain_unregister(&nh->head, n);
- spin_unlock_irqrestore(&nh->lock, flags);
- synchronize_rcu();
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister);
-
-/**
- * __atomic_notifier_call_chain - Call functions in an atomic notifier chain
- * @nh: Pointer to head of the atomic notifier chain
- * @val: Value passed unmodified to notifier function
- * @v: Pointer passed unmodified to notifier function
- * @nr_to_call: See the comment for notifier_call_chain.
- * @nr_calls: See the comment for notifier_call_chain.
- *
- * Calls each function in a notifier chain in turn. The functions
- * run in an atomic context, so they must not block.
- * This routine uses RCU to synchronize with changes to the chain.
- *
- * If the return value of the notifier can be and'ed
- * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain()
- * will return immediately, with the return value of
- * the notifier function which halted execution.
- * Otherwise the return value is the return value
- * of the last notifier function called.
- */
-
-int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh,
- unsigned long val, void *v,
- int nr_to_call, int *nr_calls)
-{
- int ret;
-
- rcu_read_lock();
- ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
- rcu_read_unlock();
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain);
-
-int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh,
- unsigned long val, void *v)
-{
- return __atomic_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(atomic_notifier_call_chain);
-/*
- * Blocking notifier chain routines. All access to the chain is
- * synchronized by an rwsem.
- */
-
-/**
- * blocking_notifier_chain_register - Add notifier to a blocking notifier chain
- * @nh: Pointer to head of the blocking notifier chain
- * @n: New entry in notifier chain
- *
- * Adds a notifier to a blocking notifier chain.
- * Must be called in process context.
- *
- * Currently always returns zero.
- */
-
-int blocking_notifier_chain_register(struct blocking_notifier_head *nh,
- struct notifier_block *n)
-{
- int ret;
-
- /*
- * This code gets used during boot-up, when task switching is
- * not yet working and interrupts must remain disabled. At
- * such times we must not call down_write().
- */
- if (unlikely(system_state == SYSTEM_BOOTING))
- return notifier_chain_register(&nh->head, n);
-
- down_write(&nh->rwsem);
- ret = notifier_chain_register(&nh->head, n);
- up_write(&nh->rwsem);
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_register);
-
-/**
- * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain
- * @nh: Pointer to head of the blocking notifier chain
- * @n: Entry to remove from notifier chain
- *
- * Removes a notifier from a blocking notifier chain.
- * Must be called from process context.
- *
- * Returns zero on success or %-ENOENT on failure.
- */
-int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
- struct notifier_block *n)
-{
- int ret;
-
- /*
- * This code gets used during boot-up, when task switching is
- * not yet working and interrupts must remain disabled. At
- * such times we must not call down_write().
- */
- if (unlikely(system_state == SYSTEM_BOOTING))
- return notifier_chain_unregister(&nh->head, n);
-
- down_write(&nh->rwsem);
- ret = notifier_chain_unregister(&nh->head, n);
- up_write(&nh->rwsem);
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
-
-/**
- * __blocking_notifier_call_chain - Call functions in a blocking notifier chain
- * @nh: Pointer to head of the blocking notifier chain
- * @val: Value passed unmodified to notifier function
- * @v: Pointer passed unmodified to notifier function
- * @nr_to_call: See comment for notifier_call_chain.
- * @nr_calls: See comment for notifier_call_chain.
- *
- * Calls each function in a notifier chain in turn. The functions
- * run in a process context, so they are allowed to block.
- *
- * If the return value of the notifier can be and'ed
- * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain()
- * will return immediately, with the return value of
- * the notifier function which halted execution.
- * Otherwise the return value is the return value
- * of the last notifier function called.
- */
-
-int __blocking_notifier_call_chain(struct blocking_notifier_head *nh,
- unsigned long val, void *v,
- int nr_to_call, int *nr_calls)
-{
- int ret = NOTIFY_DONE;
-
- /*
- * We check the head outside the lock, but if this access is
- * racy then it does not matter what the result of the test
- * is, we re-check the list after having taken the lock anyway:
- */
- if (rcu_dereference(nh->head)) {
- down_read(&nh->rwsem);
- ret = notifier_call_chain(&nh->head, val, v, nr_to_call,
- nr_calls);
- up_read(&nh->rwsem);
- }
- return ret;
-}
-EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain);
-
-int blocking_notifier_call_chain(struct blocking_notifier_head *nh,
- unsigned long val, void *v)
-{
- return __blocking_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(blocking_notifier_call_chain);
-
-/*
- * Raw notifier chain routines. There is no protection;
- * the caller must provide it. Use at your own risk!
- */
-
-/**
- * raw_notifier_chain_register - Add notifier to a raw notifier chain
- * @nh: Pointer to head of the raw notifier chain
- * @n: New entry in notifier chain
- *
- * Adds a notifier to a raw notifier chain.
- * All locking must be provided by the caller.
- *
- * Currently always returns zero.
- */
-
-int raw_notifier_chain_register(struct raw_notifier_head *nh,
- struct notifier_block *n)
-{
- return notifier_chain_register(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_register);
-
-/**
- * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain
- * @nh: Pointer to head of the raw notifier chain
- * @n: Entry to remove from notifier chain
- *
- * Removes a notifier from a raw notifier chain.
- * All locking must be provided by the caller.
- *
- * Returns zero on success or %-ENOENT on failure.
- */
-int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
- struct notifier_block *n)
-{
- return notifier_chain_unregister(&nh->head, n);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
-
-/**
- * __raw_notifier_call_chain - Call functions in a raw notifier chain
- * @nh: Pointer to head of the raw notifier chain
- * @val: Value passed unmodified to notifier function
- * @v: Pointer passed unmodified to notifier function
- * @nr_to_call: See comment for notifier_call_chain.
- * @nr_calls: See comment for notifier_call_chain
- *
- * Calls each function in a notifier chain in turn. The functions
- * run in an undefined context.
- * All locking must be provided by the caller.
- *
- * If the return value of the notifier can be and'ed
- * with %NOTIFY_STOP_MASK then raw_notifier_call_chain()
- * will return immediately, with the return value of
- * the notifier function which halted execution.
- * Otherwise the return value is the return value
- * of the last notifier function called.
- */
-
-int __raw_notifier_call_chain(struct raw_notifier_head *nh,
- unsigned long val, void *v,
- int nr_to_call, int *nr_calls)
-{
- return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
-}
-
-EXPORT_SYMBOL_GPL(__raw_notifier_call_chain);
-
-int raw_notifier_call_chain(struct raw_notifier_head *nh,
- unsigned long val, void *v)
-{
- return __raw_notifier_call_chain(nh, val, v, -1, NULL);
-}
-
-EXPORT_SYMBOL_GPL(raw_notifier_call_chain);
-
-/*
- * SRCU notifier chain routines. Registration and unregistration
- * use a mutex, and call_chain is synchronized by SRCU (no locks).
- */
-
-/**
- * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain
- * @nh: Pointer to head of the SRCU notifier chain
- * @n: New entry in notifier chain
- *
- * Adds a notifier to an SRCU notifier chain.
- * Must be called in process context.
- *
- * Currently always returns zero.
- */
-
-int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
- struct notifier_block *n)
-{
- int ret;
-
- /*
- * This code gets used during boot-up, when task switching is
- * not yet working and interrupts must remain disabled. At
- * such times we must not call mutex_lock().
- */
- if (unlikely(system_state == SYSTEM_BOOTING))
- return notifier_chain_register(&nh->head, n);
-
- mutex_lock(&nh->mutex);
- ret = notifier_chain_register(&nh->head, n);
- mutex_unlock(&nh->mutex);
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_register);
-
-/**
- * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain
- * @nh: Pointer to head of the SRCU notifier chain
- * @n: Entry to remove from notifier chain
- *
- * Removes a notifier from an SRCU notifier chain.
- * Must be called from process context.
- *
- * Returns zero on success or %-ENOENT on failure.
- */
-int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh,
- struct notifier_block *n)
-{
- int ret;
-
- /*
- * This code gets used during boot-up, when task switching is
- * not yet working and interrupts must remain disabled. At
- * such times we must not call mutex_lock().
- */
- if (unlikely(system_state == SYSTEM_BOOTING))
- return notifier_chain_unregister(&nh->head, n);
-
- mutex_lock(&nh->mutex);
- ret = notifier_chain_unregister(&nh->head, n);
- mutex_unlock(&nh->mutex);
- synchronize_srcu(&nh->srcu);
- return ret;
-}
-
-EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister);
-
-/**
- * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain
- * @nh: Pointer to head of the SRCU notifier chain
- * @val: Value passed unmodified to notifier function
- * @v: Pointer passed unmodified to notifier function
- * @nr_to_call: See comment for notifier_call_chain.
- * @nr_calls: See comment for notifier_call_chain
- *
- * Calls each function in a notifier chain in turn. The functions
- * run in a process context, so they are allowed to block.
- *
- * If the return value of the notifier can be and'ed
- * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain()
- * will return immediately, with the return value of
- * the notifier function which halted execution.
- * Otherwise the return value is the return value
- * of the last notifier function called.
- */
-
-int __srcu_notifier_call_chain(struct srcu_notifier_head *nh,
- unsigned long val, void *v,
- int nr_to_call, int *nr_calls)
-{
- int ret;
- int idx;
-
- idx = srcu_read_lock(&nh->srcu);
- ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);
- srcu_read_unlock(&nh->srcu, idx);
- return ret;
-}
-EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain);
-
-int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
- unsigned long val, void *v)
-{
- return __srcu_notifier_call_chain(nh, val, v, -1, NULL);
-}
-EXPORT_SYMBOL_GPL(srcu_notifier_call_chain);
-
-/**
- * srcu_init_notifier_head - Initialize an SRCU notifier head
- * @nh: Pointer to head of the srcu notifier chain
- *
- * Unlike other sorts of notifier heads, SRCU notifier heads require
- * dynamic initialization. Be sure to call this routine before
- * calling any of the other SRCU notifier routines for this head.
- *
- * If an SRCU notifier head is deallocated, it must first be cleaned
- * up by calling srcu_cleanup_notifier_head(). Otherwise the head's
- * per-cpu data (used by the SRCU mechanism) will leak.
- */
-
-void srcu_init_notifier_head(struct srcu_notifier_head *nh)
-{
- mutex_init(&nh->mutex);
- if (init_srcu_struct(&nh->srcu) < 0)
- BUG();
- nh->head = NULL;
-}
-
-EXPORT_SYMBOL_GPL(srcu_init_notifier_head);
-
-/**
- * register_reboot_notifier - Register function to be called at reboot time
- * @nb: Info about notifier function to be called
- *
- * Registers a function with the list of functions
- * to be called at reboot time.
- *
- * Currently always returns zero, as blocking_notifier_chain_register()
- * always returns zero.
- */
-
-int register_reboot_notifier(struct notifier_block * nb)
-{
- return blocking_notifier_chain_register(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(register_reboot_notifier);
-
-/**
- * unregister_reboot_notifier - Unregister previously registered reboot notifier
- * @nb: Hook to be unregistered
- *
- * Unregisters a previously registered reboot
- * notifier function.
- *
- * Returns zero on success, or %-ENOENT on failure.
- */
-
-int unregister_reboot_notifier(struct notifier_block * nb)
-{
- return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
-}
-
-EXPORT_SYMBOL(unregister_reboot_notifier);
-
static int set_one_prio(struct task_struct *p, int niceval, int error)
{
int no_nice;
@@ -683,7 +152,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
switch (which) {
case PRIO_PROCESS:
if (who)
- p = find_task_by_pid(who);
+ p = find_task_by_vpid(who);
else
p = current;
if (p)
@@ -691,7 +160,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval)
break;
case PRIO_PGRP:
if (who)
- pgrp = find_pid(who);
+ pgrp = find_vpid(who);
else
pgrp = task_pgrp(current);
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -740,7 +209,7 @@ asmlinkage long sys_getpriority(int which, int who)
switch (which) {
case PRIO_PROCESS:
if (who)
- p = find_task_by_pid(who);
+ p = find_task_by_vpid(who);
else
p = current;
if (p) {
@@ -751,7 +220,7 @@ asmlinkage long sys_getpriority(int which, int who)
break;
case PRIO_PGRP:
if (who)
- pgrp = find_pid(who);
+ pgrp = find_vpid(who);
else
pgrp = task_pgrp(current);
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
@@ -1448,9 +917,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
struct task_struct *p;
struct task_struct *group_leader = current->group_leader;
int err = -EINVAL;
+ struct pid_namespace *ns;
if (!pid)
- pid = group_leader->pid;
+ pid = task_pid_vnr(group_leader);
if (!pgid)
pgid = pid;
if (pgid < 0)
@@ -1459,10 +929,12 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
/* From this point forward we keep holding onto the tasklist lock
* so that our parent does not change from under us. -DaveM
*/
+ ns = current->nsproxy->pid_ns;
+
write_lock_irq(&tasklist_lock);
err = -ESRCH;
- p = find_task_by_pid(pid);
+ p = find_task_by_pid_ns(pid, ns);
if (!p)
goto out;
@@ -1488,9 +960,9 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
goto out;
if (pgid != pid) {
- struct task_struct *g =
- find_task_by_pid_type(PIDTYPE_PGID, pgid);
+ struct task_struct *g;
+ g = find_task_by_pid_type_ns(PIDTYPE_PGID, pgid, ns);
if (!g || task_session(g) != task_session(group_leader))
goto out;
}
@@ -1499,10 +971,13 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
if (err)
goto out;
- if (process_group(p) != pgid) {
+ if (task_pgrp_nr_ns(p, ns) != pgid) {
+ struct pid *pid;
+
detach_pid(p, PIDTYPE_PGID);
- p->signal->pgrp = pgid;
- attach_pid(p, PIDTYPE_PGID, find_pid(pgid));
+ pid = find_vpid(pgid);
+ attach_pid(p, PIDTYPE_PGID, pid);
+ set_task_pgrp(p, pid_nr(pid));
}
err = 0;
@@ -1515,19 +990,21 @@ out:
asmlinkage long sys_getpgid(pid_t pid)
{
if (!pid)
- return process_group(current);
+ return task_pgrp_vnr(current);
else {
int retval;
struct task_struct *p;
+ struct pid_namespace *ns;
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
+ ns = current->nsproxy->pid_ns;
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid_ns(pid, ns);
retval = -ESRCH;
if (p) {
retval = security_task_getpgid(p);
if (!retval)
- retval = process_group(p);
+ retval = task_pgrp_nr_ns(p, ns);
}
read_unlock(&tasklist_lock);
return retval;
@@ -1539,7 +1016,7 @@ asmlinkage long sys_getpgid(pid_t pid)
asmlinkage long sys_getpgrp(void)
{
/* SMP - assuming writes are word atomic this is fine */
- return process_group(current);
+ return task_pgrp_vnr(current);
}
#endif
@@ -1547,19 +1024,21 @@ asmlinkage long sys_getpgrp(void)
asmlinkage long sys_getsid(pid_t pid)
{
if (!pid)
- return process_session(current);
+ return task_session_vnr(current);
else {
int retval;
struct task_struct *p;
+ struct pid_namespace *ns;
- read_lock(&tasklist_lock);
- p = find_task_by_pid(pid);
+ ns = current->nsproxy->pid_ns;
+ read_lock(&tasklist_lock);
+ p = find_task_by_pid_ns(pid, ns);
retval = -ESRCH;
if (p) {
retval = security_task_getsid(p);
if (!retval)
- retval = process_session(p);
+ retval = task_session_nr_ns(p, ns);
}
read_unlock(&tasklist_lock);
return retval;
@@ -1586,7 +1065,8 @@ asmlinkage long sys_setsid(void)
* session id and so the check will always fail and make it so
* init cannot successfully call setsid.
*/
- if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session))
+ if (session > 1 && find_task_by_pid_type_ns(PIDTYPE_PGID,
+ session, &init_pid_ns))
goto out;
group_leader->signal->leader = 1;
@@ -1596,7 +1076,7 @@ asmlinkage long sys_setsid(void)
group_leader->signal->tty = NULL;
spin_unlock(&group_leader->sighand->siglock);
- err = process_group(group_leader);
+ err = task_pgrp_vnr(group_leader);
out:
write_unlock_irq(&tasklist_lock);
return err;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 067554bda8b..3b4efbe2644 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1888,7 +1888,7 @@ int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp,
return -EPERM;
}
- op = is_init(current) ? OP_SET : OP_AND;
+ op = is_global_init(current) ? OP_SET : OP_AND;
return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
do_proc_dointvec_bset_conv,&op);
}
@@ -2278,7 +2278,7 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp
pid_t tmp;
int r;
- tmp = pid_nr(cad_pid);
+ tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns);
r = __do_proc_dointvec(&tmp, table, write, filp, buffer,
lenp, ppos, NULL, NULL);
diff --git a/kernel/sysctl_check.c b/kernel/sysctl_check.c
index 3c9ef5a7d57..ed6fe51df77 100644
--- a/kernel/sysctl_check.c
+++ b/kernel/sysctl_check.c
@@ -731,7 +731,7 @@ static struct trans_ctl_table trans_net_table[] = {
{ NET_UNIX, "unix", trans_net_unix_table },
{ NET_IPV4, "ipv4", trans_net_ipv4_table },
{ NET_IPX, "ipx", trans_net_ipx_table },
- { NET_ATALK, "atalk", trans_net_atalk_table },
+ { NET_ATALK, "appletalk", trans_net_atalk_table },
{ NET_NETROM, "netrom", trans_net_netrom_table },
{ NET_AX25, "ax25", trans_net_ax25_table },
{ NET_BRIDGE, "bridge", trans_net_bridge_table },
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 7d4d7f9c1bb..354e74bc17c 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -22,6 +22,10 @@
#include <linux/delayacct.h>
#include <linux/cpumask.h>
#include <linux/percpu.h>
+#include <linux/cgroupstats.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/file.h>
#include <net/genetlink.h>
#include <asm/atomic.h>
@@ -49,6 +53,11 @@ __read_mostly = {
[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
+static struct nla_policy
+cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] __read_mostly = {
+ [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
+};
+
struct listener {
struct list_head list;
pid_t pid;
@@ -254,7 +263,7 @@ out:
stats->version = TASKSTATS_VERSION;
/*
- * Accounting subsytems can also add calls here to modify
+ * Accounting subsystems can also add calls here to modify
* fields of taskstats.
*/
return rc;
@@ -372,6 +381,51 @@ err:
return NULL;
}
+static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+ int rc = 0;
+ struct sk_buff *rep_skb;
+ struct cgroupstats *stats;
+ struct nlattr *na;
+ size_t size;
+ u32 fd;
+ struct file *file;
+ int fput_needed;
+
+ na = info->attrs[CGROUPSTATS_CMD_ATTR_FD];
+ if (!na)
+ return -EINVAL;
+
+ fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]);
+ file = fget_light(fd, &fput_needed);
+ if (file) {
+ size = nla_total_size(sizeof(struct cgroupstats));
+
+ rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
+ size);
+ if (rc < 0)
+ goto err;
+
+ na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS,
+ sizeof(struct cgroupstats));
+ stats = nla_data(na);
+ memset(stats, 0, sizeof(*stats));
+
+ rc = cgroupstats_build(stats, file->f_dentry);
+ if (rc < 0)
+ goto err;
+
+ fput_light(file, fput_needed);
+ return send_reply(rep_skb, info->snd_pid);
+ }
+
+err:
+ if (file)
+ fput_light(file, fput_needed);
+ nlmsg_free(rep_skb);
+ return rc;
+}
+
static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
{
int rc = 0;
@@ -522,6 +576,12 @@ static struct genl_ops taskstats_ops = {
.policy = taskstats_cmd_get_policy,
};
+static struct genl_ops cgroupstats_ops = {
+ .cmd = CGROUPSTATS_CMD_GET,
+ .doit = cgroupstats_user_cmd,
+ .policy = cgroupstats_cmd_get_policy,
+};
+
/* Needed early in initialization */
void __init taskstats_init_early(void)
{
@@ -546,8 +606,15 @@ static int __init taskstats_init(void)
if (rc < 0)
goto err;
+ rc = genl_register_ops(&family, &cgroupstats_ops);
+ if (rc < 0)
+ goto err_cgroup_ops;
+
family_registered = 1;
+ printk("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
return 0;
+err_cgroup_ops:
+ genl_unregister_ops(&family, &taskstats_ops);
err:
genl_unregister_family(&family);
return rc;
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 51b6a6a6158..c8a9d13874d 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -207,15 +207,12 @@ static inline void clocksource_resume_watchdog(void) { }
*/
void clocksource_resume(void)
{
- struct list_head *tmp;
+ struct clocksource *cs;
unsigned long flags;
spin_lock_irqsave(&clocksource_lock, flags);
- list_for_each(tmp, &clocksource_list) {
- struct clocksource *cs;
-
- cs = list_entry(tmp, struct clocksource, list);
+ list_for_each_entry(cs, &clocksource_list, list) {
if (cs->resume)
cs->resume();
}
@@ -369,7 +366,6 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
const char *buf, size_t count)
{
struct clocksource *ovr = NULL;
- struct list_head *tmp;
size_t ret = count;
int len;
@@ -389,12 +385,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
len = strlen(override_name);
if (len) {
+ struct clocksource *cs;
+
ovr = clocksource_override;
/* try to select it: */
- list_for_each(tmp, &clocksource_list) {
- struct clocksource *cs;
-
- cs = list_entry(tmp, struct clocksource, list);
+ list_for_each_entry(cs, &clocksource_list, list) {
if (strlen(cs->name) == len &&
!strcmp(cs->name, override_name))
ovr = cs;
@@ -422,14 +417,11 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
static ssize_t
sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
{
- struct list_head *tmp;
+ struct clocksource *src;
char *curr = buf;
spin_lock_irq(&clocksource_lock);
- list_for_each(tmp, &clocksource_list) {
- struct clocksource *src;
-
- src = list_entry(tmp, struct clocksource, list);
+ list_for_each_entry(src, &clocksource_list, list) {
curr += sprintf(curr, "%s ", src->name);
}
spin_unlock_irq(&clocksource_lock);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index ce89ffb474d..10a1347597f 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -153,6 +153,7 @@ void tick_nohz_stop_sched_tick(void)
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
struct tick_sched *ts;
ktime_t last_update, expires, now, delta;
+ struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
int cpu;
local_irq_save(flags);
@@ -302,11 +303,26 @@ void tick_nohz_stop_sched_tick(void)
out:
ts->next_jiffies = next_jiffies;
ts->last_jiffies = last_jiffies;
+ ts->sleep_length = ktime_sub(dev->next_event, now);
end:
local_irq_restore(flags);
}
/**
+ * tick_nohz_get_sleep_length - return the length of the current sleep
+ *
+ * Called from power state control code with interrupts disabled
+ */
+ktime_t tick_nohz_get_sleep_length(void)
+{
+ struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
+
+ return ts->sleep_length;
+}
+
+EXPORT_SYMBOL_GPL(tick_nohz_get_sleep_length);
+
+/**
* nohz_restart_sched_tick - restart the idle tick from the idle task
*
* Restart the idle tick when the CPU is woken up from idle
diff --git a/kernel/timer.c b/kernel/timer.c
index 8521d10fbb2..fb4e67d5dd6 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -26,6 +26,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/pid_namespace.h>
#include <linux/notifier.h>
#include <linux/thread_info.h>
#include <linux/time.h>
@@ -956,7 +957,7 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds)
*/
asmlinkage long sys_getpid(void)
{
- return current->tgid;
+ return task_tgid_vnr(current);
}
/*
@@ -970,7 +971,7 @@ asmlinkage long sys_getppid(void)
int pid;
rcu_read_lock();
- pid = rcu_dereference(current->real_parent)->tgid;
+ pid = task_ppid_nr_ns(current, current->nsproxy->pid_ns);
rcu_read_unlock();
return pid;
@@ -1102,7 +1103,7 @@ EXPORT_SYMBOL(schedule_timeout_uninterruptible);
/* Thread ID - the internal kernel "pid" */
asmlinkage long sys_gettid(void)
{
- return current->pid;
+ return task_pid_vnr(current);
}
/**
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index e080d1d744c..52d5e7c9a8e 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -32,6 +32,7 @@
#include <linux/freezer.h>
#include <linux/kallsyms.h>
#include <linux/debug_locks.h>
+#include <linux/lockdep.h>
/*
* The per-CPU workqueue (if single thread, we always use the first
@@ -61,6 +62,9 @@ struct workqueue_struct {
const char *name;
int singlethread;
int freezeable; /* Freeze threads during suspend */
+#ifdef CONFIG_LOCKDEP
+ struct lockdep_map lockdep_map;
+#endif
};
/* All the per-cpu workqueues on the system, for hotplug cpu to add/remove
@@ -250,6 +254,17 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
struct work_struct *work = list_entry(cwq->worklist.next,
struct work_struct, entry);
work_func_t f = work->func;
+#ifdef CONFIG_LOCKDEP
+ /*
+ * It is permissible to free the struct work_struct
+ * from inside the function that is called from it,
+ * this we need to take into account for lockdep too.
+ * To avoid bogus "held lock freed" warnings as well
+ * as problems when looking into work->lockdep_map,
+ * make a copy and use that here.
+ */
+ struct lockdep_map lockdep_map = work->lockdep_map;
+#endif
cwq->current_work = work;
list_del_init(cwq->worklist.next);
@@ -257,13 +272,17 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
BUG_ON(get_wq_data(work) != cwq);
work_clear_pending(work);
+ lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+ lock_acquire(&lockdep_map, 0, 0, 0, 2, _THIS_IP_);
f(work);
+ lock_release(&lockdep_map, 1, _THIS_IP_);
+ lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
printk(KERN_ERR "BUG: workqueue leaked lock or atomic: "
"%s/0x%08x/%d\n",
current->comm, preempt_count(),
- current->pid);
+ task_pid_nr(current));
printk(KERN_ERR " last function: ");
print_symbol("%s\n", (unsigned long)f);
debug_show_held_locks(current);
@@ -376,6 +395,8 @@ void fastcall flush_workqueue(struct workqueue_struct *wq)
int cpu;
might_sleep();
+ lock_acquire(&wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+ lock_release(&wq->lockdep_map, 1, _THIS_IP_);
for_each_cpu_mask(cpu, *cpu_map)
flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu));
}
@@ -446,6 +467,9 @@ static void wait_on_work(struct work_struct *work)
might_sleep();
+ lock_acquire(&work->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+ lock_release(&work->lockdep_map, 1, _THIS_IP_);
+
cwq = get_wq_data(work);
if (!cwq)
return;
@@ -695,8 +719,10 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
}
}
-struct workqueue_struct *__create_workqueue(const char *name,
- int singlethread, int freezeable)
+struct workqueue_struct *__create_workqueue_key(const char *name,
+ int singlethread,
+ int freezeable,
+ struct lock_class_key *key)
{
struct workqueue_struct *wq;
struct cpu_workqueue_struct *cwq;
@@ -713,6 +739,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
}
wq->name = name;
+ lockdep_init_map(&wq->lockdep_map, name, key, 0);
wq->singlethread = singlethread;
wq->freezeable = freezeable;
INIT_LIST_HEAD(&wq->list);
@@ -741,7 +768,7 @@ struct workqueue_struct *__create_workqueue(const char *name,
}
return wq;
}
-EXPORT_SYMBOL_GPL(__create_workqueue);
+EXPORT_SYMBOL_GPL(__create_workqueue_key);
static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
{
@@ -752,6 +779,9 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu)
if (cwq->thread == NULL)
return;
+ lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_);
+ lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_);
+
flush_cpu_workqueue(cwq);
/*
* If the caller is CPU_DEAD and cwq->worklist was not empty,
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 7d16e643330..1faa5087dc8 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -389,6 +389,16 @@ config DEBUG_LIST
If unsure, say N.
+config DEBUG_SG
+ bool "Debug SG table operations"
+ depends on DEBUG_KERNEL
+ help
+ Enable this to turn on checks on scatter-gather tables. This can
+ help find problems with drivers that do not properly initialize
+ their sg tables.
+
+ If unsure, say N.
+
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32 || SUPERH || BFIN)
@@ -498,3 +508,5 @@ config FAULT_INJECTION_STACKTRACE_FILTER
select FRAME_POINTER
help
Provide stacktrace filter for fault-injection capabilities
+
+source "samples/Kconfig"
diff --git a/lib/Makefile b/lib/Makefile
index c5f215d509d..3a0983b7741 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \
sha1.o irq_regs.o reciprocal_div.o argv_split.o \
- proportions.o
+ proportions.o prio_heap.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/argv_split.c b/lib/argv_split.c
index fad6ce4f7b5..5205a8dae5b 100644
--- a/lib/argv_split.c
+++ b/lib/argv_split.c
@@ -4,7 +4,8 @@
#include <linux/kernel.h>
#include <linux/ctype.h>
-#include <linux/bug.h>
+#include <linux/slab.h>
+#include <linux/module.h>
static const char *skip_sep(const char *cp)
{
diff --git a/lib/hweight.c b/lib/hweight.c
index 360556a7803..389424ecb12 100644
--- a/lib/hweight.c
+++ b/lib/hweight.c
@@ -1,6 +1,6 @@
#include <linux/module.h>
+#include <linux/bitops.h>
#include <asm/types.h>
-#include <asm/bitops.h>
/**
* hweightN - returns the hamming weight of a N-bit word
diff --git a/lib/kernel_lock.c b/lib/kernel_lock.c
index e0fdfddb406..f73e2f8c308 100644
--- a/lib/kernel_lock.c
+++ b/lib/kernel_lock.c
@@ -2,7 +2,7 @@
* lib/kernel_lock.c
*
* This is the traditional BKL - big kernel lock. Largely
- * relegated to obsolescense, but used by various less
+ * relegated to obsolescence, but used by various less
* important (or lazy) subsystems.
*/
#include <linux/smp_lock.h>
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 2e4eae5b082..5886147252d 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -126,7 +126,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
else
subsystem = kobject_name(&kset->kobj);
if (!subsystem) {
- pr_debug("unset subsytem caused the event to drop!\n");
+ pr_debug("unset subsystem caused the event to drop!\n");
return 0;
}
diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c
index 9659eabffc3..393a0e915c2 100644
--- a/lib/percpu_counter.c
+++ b/lib/percpu_counter.c
@@ -124,12 +124,13 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb,
mutex_lock(&percpu_counters_lock);
list_for_each_entry(fbc, &percpu_counters, list) {
s32 *pcount;
+ unsigned long flags;
- spin_lock(&fbc->lock);
+ spin_lock_irqsave(&fbc->lock, flags);
pcount = per_cpu_ptr(fbc->counters, cpu);
fbc->count += *pcount;
*pcount = 0;
- spin_unlock(&fbc->lock);
+ spin_unlock_irqrestore(&fbc->lock, flags);
}
mutex_unlock(&percpu_counters_lock);
return NOTIFY_OK;
diff --git a/lib/prio_heap.c b/lib/prio_heap.c
new file mode 100644
index 00000000000..471944a54e2
--- /dev/null
+++ b/lib/prio_heap.c
@@ -0,0 +1,70 @@
+/*
+ * Simple insertion-only static-sized priority heap containing
+ * pointers, based on CLR, chapter 7
+ */
+
+#include <linux/slab.h>
+#include <linux/prio_heap.h>
+
+int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask,
+ int (*gt)(void *, void *))
+{
+ heap->ptrs = kmalloc(size, gfp_mask);
+ if (!heap->ptrs)
+ return -ENOMEM;
+ heap->size = 0;
+ heap->max = size / sizeof(void *);
+ heap->gt = gt;
+ return 0;
+}
+
+void heap_free(struct ptr_heap *heap)
+{
+ kfree(heap->ptrs);
+}
+
+void *heap_insert(struct ptr_heap *heap, void *p)
+{
+ void *res;
+ void **ptrs = heap->ptrs;
+ int pos;
+
+ if (heap->size < heap->max) {
+ /* Heap insertion */
+ int pos = heap->size++;
+ while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) {
+ ptrs[pos] = ptrs[(pos-1)/2];
+ pos = (pos-1)/2;
+ }
+ ptrs[pos] = p;
+ return NULL;
+ }
+
+ /* The heap is full, so something will have to be dropped */
+
+ /* If the new pointer is greater than the current max, drop it */
+ if (heap->gt(p, ptrs[0]))
+ return p;
+
+ /* Replace the current max and heapify */
+ res = ptrs[0];
+ ptrs[0] = p;
+ pos = 0;
+
+ while (1) {
+ int left = 2 * pos + 1;
+ int right = 2 * pos + 2;
+ int largest = pos;
+ if (left < heap->size && heap->gt(ptrs[left], p))
+ largest = left;
+ if (right < heap->size && heap->gt(ptrs[right], ptrs[largest]))
+ largest = right;
+ if (largest == pos)
+ break;
+ /* Push p down the heap one level and bump one up */
+ ptrs[pos] = ptrs[largest];
+ ptrs[largest] = p;
+ pos = largest;
+ }
+ return res;
+}
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 479fd462eaa..9c4b0256490 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -60,12 +60,12 @@ static void spin_bug(spinlock_t *lock, const char *msg)
owner = lock->owner;
printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n",
msg, raw_smp_processor_id(),
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, "
".owner_cpu: %d\n",
lock, lock->magic,
owner ? owner->comm : "<none>",
- owner ? owner->pid : -1,
+ owner ? task_pid_nr(owner) : -1,
lock->owner_cpu);
dump_stack();
}
@@ -116,7 +116,7 @@ static void __spin_lock_debug(spinlock_t *lock)
printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, "
"%s/%d, %p\n",
raw_smp_processor_id(), current->comm,
- current->pid, lock);
+ task_pid_nr(current), lock);
dump_stack();
#ifdef CONFIG_SMP
trigger_all_cpu_backtrace();
@@ -161,7 +161,7 @@ static void rwlock_bug(rwlock_t *lock, const char *msg)
printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n",
msg, raw_smp_processor_id(), current->comm,
- current->pid, lock);
+ task_pid_nr(current), lock);
dump_stack();
}
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 752fd95323f..1a8050ade86 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -35,7 +35,7 @@
#define OFFSET(val,align) ((unsigned long) \
( (val) & ( (align) - 1)))
-#define SG_ENT_VIRT_ADDRESS(sg) (page_address((sg)->page) + (sg)->offset)
+#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
#define SG_ENT_PHYS_ADDRESS(sg) virt_to_bus(SG_ENT_VIRT_ADDRESS(sg))
/*
diff --git a/mm/Kconfig b/mm/Kconfig
index b1f03b0eb7f..c070ec0c15b 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -37,7 +37,7 @@ config DISCONTIGMEM_MANUAL
in their physical address spaces, and this option provides
more efficient handling of these holes. However, the vast
majority of hardware has quite flat address spaces, and
- can have degraded performance from extra overhead that
+ can have degraded performance from the extra overhead that
this option imposes.
Many NUMA configurations will have this as the only option.
diff --git a/mm/filemap.c b/mm/filemap.c
index 920366399ee..5209e47b7fe 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -841,7 +841,7 @@ static void shrink_readahead_size_eio(struct file *filp,
/**
* do_generic_mapping_read - generic file read routine
* @mapping: address_space to be read
- * @_ra: file's readahead state
+ * @ra: file's readahead state
* @filp: the file to read
* @ppos: current file position
* @desc: read_descriptor
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 034617f8cdb..8b809ecefa3 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1017,7 +1017,7 @@ static long region_chg(struct list_head *head, long f, long t)
/* If we are below the current region then a new region is required.
* Subtle, allocate a new region at the position but make it zero
- * size such that we can guarentee to record the reservation. */
+ * size such that we can guarantee to record the reservation. */
if (&rg->link == head || t < rg->from) {
nrg = kmalloc(sizeof(*nrg), GFP_KERNEL);
if (!nrg)
diff --git a/mm/memory.c b/mm/memory.c
index bd16dcaeefb..eefd5b68bc4 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -259,9 +259,6 @@ void free_pgd_range(struct mmu_gather **tlb,
continue;
free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
} while (pgd++, addr = next, addr != end);
-
- if (!(*tlb)->fullmm)
- flush_tlb_pgtables((*tlb)->mm, start, end);
}
void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma,
@@ -2716,7 +2713,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
return 0;
down_read(&mm->mmap_sem);
- /* ignore errors, just check how much was sucessfully transfered */
+ /* ignore errors, just check how much was successfully transferred */
while (len) {
int bytes, ret, offset;
void *maddr;
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 091b9c6c252..3a47871a29d 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -121,7 +121,7 @@ int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
err = __add_section(zone, i << PFN_SECTION_SHIFT);
/*
- * EEXIST is finally dealed with by ioresource collision
+ * EEXIST is finally dealt with by ioresource collision
* check. see add_memory() => register_memory_resource()
* Warning will be printed if there is collision.
*/
@@ -187,7 +187,24 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
unsigned long onlined_pages = 0;
struct zone *zone;
int need_zonelists_rebuild = 0;
+ int nid;
+ int ret;
+ struct memory_notify arg;
+
+ arg.start_pfn = pfn;
+ arg.nr_pages = nr_pages;
+ arg.status_change_nid = -1;
+
+ nid = page_to_nid(pfn_to_page(pfn));
+ if (node_present_pages(nid) == 0)
+ arg.status_change_nid = nid;
+ ret = memory_notify(MEM_GOING_ONLINE, &arg);
+ ret = notifier_to_errno(ret);
+ if (ret) {
+ memory_notify(MEM_CANCEL_ONLINE, &arg);
+ return ret;
+ }
/*
* This doesn't need a lock to do pfn_to_page().
* The section can't be removed here because of the
@@ -222,6 +239,10 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
build_all_zonelists();
vm_total_pages = nr_free_pagecache_pages();
writeback_set_ratelimit();
+
+ if (onlined_pages)
+ memory_notify(MEM_ONLINE, &arg);
+
return 0;
}
#endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */
@@ -467,8 +488,9 @@ int offline_pages(unsigned long start_pfn,
{
unsigned long pfn, nr_pages, expire;
long offlined_pages;
- int ret, drain, retry_max;
+ int ret, drain, retry_max, node;
struct zone *zone;
+ struct memory_notify arg;
BUG_ON(start_pfn >= end_pfn);
/* at least, alignment against pageblock is necessary */
@@ -480,11 +502,27 @@ int offline_pages(unsigned long start_pfn,
we assume this for now. .*/
if (!test_pages_in_a_zone(start_pfn, end_pfn))
return -EINVAL;
+
+ zone = page_zone(pfn_to_page(start_pfn));
+ node = zone_to_nid(zone);
+ nr_pages = end_pfn - start_pfn;
+
/* set above range as isolated */
ret = start_isolate_page_range(start_pfn, end_pfn);
if (ret)
return ret;
- nr_pages = end_pfn - start_pfn;
+
+ arg.start_pfn = start_pfn;
+ arg.nr_pages = nr_pages;
+ arg.status_change_nid = -1;
+ if (nr_pages >= node_present_pages(node))
+ arg.status_change_nid = node;
+
+ ret = memory_notify(MEM_GOING_OFFLINE, &arg);
+ ret = notifier_to_errno(ret);
+ if (ret)
+ goto failed_removal;
+
pfn = start_pfn;
expire = jiffies + timeout;
drain = 0;
@@ -539,20 +577,24 @@ repeat:
/* reset pagetype flags */
start_isolate_page_range(start_pfn, end_pfn);
/* removal success */
- zone = page_zone(pfn_to_page(start_pfn));
zone->present_pages -= offlined_pages;
zone->zone_pgdat->node_present_pages -= offlined_pages;
totalram_pages -= offlined_pages;
num_physpages -= offlined_pages;
+
vm_total_pages = nr_free_pagecache_pages();
writeback_set_ratelimit();
+
+ memory_notify(MEM_OFFLINE, &arg);
return 0;
failed_removal:
printk(KERN_INFO "memory offlining %lx to %lx failed\n",
start_pfn, end_pfn);
+ memory_notify(MEM_CANCEL_OFFLINE, &arg);
/* pushback to free area */
undo_isolate_page_range(start_pfn, end_pfn);
+
return ret;
}
#else
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 568152ae6ca..c1592a94582 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -78,6 +78,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/module.h>
+#include <linux/nsproxy.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/compat.h>
@@ -940,7 +941,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
/* Find the mm_struct */
read_lock(&tasklist_lock);
- task = pid ? find_task_by_pid(pid) : current;
+ task = pid ? find_task_by_vpid(pid) : current;
if (!task) {
read_unlock(&tasklist_lock);
return -ESRCH;
@@ -1388,7 +1389,6 @@ EXPORT_SYMBOL(alloc_pages_current);
* keeps mempolicies cpuset relative after its cpuset moves. See
* further kernel/cpuset.c update_nodemask().
*/
-void *cpuset_being_rebound;
/* Slow path of a mempolicy copy */
struct mempolicy *__mpol_copy(struct mempolicy *old)
@@ -2019,4 +2019,3 @@ out:
m->version = (vma != priv->tail_vma) ? vma->vm_start : 0;
return 0;
}
-
diff --git a/mm/mempool.c b/mm/mempool.c
index 02d5ec3feab..a46eb1b4bb6 100644
--- a/mm/mempool.c
+++ b/mm/mempool.c
@@ -299,7 +299,7 @@ EXPORT_SYMBOL(mempool_free_slab);
/*
* A commonly used alloc and free fn that kmalloc/kfrees the amount of memory
- * specfied by pool_data
+ * specified by pool_data
*/
void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data)
{
diff --git a/mm/migrate.c b/mm/migrate.c
index 06d0877a66e..6a207e8d17e 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -19,6 +19,7 @@
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/mm_inline.h>
+#include <linux/nsproxy.h>
#include <linux/pagevec.h>
#include <linux/rmap.h>
#include <linux/topology.h>
@@ -705,7 +706,7 @@ move_newpage:
* The function returns after 10 attempts or if no pages
* are movable anymore because to has become empty
* or no retryable pages exist anymore. All pages will be
- * retruned to the LRU or freed.
+ * returned to the LRU or freed.
*
* Return: Number of pages not migrated or error code.
*/
@@ -924,7 +925,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
/* Find the mm_struct */
read_lock(&tasklist_lock);
- task = pid ? find_task_by_pid(pid) : current;
+ task = pid ? find_task_by_vpid(pid) : current;
if (!task) {
read_unlock(&tasklist_lock);
return -ESRCH;
diff --git a/mm/mmap.c b/mm/mmap.c
index 4275e81e25b..7a30c498823 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1048,8 +1048,7 @@ int vma_wants_writenotify(struct vm_area_struct *vma)
/* The open routine did something to the protections already? */
if (pgprot_val(vma->vm_page_prot) !=
- pgprot_val(protection_map[vm_flags &
- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
+ pgprot_val(vm_get_page_prot(vm_flags)))
return 0;
/* Specialty mapping? */
@@ -1130,8 +1129,7 @@ munmap_back:
vma->vm_start = addr;
vma->vm_end = addr + len;
vma->vm_flags = vm_flags;
- vma->vm_page_prot = protection_map[vm_flags &
- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+ vma->vm_page_prot = vm_get_page_prot(vm_flags);
vma->vm_pgoff = pgoff;
if (file) {
@@ -2002,8 +2000,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
vma->vm_end = addr + len;
vma->vm_pgoff = pgoff;
vma->vm_flags = flags;
- vma->vm_page_prot = protection_map[flags &
- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+ vma->vm_page_prot = vm_get_page_prot(flags);
vma_link(mm, vma, prev, rb_link, rb_parent);
out:
mm->total_vm += len >> PAGE_SHIFT;
@@ -2209,7 +2206,7 @@ int install_special_mapping(struct mm_struct *mm,
vma->vm_end = addr + len;
vma->vm_flags = vm_flags | mm->def_flags;
- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
vma->vm_ops = &special_mapping_vmops;
vma->vm_private_data = pages;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index 1d4d69790e5..55227845abb 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -192,11 +192,9 @@ success:
* held in write mode.
*/
vma->vm_flags = newflags;
- vma->vm_page_prot = protection_map[newflags &
- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
+ vma->vm_page_prot = vm_get_page_prot(newflags);
if (vma_wants_writenotify(vma)) {
- vma->vm_page_prot = protection_map[newflags &
- (VM_READ|VM_WRITE|VM_EXEC)];
+ vma->vm_page_prot = vm_get_page_prot(newflags);
dirty_accountable = 1;
}
diff --git a/mm/nommu.c b/mm/nommu.c
index 42fb84e9e81..8f09333f78e 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -175,7 +175,8 @@ EXPORT_SYMBOL(vfree);
void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
{
/*
- * kmalloc doesn't like __GFP_HIGHMEM for some reason
+ * You can't specify __GFP_HIGHMEM with kmalloc() since kmalloc()
+ * returns only a logical address.
*/
return kmalloc(size, (gfp_mask | __GFP_COMP) & ~__GFP_HIGHMEM);
}
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index a64decb5b13..91a081a82f5 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -212,7 +212,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
if (!p->mm)
continue;
/* skip the init task */
- if (is_init(p))
+ if (is_global_init(p))
continue;
/*
@@ -265,7 +265,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints)
*/
static void __oom_kill_task(struct task_struct *p, int verbose)
{
- if (is_init(p)) {
+ if (is_global_init(p)) {
WARN_ON(1);
printk(KERN_WARNING "tried to kill init!\n");
return;
@@ -278,7 +278,8 @@ static void __oom_kill_task(struct task_struct *p, int verbose)
}
if (verbose)
- printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm);
+ printk(KERN_ERR "Killed process %d (%s)\n",
+ task_pid_nr(p), p->comm);
/*
* We give our sacrificial lamb high priority and access to
@@ -326,7 +327,7 @@ static int oom_kill_task(struct task_struct *p)
* to memory reserves though, otherwise we might deplete all memory.
*/
do_each_thread(g, q) {
- if (q->mm == mm && q->tgid != p->tgid)
+ if (q->mm == mm && !same_thread_group(q, p))
force_sig(SIGKILL, q);
} while_each_thread(g, q);
@@ -337,7 +338,6 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
unsigned long points, const char *message)
{
struct task_struct *c;
- struct list_head *tsk;
if (printk_ratelimit()) {
printk(KERN_WARNING "%s invoked oom-killer: "
@@ -357,11 +357,10 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
}
printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n",
- message, p->pid, p->comm, points);
+ message, task_pid_nr(p), p->comm, points);
/* Try to kill a child first */
- list_for_each(tsk, &p->children) {
- c = list_entry(tsk, struct task_struct, sibling);
+ list_for_each_entry(c, &p->children, sibling) {
if (c->mm == p->mm)
continue;
if (!oom_kill_task(c))
@@ -497,7 +496,7 @@ retry:
panic("Out of memory and no killable processes...\n");
}
- if (oom_kill_process(p, points, gfp_mask, order,
+ if (oom_kill_process(p, gfp_mask, order, points,
"Out of memory"))
goto retry;
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 7845462064f..838a5e31394 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -989,7 +989,7 @@ int __set_page_dirty_no_writeback(struct page *page)
* mapping is pinned by the vma's ->vm_file reference.
*
* We take care to handle the case where the page was truncated from the
- * mapping by re-checking page_mapping() insode tree_lock.
+ * mapping by re-checking page_mapping() inside tree_lock.
*/
int __set_page_dirty_nobuffers(struct page *page)
{
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 43f757fcf30..da69d833e06 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -123,7 +123,7 @@ static unsigned long __meminitdata dma_reserve;
#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
/*
- * MAX_ACTIVE_REGIONS determines the maxmimum number of distinct
+ * MAX_ACTIVE_REGIONS determines the maximum number of distinct
* ranges of memory (RAM) that may be registered with add_active_range().
* Ranges passed to add_active_range() will be merged if possible
* so the number of times add_active_range() can be called is
@@ -1260,7 +1260,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
* skip over zones that are not allowed by the cpuset, or that have
* been recently (in last second) found to be nearly full. See further
* comments in mmzone.h. Reduces cache footprint of zonelist scans
- * that have to skip over alot of full or unallowed zones.
+ * that have to skip over a lot of full or unallowed zones.
*
* If the zonelist cache is present in the passed in zonelist, then
* returns a pointer to the allowed node mask (either the current
@@ -2358,7 +2358,7 @@ void build_all_zonelists(void)
__build_all_zonelists(NULL);
cpuset_init_current_mems_allowed();
} else {
- /* we have to stop all cpus to guaranntee there is no user
+ /* we have to stop all cpus to guarantee there is no user
of zonelist */
stop_machine_run(__build_all_zonelists, NULL, NR_CPUS);
/* cpuset refresh routine should be here */
@@ -2864,7 +2864,7 @@ static int __meminit first_active_region_index_in_nid(int nid)
/*
* Basic iterator support. Return the next active range of PFNs for a node
- * Note: nid == MAX_NUMNODES returns next region regardles of node
+ * Note: nid == MAX_NUMNODES returns next region regardless of node
*/
static int __meminit next_active_region_index_in_nid(int index, int nid)
{
diff --git a/mm/prio_tree.c b/mm/prio_tree.c
index b4e76c25f95..603ae98d969 100644
--- a/mm/prio_tree.c
+++ b/mm/prio_tree.c
@@ -34,7 +34,7 @@
* Radix priority search tree for address_space->i_mmap
*
* For each vma that map a unique set of file pages i.e., unique [radix_index,
- * heap_index] value, we have a corresponing priority search tree node. If
+ * heap_index] value, we have a corresponding priority search tree node. If
* multiple vmas have identical [radix_index, heap_index] value, then one of
* them is used as a tree node and others are stored in a vm_set list. The tree
* node points to the first vma (head) of the list using vm_set.head.
diff --git a/mm/shmem.c b/mm/shmem.c
index 289dbb0a6fd..404e53bb212 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2020,33 +2020,25 @@ static int shmem_match(struct inode *ino, void *vfh)
return ino->i_ino == inum && fh[0] == ino->i_generation;
}
-static struct dentry *shmem_get_dentry(struct super_block *sb, void *vfh)
+static struct dentry *shmem_fh_to_dentry(struct super_block *sb,
+ struct fid *fid, int fh_len, int fh_type)
{
- struct dentry *de = NULL;
struct inode *inode;
- __u32 *fh = vfh;
- __u64 inum = fh[2];
- inum = (inum << 32) | fh[1];
+ struct dentry *dentry = NULL;
+ u64 inum = fid->raw[2];
+ inum = (inum << 32) | fid->raw[1];
+
+ if (fh_len < 3)
+ return NULL;
- inode = ilookup5(sb, (unsigned long)(inum+fh[0]), shmem_match, vfh);
+ inode = ilookup5(sb, (unsigned long)(inum + fid->raw[0]),
+ shmem_match, fid->raw);
if (inode) {
- de = d_find_alias(inode);
+ dentry = d_find_alias(inode);
iput(inode);
}
- return de? de: ERR_PTR(-ESTALE);
-}
-
-static struct dentry *shmem_decode_fh(struct super_block *sb, __u32 *fh,
- int len, int type,
- int (*acceptable)(void *context, struct dentry *de),
- void *context)
-{
- if (len < 3)
- return ERR_PTR(-ESTALE);
-
- return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable,
- context);
+ return dentry;
}
static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
@@ -2079,11 +2071,10 @@ static int shmem_encode_fh(struct dentry *dentry, __u32 *fh, int *len,
return 1;
}
-static struct export_operations shmem_export_ops = {
+static const struct export_operations shmem_export_ops = {
.get_parent = shmem_get_parent,
- .get_dentry = shmem_get_dentry,
.encode_fh = shmem_encode_fh,
- .decode_fh = shmem_decode_fh,
+ .fh_to_dentry = shmem_fh_to_dentry,
};
static int shmem_parse_options(char *options, int *mode, uid_t *uid,
diff --git a/mm/slab.c b/mm/slab.c
index 54eb555c4ef..cfa6be4e378 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -26,7 +26,7 @@
* initialized objects.
*
* This means, that your constructor is used only for newly allocated
- * slabs and you must pass objects with the same intializations to
+ * slabs and you must pass objects with the same initializations to
* kmem_cache_free.
*
* Each cache can only support one memory type (GFP_DMA, GFP_HIGHMEM,
@@ -1369,7 +1369,7 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb,
* structure is usually allocated from kmem_cache_create() and
* gets destroyed at kmem_cache_destroy().
*/
- /* fall thru */
+ /* fall through */
#endif
case CPU_UP_CANCELED:
case CPU_UP_CANCELED_FROZEN:
@@ -3806,7 +3806,7 @@ const char *kmem_cache_name(struct kmem_cache *cachep)
EXPORT_SYMBOL_GPL(kmem_cache_name);
/*
- * This initializes kmem_list3 or resizes varioius caches for all nodes.
+ * This initializes kmem_list3 or resizes various caches for all nodes.
*/
static int alloc_kmemlist(struct kmem_cache *cachep)
{
diff --git a/mm/slub.c b/mm/slub.c
index e29a42988c7..aac1dd3c657 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -20,6 +20,7 @@
#include <linux/mempolicy.h>
#include <linux/ctype.h>
#include <linux/kallsyms.h>
+#include <linux/memory.h>
/*
* Lock order:
@@ -2694,6 +2695,121 @@ int kmem_cache_shrink(struct kmem_cache *s)
}
EXPORT_SYMBOL(kmem_cache_shrink);
+#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
+static int slab_mem_going_offline_callback(void *arg)
+{
+ struct kmem_cache *s;
+
+ down_read(&slub_lock);
+ list_for_each_entry(s, &slab_caches, list)
+ kmem_cache_shrink(s);
+ up_read(&slub_lock);
+
+ return 0;
+}
+
+static void slab_mem_offline_callback(void *arg)
+{
+ struct kmem_cache_node *n;
+ struct kmem_cache *s;
+ struct memory_notify *marg = arg;
+ int offline_node;
+
+ offline_node = marg->status_change_nid;
+
+ /*
+ * If the node still has available memory. we need kmem_cache_node
+ * for it yet.
+ */
+ if (offline_node < 0)
+ return;
+
+ down_read(&slub_lock);
+ list_for_each_entry(s, &slab_caches, list) {
+ n = get_node(s, offline_node);
+ if (n) {
+ /*
+ * if n->nr_slabs > 0, slabs still exist on the node
+ * that is going down. We were unable to free them,
+ * and offline_pages() function shoudn't call this
+ * callback. So, we must fail.
+ */
+ BUG_ON(atomic_read(&n->nr_slabs));
+
+ s->node[offline_node] = NULL;
+ kmem_cache_free(kmalloc_caches, n);
+ }
+ }
+ up_read(&slub_lock);
+}
+
+static int slab_mem_going_online_callback(void *arg)
+{
+ struct kmem_cache_node *n;
+ struct kmem_cache *s;
+ struct memory_notify *marg = arg;
+ int nid = marg->status_change_nid;
+ int ret = 0;
+
+ /*
+ * If the node's memory is already available, then kmem_cache_node is
+ * already created. Nothing to do.
+ */
+ if (nid < 0)
+ return 0;
+
+ /*
+ * We are bringing a node online. No memory is availabe yet. We must
+ * allocate a kmem_cache_node structure in order to bring the node
+ * online.
+ */
+ down_read(&slub_lock);
+ list_for_each_entry(s, &slab_caches, list) {
+ /*
+ * XXX: kmem_cache_alloc_node will fallback to other nodes
+ * since memory is not yet available from the node that
+ * is brought up.
+ */
+ n = kmem_cache_alloc(kmalloc_caches, GFP_KERNEL);
+ if (!n) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ init_kmem_cache_node(n);
+ s->node[nid] = n;
+ }
+out:
+ up_read(&slub_lock);
+ return ret;
+}
+
+static int slab_memory_callback(struct notifier_block *self,
+ unsigned long action, void *arg)
+{
+ int ret = 0;
+
+ switch (action) {
+ case MEM_GOING_ONLINE:
+ ret = slab_mem_going_online_callback(arg);
+ break;
+ case MEM_GOING_OFFLINE:
+ ret = slab_mem_going_offline_callback(arg);
+ break;
+ case MEM_OFFLINE:
+ case MEM_CANCEL_ONLINE:
+ slab_mem_offline_callback(arg);
+ break;
+ case MEM_ONLINE:
+ case MEM_CANCEL_OFFLINE:
+ break;
+ }
+
+ ret = notifier_from_errno(ret);
+ return ret;
+}
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
+
/********************************************************************
* Basic setup of slabs
*******************************************************************/
@@ -2715,6 +2831,8 @@ void __init kmem_cache_init(void)
sizeof(struct kmem_cache_node), GFP_KERNEL);
kmalloc_caches[0].refcount = -1;
caches++;
+
+ hotplug_memory_notifier(slab_memory_callback, 1);
#endif
/* Able to allocate the per node structures */
diff --git a/mm/swap.c b/mm/swap.c
index a65eff8a517..9ac88323d23 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -5,7 +5,7 @@
*/
/*
- * This file contains the default values for the opereation of the
+ * This file contains the default values for the operation of the
* Linux VM subsystem. Fine-tuning documentation can be found in
* Documentation/sysctl/vm.txt.
* Started 18.12.91
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 2e01af36584..af77e171e33 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -247,7 +247,7 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
EXPORT_SYMBOL_GPL(__get_vm_area);
/**
- * get_vm_area - reserve a contingous kernel virtual area
+ * get_vm_area - reserve a contiguous kernel virtual area
* @size: size of the area
* @flags: %VM_IOREMAP for I/O mappings or VM_ALLOC
*
@@ -303,7 +303,7 @@ found:
}
/**
- * remove_vm_area - find and remove a contingous kernel virtual area
+ * remove_vm_area - find and remove a continuous kernel virtual area
* @addr: base address
*
* Search for the kernel VM area starting at @addr, and remove it.
@@ -364,7 +364,7 @@ static void __vunmap(void *addr, int deallocate_pages)
* vfree - release memory allocated by vmalloc()
* @addr: memory base address
*
- * Free the virtually contiguous memory area starting at @addr, as
+ * Free the virtually continuous memory area starting at @addr, as
* obtained from vmalloc(), vmalloc_32() or __vmalloc(). If @addr is
* NULL, no operation is performed.
*
diff --git a/mm/vmscan.c b/mm/vmscan.c
index cb474cc9964..e5a9597e3bb 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -141,7 +141,7 @@ EXPORT_SYMBOL(unregister_shrinker);
* percentages of the lru and ageable caches. This should balance the seeks
* generated by these structures.
*
- * If the vm encounted mapped pages on the LRU it increase the pressure on
+ * If the vm encountered mapped pages on the LRU it increase the pressure on
* slab to avoid swapping.
*
* We do weird things to avoid (scanned*seeks*entries) overflowing 32 bits.
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
index eecbf12f639..71bc110aebf 100644
--- a/net/9p/Kconfig
+++ b/net/9p/Kconfig
@@ -27,5 +27,5 @@ config NET_9P_DEBUG
bool "Debug information"
depends on NET_9P
help
- Say Y if you want the 9P subsistem to log debug information.
+ Say Y if you want the 9P subsystem to log debug information.
diff --git a/net/ax25/ax25_ds_in.c b/net/ax25/ax25_ds_in.c
index e37d217a986..8273b1200ee 100644
--- a/net/ax25/ax25_ds_in.c
+++ b/net/ax25/ax25_ds_in.c
@@ -75,7 +75,7 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
}
ax25_dama_on(ax25);
- /* according to DK4EGs spec we are required to
+ /* according to DK4EG's spec we are required to
* send a RR RESPONSE FINAL NR=0.
*/
diff --git a/net/ax25/ax25_ds_subr.c b/net/ax25/ax25_ds_subr.c
index a49773ff2b9..b5e59787be2 100644
--- a/net/ax25/ax25_ds_subr.c
+++ b/net/ax25/ax25_ds_subr.c
@@ -41,7 +41,7 @@ void ax25_ds_enquiry_response(ax25_cb *ax25)
ax25_cb *ax25o;
struct hlist_node *node;
- /* Please note that neither DK4EGs nor DG2FEFs
+ /* Please note that neither DK4EG's nor DG2FEF's
* DAMA spec mention the following behaviour as seen
* with TheFirmware:
*
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 1f78c3e336d..347e935faaf 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -2,7 +2,7 @@
BNEP implementation for Linux Bluetooth stack (BlueZ).
Copyright (C) 2001-2002 Inventel Systemes
Written 2001-2002 by
- Clment Moreau <clement.moreau@inventel.fr>
+ Clément Moreau <clement.moreau@inventel.fr>
David Libault <david.libault@inventel.fr>
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 9092816f58d..95e3837e431 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -2,7 +2,7 @@
BNEP implementation for Linux Bluetooth stack (BlueZ).
Copyright (C) 2001-2002 Inventel Systemes
Written 2001-2002 by
- Clment Moreau <clement.moreau@inventel.fr>
+ Clément Moreau <clement.moreau@inventel.fr>
David Libault <david.libault@inventel.fr>
Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 5fdfc9a67d3..9483320f6da 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -78,11 +78,11 @@ void hci_acl_connect(struct hci_conn *conn)
cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
- cp.role_switch = 0x01;
+ cp.role_switch = 0x01;
else
- cp.role_switch = 0x00;
+ cp.role_switch = 0x00;
- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_CREATE_CONN, sizeof(cp), &cp);
}
static void hci_acl_connect_cancel(struct hci_conn *conn)
@@ -95,8 +95,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn)
return;
bacpy(&cp.bdaddr, &conn->dst);
- hci_send_cmd(conn->hdev, OGF_LINK_CTL,
- OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_CREATE_CONN_CANCEL, sizeof(cp), &cp);
}
void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
@@ -109,8 +108,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
cp.handle = cpu_to_le16(conn->handle);
cp.reason = reason;
- hci_send_cmd(conn->hdev, OGF_LINK_CTL,
- OCF_DISCONNECT, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp);
}
void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -126,7 +124,29 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
cp.handle = cpu_to_le16(handle);
cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
+}
+
+void hci_setup_sync(struct hci_conn *conn, __u16 handle)
+{
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_cp_setup_sync_conn cp;
+
+ BT_DBG("%p", conn);
+
+ conn->state = BT_CONNECT;
+ conn->out = 1;
+
+ cp.handle = cpu_to_le16(handle);
+ cp.pkt_type = cpu_to_le16(hdev->esco_type);
+
+ cp.tx_bandwidth = cpu_to_le32(0x00001f40);
+ cp.rx_bandwidth = cpu_to_le32(0x00001f40);
+ cp.max_latency = cpu_to_le16(0xffff);
+ cp.voice_setting = cpu_to_le16(hdev->voice_setting);
+ cp.retrans_effort = 0xff;
+
+ hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp);
}
static void hci_conn_timeout(unsigned long arg)
@@ -143,7 +163,10 @@ static void hci_conn_timeout(unsigned long arg)
switch (conn->state) {
case BT_CONNECT:
- hci_acl_connect_cancel(conn);
+ if (conn->type == ACL_LINK)
+ hci_acl_connect_cancel(conn);
+ else
+ hci_acl_disconn(conn, 0x13);
break;
case BT_CONNECTED:
hci_acl_disconn(conn, 0x13);
@@ -330,8 +353,12 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
hci_conn_hold(sco);
if (acl->state == BT_CONNECTED &&
- (sco->state == BT_OPEN || sco->state == BT_CLOSED))
- hci_add_sco(sco, acl->handle);
+ (sco->state == BT_OPEN || sco->state == BT_CLOSED)) {
+ if (lmp_esco_capable(hdev))
+ hci_setup_sync(sco, acl->handle);
+ else
+ hci_add_sco(sco, acl->handle);
+ }
return sco;
}
@@ -348,7 +375,7 @@ int hci_conn_auth(struct hci_conn *conn)
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
cp.handle = cpu_to_le16(conn->handle);
- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
return 0;
}
@@ -369,7 +396,7 @@ int hci_conn_encrypt(struct hci_conn *conn)
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 1;
- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
}
return 0;
}
@@ -383,7 +410,7 @@ int hci_conn_change_link_key(struct hci_conn *conn)
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_change_conn_link_key cp;
cp.handle = cpu_to_le16(conn->handle);
- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp);
}
return 0;
}
@@ -401,7 +428,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role)
struct hci_cp_switch_role cp;
bacpy(&cp.bdaddr, &conn->dst);
cp.role = role;
- hci_send_cmd(conn->hdev, OGF_LINK_POLICY, OCF_SWITCH_ROLE, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp);
}
return 0;
}
@@ -423,8 +450,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn)
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
struct hci_cp_exit_sniff_mode cp;
cp.handle = cpu_to_le16(conn->handle);
- hci_send_cmd(hdev, OGF_LINK_POLICY,
- OCF_EXIT_SNIFF_MODE, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_EXIT_SNIFF_MODE, sizeof(cp), &cp);
}
timer:
@@ -455,8 +481,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn)
cp.max_latency = cpu_to_le16(0);
cp.min_remote_timeout = cpu_to_le16(0);
cp.min_local_timeout = cpu_to_le16(0);
- hci_send_cmd(hdev, OGF_LINK_POLICY,
- OCF_SNIFF_SUBRATE, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp);
}
if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
@@ -466,8 +491,7 @@ void hci_conn_enter_sniff_mode(struct hci_conn *conn)
cp.min_interval = cpu_to_le16(hdev->sniff_min_interval);
cp.attempt = cpu_to_le16(4);
cp.timeout = cpu_to_le16(1);
- hci_send_cmd(hdev, OGF_LINK_POLICY,
- OCF_SNIFF_MODE, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp);
}
}
@@ -493,6 +517,22 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
}
}
+/* Check pending connect attempts */
+void hci_conn_check_pending(struct hci_dev *hdev)
+{
+ struct hci_conn *conn;
+
+ BT_DBG("hdev %s", hdev->name);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
+ if (conn)
+ hci_acl_connect(conn);
+
+ hci_dev_unlock(hdev);
+}
+
int hci_get_conn_list(void __user *arg)
{
struct hci_conn_list_req req, *cl;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 18e3afc964d..372b0d3b75a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -176,7 +176,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG("%s %ld", hdev->name, opt);
/* Reset device */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
}
static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
@@ -202,16 +202,16 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
/* Reset */
if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL);
/* Read Local Supported Features */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL);
/* Read Local Version */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL);
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
#if 0
/* Host buffer size */
@@ -221,29 +221,35 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
cp.sco_mtu = HCI_MAX_SCO_SIZE;
cp.acl_max_pkt = cpu_to_le16(0xffff);
cp.sco_max_pkt = cpu_to_le16(0xffff);
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_HOST_BUFFER_SIZE, sizeof(cp), &cp);
}
#endif
/* Read BD Address */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL);
+
+ /* Read Class of Device */
+ hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL);
+
+ /* Read Local Name */
+ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL);
/* Read Voice Setting */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
+ hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL);
/* Optional initialization */
/* Clear Event Filters */
flt_type = HCI_FLT_CLEAR_ALL;
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &flt_type);
+ hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
/* Page timeout ~20 secs */
param = cpu_to_le16(0x8000);
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, &param);
+ hci_send_cmd(hdev, HCI_OP_WRITE_PG_TIMEOUT, 2, &param);
/* Connection accept timeout ~20 secs */
param = cpu_to_le16(0x7d00);
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_CA_TIMEOUT, 2, &param);
+ hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, &param);
}
static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
@@ -253,7 +259,7 @@ static void hci_scan_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG("%s %x", hdev->name, scan);
/* Inquiry and Page scans */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
+ hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
}
static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
@@ -263,7 +269,7 @@ static void hci_auth_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG("%s %x", hdev->name, auth);
/* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
+ hci_send_cmd(hdev, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
}
static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
@@ -273,7 +279,7 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
BT_DBG("%s %x", hdev->name, encrypt);
/* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
+ hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
}
/* Get HCI device by index.
@@ -384,7 +390,7 @@ static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
memcpy(&cp.lap, &ir->lap, 3);
cp.length = ir->length;
cp.num_rsp = ir->num_rsp;
- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
}
int hci_inquiry(void __user *arg)
@@ -1111,13 +1117,13 @@ static int hci_send_frame(struct sk_buff *skb)
}
/* Send HCI command */
-int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
+int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param)
{
int len = HCI_COMMAND_HDR_SIZE + plen;
struct hci_command_hdr *hdr;
struct sk_buff *skb;
- BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+ BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen);
skb = bt_skb_alloc(len, GFP_ATOMIC);
if (!skb) {
@@ -1126,7 +1132,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
}
hdr = (struct hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
- hdr->opcode = cpu_to_le16(hci_opcode_pack(ogf, ocf));
+ hdr->opcode = cpu_to_le16(opcode);
hdr->plen = plen;
if (plen)
@@ -1143,7 +1149,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *p
}
/* Get data from the previously sent command */
-void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode)
{
struct hci_command_hdr *hdr;
@@ -1152,10 +1158,10 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
hdr = (void *) hdev->sent_cmd->data;
- if (hdr->opcode != cpu_to_le16(hci_opcode_pack(ogf, ocf)))
+ if (hdr->opcode != cpu_to_le16(opcode))
return NULL;
- BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+ BT_DBG("%s opcode 0x%x", hdev->name, opcode);
return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
}
@@ -1355,6 +1361,26 @@ static inline void hci_sched_sco(struct hci_dev *hdev)
}
}
+static inline void hci_sched_esco(struct hci_dev *hdev)
+{
+ struct hci_conn *conn;
+ struct sk_buff *skb;
+ int quote;
+
+ BT_DBG("%s", hdev->name);
+
+ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, &quote))) {
+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
+ BT_DBG("skb %p len %d", skb, skb->len);
+ hci_send_frame(skb);
+
+ conn->sent++;
+ if (conn->sent == ~0)
+ conn->sent = 0;
+ }
+ }
+}
+
static void hci_tx_task(unsigned long arg)
{
struct hci_dev *hdev = (struct hci_dev *) arg;
@@ -1370,6 +1396,8 @@ static void hci_tx_task(unsigned long arg)
hci_sched_sco(hdev);
+ hci_sched_esco(hdev);
+
/* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4baea1e3865..46df2e403df 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -52,234 +52,273 @@
/* Handle HCI Event packets */
-/* Command Complete OGF LINK_CTL */
-static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
{
- __u8 status;
- struct hci_conn *pend;
+ __u8 status = *((__u8 *) skb->data);
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+ BT_DBG("%s status 0x%x", hdev->name, status);
- switch (ocf) {
- case OCF_INQUIRY_CANCEL:
- case OCF_EXIT_PERIODIC_INQ:
- status = *((__u8 *) skb->data);
+ if (status)
+ return;
- if (status) {
- BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
- } else {
- clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
- }
+ clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_dev_lock(hdev);
+ hci_req_complete(hdev, status);
- pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
- if (pend)
- hci_acl_connect(pend);
+ hci_conn_check_pending(hdev);
+}
- hci_dev_unlock(hdev);
+static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
- break;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- default:
- BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
- break;
+ if (status)
+ return;
+
+ clear_bit(HCI_INQUIRY, &hdev->flags);
+
+ hci_conn_check_pending(hdev);
+}
+
+static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
+static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_role_discovery *rp = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+ if (conn) {
+ if (rp->role)
+ conn->link_mode &= ~HCI_LM_MASTER;
+ else
+ conn->link_mode |= HCI_LM_MASTER;
}
+
+ hci_dev_unlock(hdev);
}
-/* Command Complete OGF LINK_POLICY */
-static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
{
+ struct hci_rp_write_link_policy *rp = (void *) skb->data;
struct hci_conn *conn;
- struct hci_rp_role_discovery *rd;
- struct hci_rp_write_link_policy *lp;
void *sent;
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- switch (ocf) {
- case OCF_ROLE_DISCOVERY:
- rd = (void *) skb->data;
+ if (rp->status)
+ return;
- if (rd->status)
- break;
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
+ if (!sent)
+ return;
- hci_dev_lock(hdev);
+ hci_dev_lock(hdev);
- conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
- if (conn) {
- if (rd->role)
- conn->link_mode &= ~HCI_LM_MASTER;
- else
- conn->link_mode |= HCI_LM_MASTER;
- }
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
+ if (conn) {
+ __le16 policy = get_unaligned((__le16 *) (sent + 2));
+ conn->link_policy = __le16_to_cpu(policy);
+ }
- hci_dev_unlock(hdev);
- break;
+ hci_dev_unlock(hdev);
+}
- case OCF_WRITE_LINK_POLICY:
- sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY);
- if (!sent)
- break;
+static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
- lp = (struct hci_rp_write_link_policy *) skb->data;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- if (lp->status)
- break;
+ hci_req_complete(hdev, status);
+}
- hci_dev_lock(hdev);
+static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ void *sent;
- conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle));
- if (conn) {
- __le16 policy = get_unaligned((__le16 *) (sent + 2));
- conn->link_policy = __le16_to_cpu(policy);
- }
+ BT_DBG("%s status 0x%x", hdev->name, status);
- hci_dev_unlock(hdev);
- break;
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
+ if (!sent)
+ return;
- default:
- BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
- hdev->name, ocf);
- break;
+ if (!status)
+ memcpy(hdev->dev_name, sent, 248);
+}
+
+static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_local_name *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ memcpy(hdev->dev_name, rp->name, 248);
+}
+
+static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ void *sent;
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
+ if (!sent)
+ return;
+
+ if (!status) {
+ __u8 param = *((__u8 *) sent);
+
+ if (param == AUTH_ENABLED)
+ set_bit(HCI_AUTH, &hdev->flags);
+ else
+ clear_bit(HCI_AUTH, &hdev->flags);
}
+
+ hci_req_complete(hdev, status);
}
-/* Command Complete OGF HOST_CTL */
-static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
{
- __u8 status, param;
- __u16 setting;
- struct hci_rp_read_voice_setting *vs;
+ __u8 status = *((__u8 *) skb->data);
void *sent;
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+ BT_DBG("%s status 0x%x", hdev->name, status);
- switch (ocf) {
- case OCF_RESET:
- status = *((__u8 *) skb->data);
- hci_req_complete(hdev, status);
- break;
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
+ if (!sent)
+ return;
- case OCF_SET_EVENT_FLT:
- status = *((__u8 *) skb->data);
- if (status) {
- BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
- } else {
- BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
- }
- break;
+ if (!status) {
+ __u8 param = *((__u8 *) sent);
- case OCF_WRITE_AUTH_ENABLE:
- sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
- if (!sent)
- break;
+ if (param)
+ set_bit(HCI_ENCRYPT, &hdev->flags);
+ else
+ clear_bit(HCI_ENCRYPT, &hdev->flags);
+ }
- status = *((__u8 *) skb->data);
- param = *((__u8 *) sent);
+ hci_req_complete(hdev, status);
+}
- if (!status) {
- if (param == AUTH_ENABLED)
- set_bit(HCI_AUTH, &hdev->flags);
- else
- clear_bit(HCI_AUTH, &hdev->flags);
- }
- hci_req_complete(hdev, status);
- break;
+static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ void *sent;
- case OCF_WRITE_ENCRYPT_MODE:
- sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
- if (!sent)
- break;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- status = *((__u8 *) skb->data);
- param = *((__u8 *) sent);
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
+ if (!sent)
+ return;
- if (!status) {
- if (param)
- set_bit(HCI_ENCRYPT, &hdev->flags);
- else
- clear_bit(HCI_ENCRYPT, &hdev->flags);
- }
- hci_req_complete(hdev, status);
- break;
+ if (!status) {
+ __u8 param = *((__u8 *) sent);
- case OCF_WRITE_CA_TIMEOUT:
- status = *((__u8 *) skb->data);
- if (status) {
- BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
- } else {
- BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
- }
- break;
+ clear_bit(HCI_PSCAN, &hdev->flags);
+ clear_bit(HCI_ISCAN, &hdev->flags);
- case OCF_WRITE_PG_TIMEOUT:
- status = *((__u8 *) skb->data);
- if (status) {
- BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
- } else {
- BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
- }
- break;
+ if (param & SCAN_INQUIRY)
+ set_bit(HCI_ISCAN, &hdev->flags);
- case OCF_WRITE_SCAN_ENABLE:
- sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
- if (!sent)
- break;
+ if (param & SCAN_PAGE)
+ set_bit(HCI_PSCAN, &hdev->flags);
+ }
- status = *((__u8 *) skb->data);
- param = *((__u8 *) sent);
+ hci_req_complete(hdev, status);
+}
- BT_DBG("param 0x%x", param);
+static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
- if (!status) {
- clear_bit(HCI_PSCAN, &hdev->flags);
- clear_bit(HCI_ISCAN, &hdev->flags);
- if (param & SCAN_INQUIRY)
- set_bit(HCI_ISCAN, &hdev->flags);
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- if (param & SCAN_PAGE)
- set_bit(HCI_PSCAN, &hdev->flags);
- }
- hci_req_complete(hdev, status);
- break;
+ if (rp->status)
+ return;
- case OCF_READ_VOICE_SETTING:
- vs = (struct hci_rp_read_voice_setting *) skb->data;
+ memcpy(hdev->dev_class, rp->dev_class, 3);
- if (vs->status) {
- BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vs->status);
- break;
- }
+ BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
+ hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
- setting = __le16_to_cpu(vs->voice_setting);
+static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ void *sent;
- if (hdev->voice_setting != setting ) {
- hdev->voice_setting = setting;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
+ if (!sent)
+ return;
- if (hdev->notify) {
- tasklet_disable(&hdev->tx_task);
- hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
- tasklet_enable(&hdev->tx_task);
- }
- }
- break;
+ if (!status)
+ memcpy(hdev->dev_class, sent, 3);
+}
- case OCF_WRITE_VOICE_SETTING:
- sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
- if (!sent)
- break;
+static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_voice_setting *rp = (void *) skb->data;
+ __u16 setting;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (rp->status)
+ return;
+
+ setting = __le16_to_cpu(rp->voice_setting);
+
+ if (hdev->voice_setting == setting )
+ return;
+
+ hdev->voice_setting = setting;
- status = *((__u8 *) skb->data);
- setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
+ BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
- if (!status && hdev->voice_setting != setting) {
+ if (hdev->notify) {
+ tasklet_disable(&hdev->tx_task);
+ hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
+ tasklet_enable(&hdev->tx_task);
+ }
+}
+
+static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ __u8 status = *((__u8 *) skb->data);
+ void *sent;
+
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
+ if (!sent)
+ return;
+
+ if (!status) {
+ __u16 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
+
+ if (hdev->voice_setting != setting) {
hdev->voice_setting = setting;
- BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
+ BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
if (hdev->notify) {
tasklet_disable(&hdev->tx_task);
@@ -287,143 +326,153 @@ static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb
tasklet_enable(&hdev->tx_task);
}
}
- hci_req_complete(hdev, status);
- break;
-
- case OCF_HOST_BUFFER_SIZE:
- status = *((__u8 *) skb->data);
- if (status) {
- BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
- hci_req_complete(hdev, status);
- }
- break;
-
- default:
- BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
- break;
}
}
-/* Command Complete OGF INFO_PARAM */
-static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
+static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_rp_read_loc_version *lv;
- struct hci_rp_read_local_features *lf;
- struct hci_rp_read_buffer_size *bs;
- struct hci_rp_read_bd_addr *ba;
+ __u8 status = *((__u8 *) skb->data);
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+ BT_DBG("%s status 0x%x", hdev->name, status);
- switch (ocf) {
- case OCF_READ_LOCAL_VERSION:
- lv = (struct hci_rp_read_loc_version *) skb->data;
+ hci_req_complete(hdev, status);
+}
- if (lv->status) {
- BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
- break;
- }
+static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_local_version *rp = (void *) skb->data;
- hdev->hci_ver = lv->hci_ver;
- hdev->hci_rev = btohs(lv->hci_rev);
- hdev->manufacturer = btohs(lv->manufacturer);
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
- hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
+ if (rp->status)
+ return;
- break;
+ hdev->hci_ver = rp->hci_ver;
+ hdev->hci_rev = btohs(rp->hci_rev);
+ hdev->manufacturer = btohs(rp->manufacturer);
- case OCF_READ_LOCAL_FEATURES:
- lf = (struct hci_rp_read_local_features *) skb->data;
+ BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
+ hdev->manufacturer,
+ hdev->hci_ver, hdev->hci_rev);
+}
- if (lf->status) {
- BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
- break;
- }
+static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_local_commands *rp = (void *) skb->data;
- memcpy(hdev->features, lf->features, sizeof(hdev->features));
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- /* Adjust default settings according to features
- * supported by device. */
- if (hdev->features[0] & LMP_3SLOT)
- hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+ if (rp->status)
+ return;
- if (hdev->features[0] & LMP_5SLOT)
- hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+ memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
+}
- if (hdev->features[1] & LMP_HV2) {
- hdev->pkt_type |= (HCI_HV2);
- hdev->esco_type |= (ESCO_HV2);
- }
+static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_local_features *rp = (void *) skb->data;
- if (hdev->features[1] & LMP_HV3) {
- hdev->pkt_type |= (HCI_HV3);
- hdev->esco_type |= (ESCO_HV3);
- }
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- if (hdev->features[3] & LMP_ESCO)
- hdev->esco_type |= (ESCO_EV3);
+ if (rp->status)
+ return;
- if (hdev->features[4] & LMP_EV4)
- hdev->esco_type |= (ESCO_EV4);
+ memcpy(hdev->features, rp->features, 8);
- if (hdev->features[4] & LMP_EV5)
- hdev->esco_type |= (ESCO_EV5);
+ /* Adjust default settings according to features
+ * supported by device. */
- BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
- lf->features[0], lf->features[1], lf->features[2]);
+ if (hdev->features[0] & LMP_3SLOT)
+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
- break;
+ if (hdev->features[0] & LMP_5SLOT)
+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
- case OCF_READ_BUFFER_SIZE:
- bs = (struct hci_rp_read_buffer_size *) skb->data;
+ if (hdev->features[1] & LMP_HV2) {
+ hdev->pkt_type |= (HCI_HV2);
+ hdev->esco_type |= (ESCO_HV2);
+ }
- if (bs->status) {
- BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
- hci_req_complete(hdev, bs->status);
- break;
- }
+ if (hdev->features[1] & LMP_HV3) {
+ hdev->pkt_type |= (HCI_HV3);
+ hdev->esco_type |= (ESCO_HV3);
+ }
- hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
- hdev->sco_mtu = bs->sco_mtu;
- hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
- hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
+ if (hdev->features[3] & LMP_ESCO)
+ hdev->esco_type |= (ESCO_EV3);
- if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
- hdev->sco_mtu = 64;
- hdev->sco_pkts = 8;
- }
+ if (hdev->features[4] & LMP_EV4)
+ hdev->esco_type |= (ESCO_EV4);
- hdev->acl_cnt = hdev->acl_pkts;
- hdev->sco_cnt = hdev->sco_pkts;
+ if (hdev->features[4] & LMP_EV5)
+ hdev->esco_type |= (ESCO_EV5);
- BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
- break;
+ BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
+ hdev->features[0], hdev->features[1],
+ hdev->features[2], hdev->features[3],
+ hdev->features[4], hdev->features[5],
+ hdev->features[6], hdev->features[7]);
+}
- case OCF_READ_BD_ADDR:
- ba = (struct hci_rp_read_bd_addr *) skb->data;
+static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_buffer_size *rp = (void *) skb->data;
- if (!ba->status) {
- bacpy(&hdev->bdaddr, &ba->bdaddr);
- } else {
- BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
- }
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
- hci_req_complete(hdev, ba->status);
- break;
+ if (rp->status)
+ return;
- default:
- BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
- break;
+ hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
+ hdev->sco_mtu = rp->sco_mtu;
+ hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
+ hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
+
+ if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
+ hdev->sco_mtu = 64;
+ hdev->sco_pkts = 8;
}
+
+ hdev->acl_cnt = hdev->acl_pkts;
+ hdev->sco_cnt = hdev->sco_pkts;
+
+ BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
+ hdev->acl_mtu, hdev->acl_pkts,
+ hdev->sco_mtu, hdev->sco_pkts);
+}
+
+static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_rp_read_bd_addr *rp = (void *) skb->data;
+
+ BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+ if (!rp->status)
+ bacpy(&hdev->bdaddr, &rp->bdaddr);
+
+ hci_req_complete(hdev, rp->status);
+}
+
+static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
+{
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ if (status) {
+ hci_req_complete(hdev, status);
+
+ hci_conn_check_pending(hdev);
+ } else
+ set_bit(HCI_INQUIRY, &hdev->flags);
}
-/* Command Status OGF LINK_CTL */
static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
{
+ struct hci_cp_create_conn *cp;
struct hci_conn *conn;
- struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
+ BT_DBG("%s status 0x%x", hdev->name, status);
+
+ cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
if (!cp)
return;
@@ -431,8 +480,7 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
- BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
- status, batostr(&cp->bdaddr), conn);
+ BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
if (status) {
if (conn && conn->state == BT_CONNECT) {
@@ -457,234 +505,138 @@ static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
hci_dev_unlock(hdev);
}
-static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
{
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
+ struct hci_cp_add_sco *cp;
+ struct hci_conn *acl, *sco;
+ __u16 handle;
- switch (ocf) {
- case OCF_CREATE_CONN:
- hci_cs_create_conn(hdev, status);
- break;
-
- case OCF_ADD_SCO:
- if (status) {
- struct hci_conn *acl, *sco;
- struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
- __u16 handle;
-
- if (!cp)
- break;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- handle = __le16_to_cpu(cp->handle);
-
- BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+ if (!status)
+ return;
- hci_dev_lock(hdev);
+ cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
+ if (!cp)
+ return;
- acl = hci_conn_hash_lookup_handle(hdev, handle);
- if (acl && (sco = acl->link)) {
- sco->state = BT_CLOSED;
+ handle = __le16_to_cpu(cp->handle);
- hci_proto_connect_cfm(sco, status);
- hci_conn_del(sco);
- }
+ BT_DBG("%s handle %d", hdev->name, handle);
- hci_dev_unlock(hdev);
- }
- break;
+ hci_dev_lock(hdev);
- case OCF_INQUIRY:
- if (status) {
- BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
- hci_req_complete(hdev, status);
- } else {
- set_bit(HCI_INQUIRY, &hdev->flags);
- }
- break;
+ acl = hci_conn_hash_lookup_handle(hdev, handle);
+ if (acl && (sco = acl->link)) {
+ sco->state = BT_CLOSED;
- default:
- BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
- hdev->name, ocf, status);
- break;
+ hci_proto_connect_cfm(sco, status);
+ hci_conn_del(sco);
}
+
+ hci_dev_unlock(hdev);
}
-/* Command Status OGF LINK_POLICY */
-static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
{
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
- switch (ocf) {
- case OCF_SNIFF_MODE:
- if (status) {
- struct hci_conn *conn;
- struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
+ BT_DBG("%s status 0x%x", hdev->name, status);
+}
- if (!cp)
- break;
+static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
+{
+ struct hci_cp_setup_sync_conn *cp;
+ struct hci_conn *acl, *sco;
+ __u16 handle;
- hci_dev_lock(hdev);
+ BT_DBG("%s status 0x%x", hdev->name, status);
- conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
- if (conn) {
- clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
- }
-
- hci_dev_unlock(hdev);
- }
- break;
+ if (!status)
+ return;
- case OCF_EXIT_SNIFF_MODE:
- if (status) {
- struct hci_conn *conn;
- struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
+ cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
+ if (!cp)
+ return;
- if (!cp)
- break;
+ handle = __le16_to_cpu(cp->handle);
- hci_dev_lock(hdev);
+ BT_DBG("%s handle %d", hdev->name, handle);
- conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
- if (conn) {
- clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
- }
+ hci_dev_lock(hdev);
- hci_dev_unlock(hdev);
- }
- break;
+ acl = hci_conn_hash_lookup_handle(hdev, handle);
+ if (acl && (sco = acl->link)) {
+ sco->state = BT_CLOSED;
- default:
- BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
- break;
+ hci_proto_connect_cfm(sco, status);
+ hci_conn_del(sco);
}
-}
-/* Command Status OGF HOST_CTL */
-static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-{
- BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-
- switch (ocf) {
- default:
- BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
- break;
- }
+ hci_dev_unlock(hdev);
}
-/* Command Status OGF INFO_PARAM */
-static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
+static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
{
- BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-
- switch (ocf) {
- default:
- BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
- break;
- }
-}
+ struct hci_cp_sniff_mode *cp;
+ struct hci_conn *conn;
-/* Inquiry Complete */
-static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
- __u8 status = *((__u8 *) skb->data);
- struct hci_conn *pend;
+ BT_DBG("%s status 0x%x", hdev->name, status);
- BT_DBG("%s status %d", hdev->name, status);
+ if (!status)
+ return;
- clear_bit(HCI_INQUIRY, &hdev->flags);
- hci_req_complete(hdev, status);
+ cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
+ if (!cp)
+ return;
hci_dev_lock(hdev);
- pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
- if (pend)
- hci_acl_connect(pend);
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+ if (conn)
+ clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
hci_dev_unlock(hdev);
}
-/* Inquiry Result */
-static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
{
- struct inquiry_data data;
- struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
- int num_rsp = *((__u8 *) skb->data);
+ struct hci_cp_exit_sniff_mode *cp;
+ struct hci_conn *conn;
- BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+ BT_DBG("%s status 0x%x", hdev->name, status);
- if (!num_rsp)
+ if (!status)
+ return;
+
+ cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
+ if (!cp)
return;
hci_dev_lock(hdev);
- for (; num_rsp; num_rsp--) {
- bacpy(&data.bdaddr, &info->bdaddr);
- data.pscan_rep_mode = info->pscan_rep_mode;
- data.pscan_period_mode = info->pscan_period_mode;
- data.pscan_mode = info->pscan_mode;
- memcpy(data.dev_class, info->dev_class, 3);
- data.clock_offset = info->clock_offset;
- data.rssi = 0x00;
- info++;
- hci_inquiry_cache_update(hdev, &data);
- }
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
+ if (conn)
+ clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
hci_dev_unlock(hdev);
}
-/* Inquiry Result With RSSI */
-static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct inquiry_data data;
- int num_rsp = *((__u8 *) skb->data);
-
- BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-
- if (!num_rsp)
- return;
-
- hci_dev_lock(hdev);
+ __u8 status = *((__u8 *) skb->data);
- if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
- struct inquiry_info_with_rssi_and_pscan_mode *info =
- (struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
+ BT_DBG("%s status %d", hdev->name, status);
- for (; num_rsp; num_rsp--) {
- bacpy(&data.bdaddr, &info->bdaddr);
- data.pscan_rep_mode = info->pscan_rep_mode;
- data.pscan_period_mode = info->pscan_period_mode;
- data.pscan_mode = info->pscan_mode;
- memcpy(data.dev_class, info->dev_class, 3);
- data.clock_offset = info->clock_offset;
- data.rssi = info->rssi;
- info++;
- hci_inquiry_cache_update(hdev, &data);
- }
- } else {
- struct inquiry_info_with_rssi *info =
- (struct inquiry_info_with_rssi *) (skb->data + 1);
+ clear_bit(HCI_INQUIRY, &hdev->flags);
- for (; num_rsp; num_rsp--) {
- bacpy(&data.bdaddr, &info->bdaddr);
- data.pscan_rep_mode = info->pscan_rep_mode;
- data.pscan_period_mode = info->pscan_period_mode;
- data.pscan_mode = 0x00;
- memcpy(data.dev_class, info->dev_class, 3);
- data.clock_offset = info->clock_offset;
- data.rssi = info->rssi;
- info++;
- hci_inquiry_cache_update(hdev, &data);
- }
- }
+ hci_req_complete(hdev, status);
- hci_dev_unlock(hdev);
+ hci_conn_check_pending(hdev);
}
-/* Extended Inquiry Result */
-static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct inquiry_data data;
- struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
+ struct inquiry_info *info = (void *) (skb->data + 1);
int num_rsp = *((__u8 *) skb->data);
BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
@@ -696,12 +648,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
for (; num_rsp; num_rsp--) {
bacpy(&data.bdaddr, &info->bdaddr);
- data.pscan_rep_mode = info->pscan_rep_mode;
- data.pscan_period_mode = info->pscan_period_mode;
- data.pscan_mode = 0x00;
+ data.pscan_rep_mode = info->pscan_rep_mode;
+ data.pscan_period_mode = info->pscan_period_mode;
+ data.pscan_mode = info->pscan_mode;
memcpy(data.dev_class, info->dev_class, 3);
- data.clock_offset = info->clock_offset;
- data.rssi = info->rssi;
+ data.clock_offset = info->clock_offset;
+ data.rssi = 0x00;
info++;
hci_inquiry_cache_update(hdev, &data);
}
@@ -709,70 +661,18 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct
hci_dev_unlock(hdev);
}
-/* Connect Request */
-static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
- int mask = hdev->link_mode;
-
- BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
- batostr(&ev->bdaddr), ev->link_type);
-
- mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
-
- if (mask & HCI_LM_ACCEPT) {
- /* Connection accepted */
- struct hci_conn *conn;
- struct hci_cp_accept_conn_req cp;
-
- hci_dev_lock(hdev);
- conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
- if (!conn) {
- if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
- BT_ERR("No memmory for new connection");
- hci_dev_unlock(hdev);
- return;
- }
- }
- memcpy(conn->dev_class, ev->dev_class, 3);
- conn->state = BT_CONNECT;
- hci_dev_unlock(hdev);
-
- bacpy(&cp.bdaddr, &ev->bdaddr);
-
- if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
- cp.role = 0x00; /* Become master */
- else
- cp.role = 0x01; /* Remain slave */
-
- hci_send_cmd(hdev, OGF_LINK_CTL,
- OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
- } else {
- /* Connection rejected */
- struct hci_cp_reject_conn_req cp;
-
- bacpy(&cp.bdaddr, &ev->bdaddr);
- cp.reason = 0x0f;
- hci_send_cmd(hdev, OGF_LINK_CTL,
- OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
- }
-}
-
-/* Connect Complete */
static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
- struct hci_conn *conn, *pend;
+ struct hci_ev_conn_complete *ev = (void *) skb->data;
+ struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
- if (!conn) {
- hci_dev_unlock(hdev);
- return;
- }
+ if (!conn)
+ goto unlock;
if (!ev->status) {
conn->handle = __le16_to_cpu(ev->handle);
@@ -788,8 +688,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn->type == ACL_LINK) {
struct hci_cp_read_remote_features cp;
cp.handle = ev->handle;
- hci_send_cmd(hdev, OGF_LINK_CTL,
- OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);
}
/* Set link policy */
@@ -797,8 +696,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
struct hci_cp_write_link_policy cp;
cp.handle = ev->handle;
cp.policy = cpu_to_le16(hdev->link_policy);
- hci_send_cmd(hdev, OGF_LINK_POLICY,
- OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp);
}
/* Set packet type for incoming connection */
@@ -809,8 +707,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
- hci_send_cmd(hdev, OGF_LINK_CTL,
- OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
+ hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
} else {
/* Update disconnect timer */
hci_conn_hold(conn);
@@ -822,9 +719,12 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link;
if (sco) {
- if (!ev->status)
- hci_add_sco(sco, conn->handle);
- else {
+ if (!ev->status) {
+ if (lmp_esco_capable(hdev))
+ hci_setup_sync(sco, conn->handle);
+ else
+ hci_add_sco(sco, conn->handle);
+ } else {
hci_proto_connect_cfm(sco, ev->status);
hci_conn_del(sco);
}
@@ -835,136 +735,104 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (ev->status)
hci_conn_del(conn);
- pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
- if (pend)
- hci_acl_connect(pend);
-
+unlock:
hci_dev_unlock(hdev);
-}
-
-/* Disconnect Complete */
-static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
- struct hci_conn *conn;
-
- BT_DBG("%s status %d", hdev->name, ev->status);
-
- if (ev->status)
- return;
- hci_dev_lock(hdev);
-
- conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn) {
- conn->state = BT_CLOSED;
- hci_proto_disconn_ind(conn, ev->reason);
- hci_conn_del(conn);
- }
-
- hci_dev_unlock(hdev);
+ hci_conn_check_pending(hdev);
}
-/* Number of completed packets */
-static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
- __le16 *ptr;
- int i;
-
- skb_pull(skb, sizeof(*ev));
-
- BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
+ struct hci_ev_conn_request *ev = (void *) skb->data;
+ int mask = hdev->link_mode;
- if (skb->len < ev->num_hndl * 4) {
- BT_DBG("%s bad parameters", hdev->name);
- return;
- }
+ BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
+ batostr(&ev->bdaddr), ev->link_type);
- tasklet_disable(&hdev->tx_task);
+ mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
- for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
+ if (mask & HCI_LM_ACCEPT) {
+ /* Connection accepted */
struct hci_conn *conn;
- __u16 handle, count;
-
- handle = __le16_to_cpu(get_unaligned(ptr++));
- count = __le16_to_cpu(get_unaligned(ptr++));
- conn = hci_conn_hash_lookup_handle(hdev, handle);
- if (conn) {
- conn->sent -= count;
+ hci_dev_lock(hdev);
- if (conn->type == ACL_LINK) {
- if ((hdev->acl_cnt += count) > hdev->acl_pkts)
- hdev->acl_cnt = hdev->acl_pkts;
- } else {
- if ((hdev->sco_cnt += count) > hdev->sco_pkts)
- hdev->sco_cnt = hdev->sco_pkts;
+ conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+ if (!conn) {
+ if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
+ BT_ERR("No memmory for new connection");
+ hci_dev_unlock(hdev);
+ return;
}
}
- }
- hci_sched_tx(hdev);
- tasklet_enable(&hdev->tx_task);
-}
+ memcpy(conn->dev_class, ev->dev_class, 3);
+ conn->state = BT_CONNECT;
-/* Role Change */
-static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-{
- struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
- struct hci_conn *conn;
+ hci_dev_unlock(hdev);
- BT_DBG("%s status %d", hdev->name, ev->status);
+ if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
+ struct hci_cp_accept_conn_req cp;
- hci_dev_lock(hdev);
+ bacpy(&cp.bdaddr, &ev->bdaddr);
- conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
- if (conn) {
- if (!ev->status) {
- if (ev->role)
- conn->link_mode &= ~HCI_LM_MASTER;
+ if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+ cp.role = 0x00; /* Become master */
else
- conn->link_mode |= HCI_LM_MASTER;
- }
+ cp.role = 0x01; /* Remain slave */
- clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+ hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
+ sizeof(cp), &cp);
+ } else {
+ struct hci_cp_accept_sync_conn_req cp;
- hci_role_switch_cfm(conn, ev->status, ev->role);
- }
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ cp.pkt_type = cpu_to_le16(hdev->esco_type);
- hci_dev_unlock(hdev);
+ cp.tx_bandwidth = cpu_to_le32(0x00001f40);
+ cp.rx_bandwidth = cpu_to_le32(0x00001f40);
+ cp.max_latency = cpu_to_le16(0xffff);
+ cp.content_format = cpu_to_le16(hdev->voice_setting);
+ cp.retrans_effort = 0xff;
+
+ hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
+ sizeof(cp), &cp);
+ }
+ } else {
+ /* Connection rejected */
+ struct hci_cp_reject_conn_req cp;
+
+ bacpy(&cp.bdaddr, &ev->bdaddr);
+ cp.reason = 0x0f;
+ hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
+ }
}
-/* Mode Change */
-static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
+ struct hci_ev_disconn_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
+ if (ev->status)
+ return;
+
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
if (conn) {
- conn->mode = ev->mode;
- conn->interval = __le16_to_cpu(ev->interval);
-
- if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
- if (conn->mode == HCI_CM_ACTIVE)
- conn->power_save = 1;
- else
- conn->power_save = 0;
- }
+ conn->state = BT_CLOSED;
+ hci_proto_disconn_ind(conn, ev->reason);
+ hci_conn_del(conn);
}
hci_dev_unlock(hdev);
}
-/* Authentication Complete */
static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
+ struct hci_ev_auth_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -985,8 +853,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 1;
- hci_send_cmd(conn->hdev, OGF_LINK_CTL,
- OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
+ hci_send_cmd(conn->hdev,
+ HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
} else {
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
hci_encrypt_cfm(conn, ev->status, 0x00);
@@ -997,10 +865,16 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
hci_dev_unlock(hdev);
}
-/* Encryption Change */
+static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+
+ hci_conn_check_pending(hdev);
+}
+
static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
+ struct hci_ev_encrypt_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1024,10 +898,9 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_unlock(hdev);
}
-/* Change Connection Link Key Complete */
-static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
+ struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1047,25 +920,263 @@ static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, s
hci_dev_unlock(hdev);
}
-/* Pin Code Request*/
-static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
+ struct hci_ev_remote_features *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ if (ev->status)
+ return;
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
+ if (conn)
+ memcpy(conn->features, ev->features, 8);
+
+ hci_dev_unlock(hdev);
}
-/* Link Key Request */
-static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
+ BT_DBG("%s", hdev->name);
}
-/* Link Key Notification */
-static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
+ BT_DBG("%s", hdev->name);
}
-/* Remote Features */
-static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
+ struct hci_ev_cmd_complete *ev = (void *) skb->data;
+ __u16 opcode;
+
+ skb_pull(skb, sizeof(*ev));
+
+ opcode = __le16_to_cpu(ev->opcode);
+
+ switch (opcode) {
+ case HCI_OP_INQUIRY_CANCEL:
+ hci_cc_inquiry_cancel(hdev, skb);
+ break;
+
+ case HCI_OP_EXIT_PERIODIC_INQ:
+ hci_cc_exit_periodic_inq(hdev, skb);
+ break;
+
+ case HCI_OP_REMOTE_NAME_REQ_CANCEL:
+ hci_cc_remote_name_req_cancel(hdev, skb);
+ break;
+
+ case HCI_OP_ROLE_DISCOVERY:
+ hci_cc_role_discovery(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_LINK_POLICY:
+ hci_cc_write_link_policy(hdev, skb);
+ break;
+
+ case HCI_OP_RESET:
+ hci_cc_reset(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_LOCAL_NAME:
+ hci_cc_write_local_name(hdev, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_NAME:
+ hci_cc_read_local_name(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_AUTH_ENABLE:
+ hci_cc_write_auth_enable(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_ENCRYPT_MODE:
+ hci_cc_write_encrypt_mode(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_SCAN_ENABLE:
+ hci_cc_write_scan_enable(hdev, skb);
+ break;
+
+ case HCI_OP_READ_CLASS_OF_DEV:
+ hci_cc_read_class_of_dev(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_CLASS_OF_DEV:
+ hci_cc_write_class_of_dev(hdev, skb);
+ break;
+
+ case HCI_OP_READ_VOICE_SETTING:
+ hci_cc_read_voice_setting(hdev, skb);
+ break;
+
+ case HCI_OP_WRITE_VOICE_SETTING:
+ hci_cc_write_voice_setting(hdev, skb);
+ break;
+
+ case HCI_OP_HOST_BUFFER_SIZE:
+ hci_cc_host_buffer_size(hdev, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_VERSION:
+ hci_cc_read_local_version(hdev, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_COMMANDS:
+ hci_cc_read_local_commands(hdev, skb);
+ break;
+
+ case HCI_OP_READ_LOCAL_FEATURES:
+ hci_cc_read_local_features(hdev, skb);
+ break;
+
+ case HCI_OP_READ_BUFFER_SIZE:
+ hci_cc_read_buffer_size(hdev, skb);
+ break;
+
+ case HCI_OP_READ_BD_ADDR:
+ hci_cc_read_bd_addr(hdev, skb);
+ break;
+
+ default:
+ BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+ break;
+ }
+
+ if (ev->ncmd) {
+ atomic_set(&hdev->cmd_cnt, 1);
+ if (!skb_queue_empty(&hdev->cmd_q))
+ hci_sched_cmd(hdev);
+ }
+}
+
+static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_cmd_status *ev = (void *) skb->data;
+ __u16 opcode;
+
+ skb_pull(skb, sizeof(*ev));
+
+ opcode = __le16_to_cpu(ev->opcode);
+
+ switch (opcode) {
+ case HCI_OP_INQUIRY:
+ hci_cs_inquiry(hdev, ev->status);
+ break;
+
+ case HCI_OP_CREATE_CONN:
+ hci_cs_create_conn(hdev, ev->status);
+ break;
+
+ case HCI_OP_ADD_SCO:
+ hci_cs_add_sco(hdev, ev->status);
+ break;
+
+ case HCI_OP_REMOTE_NAME_REQ:
+ hci_cs_remote_name_req(hdev, ev->status);
+ break;
+
+ case HCI_OP_SETUP_SYNC_CONN:
+ hci_cs_setup_sync_conn(hdev, ev->status);
+ break;
+
+ case HCI_OP_SNIFF_MODE:
+ hci_cs_sniff_mode(hdev, ev->status);
+ break;
+
+ case HCI_OP_EXIT_SNIFF_MODE:
+ hci_cs_exit_sniff_mode(hdev, ev->status);
+ break;
+
+ default:
+ BT_DBG("%s opcode 0x%x", hdev->name, opcode);
+ break;
+ }
+
+ if (ev->ncmd) {
+ atomic_set(&hdev->cmd_cnt, 1);
+ if (!skb_queue_empty(&hdev->cmd_q))
+ hci_sched_cmd(hdev);
+ }
+}
+
+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_role_change *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (conn) {
+ if (!ev->status) {
+ if (ev->role)
+ conn->link_mode &= ~HCI_LM_MASTER;
+ else
+ conn->link_mode |= HCI_LM_MASTER;
+ }
+
+ clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
+
+ hci_role_switch_cfm(conn, ev->status, ev->role);
+ }
+
+ hci_dev_unlock(hdev);
+}
+
+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
+ __le16 *ptr;
+ int i;
+
+ skb_pull(skb, sizeof(*ev));
+
+ BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
+
+ if (skb->len < ev->num_hndl * 4) {
+ BT_DBG("%s bad parameters", hdev->name);
+ return;
+ }
+
+ tasklet_disable(&hdev->tx_task);
+
+ for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
+ struct hci_conn *conn;
+ __u16 handle, count;
+
+ handle = __le16_to_cpu(get_unaligned(ptr++));
+ count = __le16_to_cpu(get_unaligned(ptr++));
+
+ conn = hci_conn_hash_lookup_handle(hdev, handle);
+ if (conn) {
+ conn->sent -= count;
+
+ if (conn->type == ACL_LINK) {
+ if ((hdev->acl_cnt += count) > hdev->acl_pkts)
+ hdev->acl_cnt = hdev->acl_pkts;
+ } else {
+ if ((hdev->sco_cnt += count) > hdev->sco_pkts)
+ hdev->sco_cnt = hdev->sco_pkts;
+ }
+ }
+ }
+
+ hci_sched_tx(hdev);
+
+ tasklet_enable(&hdev->tx_task);
+}
+
+static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_mode_change *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1073,17 +1184,39 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
- if (conn && !ev->status) {
- memcpy(conn->features, ev->features, sizeof(conn->features));
+ if (conn) {
+ conn->mode = ev->mode;
+ conn->interval = __le16_to_cpu(ev->interval);
+
+ if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
+ if (conn->mode == HCI_CM_ACTIVE)
+ conn->power_save = 1;
+ else
+ conn->power_save = 0;
+ }
}
hci_dev_unlock(hdev);
}
-/* Clock Offset */
+static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
+ struct hci_ev_clock_offset *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1103,10 +1236,9 @@ static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_unlock(hdev);
}
-/* Page Scan Repetition Mode */
static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
+ struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
struct inquiry_entry *ie;
BT_DBG("%s", hdev->name);
@@ -1121,10 +1253,91 @@ static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *
hci_dev_unlock(hdev);
}
-/* Sniff Subrate */
+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct inquiry_data data;
+ int num_rsp = *((__u8 *) skb->data);
+
+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
+
+ if (!num_rsp)
+ return;
+
+ hci_dev_lock(hdev);
+
+ if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
+ struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
+
+ for (; num_rsp; num_rsp--) {
+ bacpy(&data.bdaddr, &info->bdaddr);
+ data.pscan_rep_mode = info->pscan_rep_mode;
+ data.pscan_period_mode = info->pscan_period_mode;
+ data.pscan_mode = info->pscan_mode;
+ memcpy(data.dev_class, info->dev_class, 3);
+ data.clock_offset = info->clock_offset;
+ data.rssi = info->rssi;
+ info++;
+ hci_inquiry_cache_update(hdev, &data);
+ }
+ } else {
+ struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
+
+ for (; num_rsp; num_rsp--) {
+ bacpy(&data.bdaddr, &info->bdaddr);
+ data.pscan_rep_mode = info->pscan_rep_mode;
+ data.pscan_period_mode = info->pscan_period_mode;
+ data.pscan_mode = 0x00;
+ memcpy(data.dev_class, info->dev_class, 3);
+ data.clock_offset = info->clock_offset;
+ data.rssi = info->rssi;
+ info++;
+ hci_inquiry_cache_update(hdev, &data);
+ }
+ }
+
+ hci_dev_unlock(hdev);
+}
+
+static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
+static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
+ struct hci_conn *conn;
+
+ BT_DBG("%s status %d", hdev->name, ev->status);
+
+ hci_dev_lock(hdev);
+
+ conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ if (!ev->status) {
+ conn->handle = __le16_to_cpu(ev->handle);
+ conn->state = BT_CONNECTED;
+ } else
+ conn->state = BT_CLOSED;
+
+ hci_proto_connect_cfm(conn, ev->status);
+ if (ev->status)
+ hci_conn_del(conn);
+
+unlock:
+ hci_dev_unlock(hdev);
+}
+
+static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ BT_DBG("%s", hdev->name);
+}
+
static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
+ struct hci_ev_sniff_subrate *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s status %d", hdev->name, ev->status);
@@ -1138,22 +1351,42 @@ static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *s
hci_dev_unlock(hdev);
}
-void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
- struct hci_ev_cmd_complete *ec;
- struct hci_ev_cmd_status *cs;
- u16 opcode, ocf, ogf;
+ struct inquiry_data data;
+ struct extended_inquiry_info *info = (void *) (skb->data + 1);
+ int num_rsp = *((__u8 *) skb->data);
- skb_pull(skb, HCI_EVENT_HDR_SIZE);
+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
- BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);
+ if (!num_rsp)
+ return;
- switch (hdr->evt) {
- case HCI_EV_NUM_COMP_PKTS:
- hci_num_comp_pkts_evt(hdev, skb);
- break;
+ hci_dev_lock(hdev);
+
+ for (; num_rsp; num_rsp--) {
+ bacpy(&data.bdaddr, &info->bdaddr);
+ data.pscan_rep_mode = info->pscan_rep_mode;
+ data.pscan_period_mode = info->pscan_period_mode;
+ data.pscan_mode = 0x00;
+ memcpy(data.dev_class, info->dev_class, 3);
+ data.clock_offset = info->clock_offset;
+ data.rssi = info->rssi;
+ info++;
+ hci_inquiry_cache_update(hdev, &data);
+ }
+ hci_dev_unlock(hdev);
+}
+
+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+{
+ struct hci_event_hdr *hdr = (void *) skb->data;
+ __u8 event = hdr->evt;
+
+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
+
+ switch (event) {
case HCI_EV_INQUIRY_COMPLETE:
hci_inquiry_complete_evt(hdev, skb);
break;
@@ -1162,44 +1395,64 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_inquiry_result_evt(hdev, skb);
break;
- case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
- hci_inquiry_result_with_rssi_evt(hdev, skb);
- break;
-
- case HCI_EV_EXTENDED_INQUIRY_RESULT:
- hci_extended_inquiry_result_evt(hdev, skb);
+ case HCI_EV_CONN_COMPLETE:
+ hci_conn_complete_evt(hdev, skb);
break;
case HCI_EV_CONN_REQUEST:
hci_conn_request_evt(hdev, skb);
break;
- case HCI_EV_CONN_COMPLETE:
- hci_conn_complete_evt(hdev, skb);
- break;
-
case HCI_EV_DISCONN_COMPLETE:
hci_disconn_complete_evt(hdev, skb);
break;
- case HCI_EV_ROLE_CHANGE:
- hci_role_change_evt(hdev, skb);
- break;
-
- case HCI_EV_MODE_CHANGE:
- hci_mode_change_evt(hdev, skb);
- break;
-
case HCI_EV_AUTH_COMPLETE:
hci_auth_complete_evt(hdev, skb);
break;
+ case HCI_EV_REMOTE_NAME:
+ hci_remote_name_evt(hdev, skb);
+ break;
+
case HCI_EV_ENCRYPT_CHANGE:
hci_encrypt_change_evt(hdev, skb);
break;
- case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
- hci_change_conn_link_key_complete_evt(hdev, skb);
+ case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
+ hci_change_link_key_complete_evt(hdev, skb);
+ break;
+
+ case HCI_EV_REMOTE_FEATURES:
+ hci_remote_features_evt(hdev, skb);
+ break;
+
+ case HCI_EV_REMOTE_VERSION:
+ hci_remote_version_evt(hdev, skb);
+ break;
+
+ case HCI_EV_QOS_SETUP_COMPLETE:
+ hci_qos_setup_complete_evt(hdev, skb);
+ break;
+
+ case HCI_EV_CMD_COMPLETE:
+ hci_cmd_complete_evt(hdev, skb);
+ break;
+
+ case HCI_EV_CMD_STATUS:
+ hci_cmd_status_evt(hdev, skb);
+ break;
+
+ case HCI_EV_ROLE_CHANGE:
+ hci_role_change_evt(hdev, skb);
+ break;
+
+ case HCI_EV_NUM_COMP_PKTS:
+ hci_num_comp_pkts_evt(hdev, skb);
+ break;
+
+ case HCI_EV_MODE_CHANGE:
+ hci_mode_change_evt(hdev, skb);
break;
case HCI_EV_PIN_CODE_REQ:
@@ -1214,10 +1467,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_link_key_notify_evt(hdev, skb);
break;
- case HCI_EV_REMOTE_FEATURES:
- hci_remote_features_evt(hdev, skb);
- break;
-
case HCI_EV_CLOCK_OFFSET:
hci_clock_offset_evt(hdev, skb);
break;
@@ -1226,82 +1475,32 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_pscan_rep_mode_evt(hdev, skb);
break;
- case HCI_EV_SNIFF_SUBRATE:
- hci_sniff_subrate_evt(hdev, skb);
+ case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
+ hci_inquiry_result_with_rssi_evt(hdev, skb);
break;
- case HCI_EV_CMD_STATUS:
- cs = (struct hci_ev_cmd_status *) skb->data;
- skb_pull(skb, sizeof(cs));
-
- opcode = __le16_to_cpu(cs->opcode);
- ogf = hci_opcode_ogf(opcode);
- ocf = hci_opcode_ocf(opcode);
-
- switch (ogf) {
- case OGF_INFO_PARAM:
- hci_cs_info_param(hdev, ocf, cs->status);
- break;
-
- case OGF_HOST_CTL:
- hci_cs_host_ctl(hdev, ocf, cs->status);
- break;
-
- case OGF_LINK_CTL:
- hci_cs_link_ctl(hdev, ocf, cs->status);
- break;
-
- case OGF_LINK_POLICY:
- hci_cs_link_policy(hdev, ocf, cs->status);
- break;
-
- default:
- BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
- break;
- }
-
- if (cs->ncmd) {
- atomic_set(&hdev->cmd_cnt, 1);
- if (!skb_queue_empty(&hdev->cmd_q))
- hci_sched_cmd(hdev);
- }
+ case HCI_EV_REMOTE_EXT_FEATURES:
+ hci_remote_ext_features_evt(hdev, skb);
break;
- case HCI_EV_CMD_COMPLETE:
- ec = (struct hci_ev_cmd_complete *) skb->data;
- skb_pull(skb, sizeof(*ec));
-
- opcode = __le16_to_cpu(ec->opcode);
- ogf = hci_opcode_ogf(opcode);
- ocf = hci_opcode_ocf(opcode);
-
- switch (ogf) {
- case OGF_INFO_PARAM:
- hci_cc_info_param(hdev, ocf, skb);
- break;
-
- case OGF_HOST_CTL:
- hci_cc_host_ctl(hdev, ocf, skb);
- break;
+ case HCI_EV_SYNC_CONN_COMPLETE:
+ hci_sync_conn_complete_evt(hdev, skb);
+ break;
- case OGF_LINK_CTL:
- hci_cc_link_ctl(hdev, ocf, skb);
- break;
+ case HCI_EV_SYNC_CONN_CHANGED:
+ hci_sync_conn_changed_evt(hdev, skb);
+ break;
- case OGF_LINK_POLICY:
- hci_cc_link_policy(hdev, ocf, skb);
- break;
+ case HCI_EV_SNIFF_SUBRATE:
+ hci_sniff_subrate_evt(hdev, skb);
+ break;
- default:
- BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
- break;
- }
+ case HCI_EV_EXTENDED_INQUIRY_RESULT:
+ hci_extended_inquiry_result_evt(hdev, skb);
+ break;
- if (ec->ncmd) {
- atomic_set(&hdev->cmd_cnt, 1);
- if (!skb_queue_empty(&hdev->cmd_q))
- hci_sched_cmd(hdev);
- }
+ default:
+ BT_DBG("%s event 0x%x", hdev->name, event);
break;
}
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 43dd6373bff..8825102c517 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -451,7 +451,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto drop;
}
- if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
+ if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
skb_queue_tail(&hdev->raw_q, skb);
hci_sched_tx(hdev);
} else {
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 25835403d65..cef1e3e1881 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -41,6 +41,26 @@ static ssize_t show_type(struct device *dev, struct device_attribute *attr, char
return sprintf(buf, "%s\n", typetostr(hdev->type));
}
+static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ char name[249];
+ int i;
+
+ for (i = 0; i < 248; i++)
+ name[i] = hdev->dev_name[i];
+
+ name[248] = '\0';
+ return sprintf(buf, "%s\n", name);
+}
+
+static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+ return sprintf(buf, "0x%.2x%.2x%.2x\n",
+ hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
+}
+
static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -49,6 +69,17 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, c
return sprintf(buf, "%s\n", batostr(&bdaddr));
}
+static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct hci_dev *hdev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ hdev->features[0], hdev->features[1],
+ hdev->features[2], hdev->features[3],
+ hdev->features[4], hdev->features[5],
+ hdev->features[6], hdev->features[7]);
+}
+
static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct hci_dev *hdev = dev_get_drvdata(dev);
@@ -170,7 +201,10 @@ static ssize_t store_sniff_min_interval(struct device *dev, struct device_attrib
}
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static DEVICE_ATTR(class, S_IRUGO, show_class, NULL);
static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(features, S_IRUGO, show_features, NULL);
static DEVICE_ATTR(manufacturer, S_IRUGO, show_manufacturer, NULL);
static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL);
static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL);
@@ -185,7 +219,10 @@ static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR,
static struct device_attribute *bt_attrs[] = {
&dev_attr_type,
+ &dev_attr_name,
+ &dev_attr_class,
&dev_attr_address,
+ &dev_attr_features,
&dev_attr_manufacturer,
&dev_attr_hci_version,
&dev_attr_hci_revision,
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index ff5784b440d..4bbacddeb49 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -247,7 +247,7 @@ static inline int hidp_queue_report(struct hidp_session *session, unsigned char
{
struct sk_buff *skb;
- BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
+ BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size);
if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) {
BT_ERR("Can't allocate memory for new frame");
@@ -656,11 +656,13 @@ static inline int hidp_setup_input(struct hidp_session *session, struct hidp_con
}
if (req->subclass & 0x80) {
- input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
- input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
- input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
- input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
- input->relbit[0] |= BIT(REL_WHEEL);
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
+ input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) |
+ BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
+ input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
+ input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) |
+ BIT_MASK(BTN_EXTRA);
+ input->relbit[0] |= BIT_MASK(REL_WHEEL);
}
input->dev.parent = hidp_get_device(session);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 36ef27b625d..6fbbae78b30 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -55,7 +55,9 @@
#define BT_DBG(D...)
#endif
-#define VERSION "2.8"
+#define VERSION "2.9"
+
+static u32 l2cap_feat_mask = 0x0000;
static const struct proto_ops l2cap_sock_ops;
@@ -258,7 +260,119 @@ static void l2cap_chan_del(struct sock *sk, int err)
sk->sk_state_change(sk);
}
+static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
+{
+ u8 id;
+
+ /* Get next available identificator.
+ * 1 - 128 are used by kernel.
+ * 129 - 199 are reserved.
+ * 200 - 254 are used by utilities like l2ping, etc.
+ */
+
+ spin_lock_bh(&conn->lock);
+
+ if (++conn->tx_ident > 128)
+ conn->tx_ident = 1;
+
+ id = conn->tx_ident;
+
+ spin_unlock_bh(&conn->lock);
+
+ return id;
+}
+
+static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
+{
+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
+
+ BT_DBG("code 0x%2.2x", code);
+
+ if (!skb)
+ return -ENOMEM;
+
+ return hci_send_acl(conn->hcon, skb, 0);
+}
+
/* ---- L2CAP connections ---- */
+static void l2cap_conn_start(struct l2cap_conn *conn)
+{
+ struct l2cap_chan_list *l = &conn->chan_list;
+ struct sock *sk;
+
+ BT_DBG("conn %p", conn);
+
+ read_lock(&l->lock);
+
+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ bh_lock_sock(sk);
+
+ if (sk->sk_type != SOCK_SEQPACKET) {
+ l2cap_sock_clear_timer(sk);
+ sk->sk_state = BT_CONNECTED;
+ sk->sk_state_change(sk);
+ } else if (sk->sk_state == BT_CONNECT) {
+ struct l2cap_conn_req req;
+ l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
+ req.psm = l2cap_pi(sk)->psm;
+ l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
+ L2CAP_CONN_REQ, sizeof(req), &req);
+ }
+
+ bh_unlock_sock(sk);
+ }
+
+ read_unlock(&l->lock);
+}
+
+static void l2cap_conn_ready(struct l2cap_conn *conn)
+{
+ BT_DBG("conn %p", conn);
+
+ if (conn->chan_list.head || !hlist_empty(&l2cap_sk_list.head)) {
+ struct l2cap_info_req req;
+
+ req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+
+ conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT;
+ conn->info_ident = l2cap_get_ident(conn);
+
+ mod_timer(&conn->info_timer,
+ jiffies + msecs_to_jiffies(L2CAP_INFO_TIMEOUT));
+
+ l2cap_send_cmd(conn, conn->info_ident,
+ L2CAP_INFO_REQ, sizeof(req), &req);
+ }
+}
+
+/* Notify sockets that we cannot guaranty reliability anymore */
+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
+{
+ struct l2cap_chan_list *l = &conn->chan_list;
+ struct sock *sk;
+
+ BT_DBG("conn %p", conn);
+
+ read_lock(&l->lock);
+
+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
+ sk->sk_err = err;
+ }
+
+ read_unlock(&l->lock);
+}
+
+static void l2cap_info_timeout(unsigned long arg)
+{
+ struct l2cap_conn *conn = (void *) arg;
+
+ conn->info_ident = 0;
+
+ l2cap_conn_start(conn);
+}
+
static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
{
struct l2cap_conn *conn = hcon->l2cap_data;
@@ -279,6 +393,12 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status)
conn->src = &hcon->hdev->bdaddr;
conn->dst = &hcon->dst;
+ conn->feat_mask = 0;
+
+ init_timer(&conn->info_timer);
+ conn->info_timer.function = l2cap_info_timeout;
+ conn->info_timer.data = (unsigned long) conn;
+
spin_lock_init(&conn->lock);
rwlock_init(&conn->chan_list.lock);
@@ -318,40 +438,6 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru
write_unlock_bh(&l->lock);
}
-static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
-{
- u8 id;
-
- /* Get next available identificator.
- * 1 - 128 are used by kernel.
- * 129 - 199 are reserved.
- * 200 - 254 are used by utilities like l2ping, etc.
- */
-
- spin_lock_bh(&conn->lock);
-
- if (++conn->tx_ident > 128)
- conn->tx_ident = 1;
-
- id = conn->tx_ident;
-
- spin_unlock_bh(&conn->lock);
-
- return id;
-}
-
-static inline int l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data)
-{
- struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-
- BT_DBG("code 0x%2.2x", code);
-
- if (!skb)
- return -ENOMEM;
-
- return hci_send_acl(conn->hcon, skb, 0);
-}
-
/* ---- Socket interface ---- */
static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
{
@@ -508,7 +594,6 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
/* Default config options */
pi->conf_len = 0;
- pi->conf_mtu = L2CAP_DEFAULT_MTU;
pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
}
@@ -530,7 +615,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
- sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+ sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sock_reset_flag(sk, SOCK_ZAPPED);
@@ -650,6 +735,11 @@ static int l2cap_do_connect(struct sock *sk)
l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
if (hcon->state == BT_CONNECTED) {
+ if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) {
+ l2cap_conn_ready(conn);
+ goto done;
+ }
+
if (sk->sk_type == SOCK_SEQPACKET) {
struct l2cap_conn_req req;
l2cap_pi(sk)->ident = l2cap_get_ident(conn);
@@ -958,7 +1048,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
opts.imtu = l2cap_pi(sk)->imtu;
opts.omtu = l2cap_pi(sk)->omtu;
opts.flush_to = l2cap_pi(sk)->flush_to;
- opts.mode = 0x00;
+ opts.mode = L2CAP_MODE_BASIC;
len = min_t(unsigned int, sizeof(opts), optlen);
if (copy_from_user((char *) &opts, optval, len)) {
@@ -1007,7 +1097,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch
opts.imtu = l2cap_pi(sk)->imtu;
opts.omtu = l2cap_pi(sk)->omtu;
opts.flush_to = l2cap_pi(sk)->flush_to;
- opts.mode = 0x00;
+ opts.mode = L2CAP_MODE_BASIC;
len = min_t(unsigned int, len, sizeof(opts));
if (copy_to_user(optval, (char *) &opts, len))
@@ -1084,52 +1174,6 @@ static int l2cap_sock_release(struct socket *sock)
return err;
}
-static void l2cap_conn_ready(struct l2cap_conn *conn)
-{
- struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
-
- BT_DBG("conn %p", conn);
-
- read_lock(&l->lock);
-
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
- bh_lock_sock(sk);
-
- if (sk->sk_type != SOCK_SEQPACKET) {
- l2cap_sock_clear_timer(sk);
- sk->sk_state = BT_CONNECTED;
- sk->sk_state_change(sk);
- } else if (sk->sk_state == BT_CONNECT) {
- struct l2cap_conn_req req;
- l2cap_pi(sk)->ident = l2cap_get_ident(conn);
- req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
- req.psm = l2cap_pi(sk)->psm;
- l2cap_send_cmd(conn, l2cap_pi(sk)->ident, L2CAP_CONN_REQ, sizeof(req), &req);
- }
-
- bh_unlock_sock(sk);
- }
-
- read_unlock(&l->lock);
-}
-
-/* Notify sockets that we cannot guaranty reliability anymore */
-static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-{
- struct l2cap_chan_list *l = &conn->chan_list;
- struct sock *sk;
-
- BT_DBG("conn %p", conn);
-
- read_lock(&l->lock);
- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
- if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
- sk->sk_err = err;
- }
- read_unlock(&l->lock);
-}
-
static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
@@ -1256,11 +1300,11 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned
break;
case 2:
- *val = __le16_to_cpu(*((__le16 *)opt->val));
+ *val = __le16_to_cpu(*((__le16 *) opt->val));
break;
case 4:
- *val = __le32_to_cpu(*((__le32 *)opt->val));
+ *val = __le32_to_cpu(*((__le32 *) opt->val));
break;
default:
@@ -1332,6 +1376,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
int len = pi->conf_len;
int type, hint, olen;
unsigned long val;
+ struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
+ u16 mtu = L2CAP_DEFAULT_MTU;
u16 result = L2CAP_CONF_SUCCESS;
BT_DBG("sk %p", sk);
@@ -1344,7 +1390,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
switch (type) {
case L2CAP_CONF_MTU:
- pi->conf_mtu = val;
+ mtu = val;
break;
case L2CAP_CONF_FLUSH_TO:
@@ -1354,6 +1400,11 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
case L2CAP_CONF_QOS:
break;
+ case L2CAP_CONF_RFC:
+ if (olen == sizeof(rfc))
+ memcpy(&rfc, (void *) val, olen);
+ break;
+
default:
if (hint)
break;
@@ -1368,12 +1419,24 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
/* Configure output options and let the other side know
* which ones we don't like. */
- if (pi->conf_mtu < pi->omtu)
+ if (rfc.mode == L2CAP_MODE_BASIC) {
+ if (mtu < pi->omtu)
+ result = L2CAP_CONF_UNACCEPT;
+ else {
+ pi->omtu = mtu;
+ pi->conf_state |= L2CAP_CONF_OUTPUT_DONE;
+ }
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ } else {
result = L2CAP_CONF_UNACCEPT;
- else
- pi->omtu = pi->conf_mtu;
- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->omtu);
+ memset(&rfc, 0, sizeof(rfc));
+ rfc.mode = L2CAP_MODE_BASIC;
+
+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+ sizeof(rfc), (unsigned long) &rfc);
+ }
}
rsp->scid = cpu_to_le16(pi->dcid);
@@ -1397,6 +1460,23 @@ static int l2cap_build_conf_rsp(struct sock *sk, void *data, u16 result, u16 fla
return ptr - data;
}
+static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
+{
+ struct l2cap_cmd_rej *rej = (struct l2cap_cmd_rej *) data;
+
+ if (rej->reason != 0x0000)
+ return 0;
+
+ if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
+ cmd->ident == conn->info_ident) {
+ conn->info_ident = 0;
+ del_timer(&conn->info_timer);
+ l2cap_conn_start(conn);
+ }
+
+ return 0;
+}
+
static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
struct l2cap_chan_list *list = &conn->chan_list;
@@ -1577,16 +1657,19 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
- /* Output config done. */
- l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-
/* Reset config buffer. */
l2cap_pi(sk)->conf_len = 0;
+ if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE))
+ goto unlock;
+
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
sk->sk_state = BT_CONNECTED;
l2cap_chan_ready(sk);
- } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
+ goto unlock;
+ }
+
+ if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
u8 req[64];
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(sk, req), req);
@@ -1646,7 +1729,6 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
if (flags & 0x01)
goto done;
- /* Input config done */
l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
@@ -1711,16 +1793,27 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data)
{
struct l2cap_info_req *req = (struct l2cap_info_req *) data;
- struct l2cap_info_rsp rsp;
u16 type;
type = __le16_to_cpu(req->type);
BT_DBG("type 0x%4.4x", type);
- rsp.type = cpu_to_le16(type);
- rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
- l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+ if (type == L2CAP_IT_FEAT_MASK) {
+ u8 buf[8];
+ struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf;
+ rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK);
+ rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS);
+ put_unaligned(cpu_to_le32(l2cap_feat_mask), (__le32 *) rsp->data);
+ l2cap_send_cmd(conn, cmd->ident,
+ L2CAP_INFO_RSP, sizeof(buf), buf);
+ } else {
+ struct l2cap_info_rsp rsp;
+ rsp.type = cpu_to_le16(type);
+ rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP);
+ l2cap_send_cmd(conn, cmd->ident,
+ L2CAP_INFO_RSP, sizeof(rsp), &rsp);
+ }
return 0;
}
@@ -1735,6 +1828,15 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
+ conn->info_ident = 0;
+
+ del_timer(&conn->info_timer);
+
+ if (type == L2CAP_IT_FEAT_MASK)
+ conn->feat_mask = __le32_to_cpu(get_unaligned((__le32 *) rsp->data));
+
+ l2cap_conn_start(conn);
+
return 0;
}
@@ -1764,7 +1866,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk
switch (cmd.code) {
case L2CAP_COMMAND_REJ:
- /* FIXME: We should process this */
+ l2cap_command_rej(conn, &cmd, data);
break;
case L2CAP_CONN_REQ:
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index bb7220770f2..e7ac6ba7eca 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -33,11 +33,11 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/init.h>
-#include <linux/freezer.h>
#include <linux/wait.h>
#include <linux/device.h>
#include <linux/net.h>
#include <linux/mutex.h>
+#include <linux/kthread.h>
#include <net/sock.h>
#include <asm/uaccess.h>
@@ -68,7 +68,6 @@ static DEFINE_MUTEX(rfcomm_mutex);
static unsigned long rfcomm_event;
static LIST_HEAD(session_list);
-static atomic_t terminate, running;
static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
@@ -1850,26 +1849,6 @@ static inline void rfcomm_process_sessions(void)
rfcomm_unlock();
}
-static void rfcomm_worker(void)
-{
- BT_DBG("");
-
- while (!atomic_read(&terminate)) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
- /* No pending events. Let's sleep.
- * Incoming connections and data will wake us up. */
- schedule();
- }
- set_current_state(TASK_RUNNING);
-
- /* Process stuff */
- clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
- rfcomm_process_sessions();
- }
- return;
-}
-
static int rfcomm_add_listener(bdaddr_t *ba)
{
struct sockaddr_l2 addr;
@@ -1935,22 +1914,28 @@ static void rfcomm_kill_listener(void)
static int rfcomm_run(void *unused)
{
- rfcomm_thread = current;
-
- atomic_inc(&running);
+ BT_DBG("");
- daemonize("krfcommd");
set_user_nice(current, -10);
- BT_DBG("");
-
rfcomm_add_listener(BDADDR_ANY);
- rfcomm_worker();
+ while (!kthread_should_stop()) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
+ /* No pending events. Let's sleep.
+ * Incoming connections and data will wake us up. */
+ schedule();
+ }
+ set_current_state(TASK_RUNNING);
+
+ /* Process stuff */
+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
+ rfcomm_process_sessions();
+ }
rfcomm_kill_listener();
- atomic_dec(&running);
return 0;
}
@@ -2059,7 +2044,11 @@ static int __init rfcomm_init(void)
hci_register_cb(&rfcomm_cb);
- kernel_thread(rfcomm_run, NULL, CLONE_KERNEL);
+ rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd");
+ if (IS_ERR(rfcomm_thread)) {
+ hci_unregister_cb(&rfcomm_cb);
+ return PTR_ERR(rfcomm_thread);
+ }
if (class_create_file(bt_class, &class_attr_rfcomm_dlc) < 0)
BT_ERR("Failed to create RFCOMM info file");
@@ -2081,14 +2070,7 @@ static void __exit rfcomm_exit(void)
hci_unregister_cb(&rfcomm_cb);
- /* Terminate working thread.
- * ie. Set terminate flag and wake it up */
- atomic_inc(&terminate);
- rfcomm_schedule(RFCOMM_SCHED_STATE);
-
- /* Wait until thread is running */
- while (atomic_read(&running))
- schedule();
+ kthread_stop(rfcomm_thread);
#ifdef CONFIG_BT_RFCOMM_TTY
rfcomm_cleanup_ttys();
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 22a832098d4..e447651a2db 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -189,6 +189,23 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
return conn ? &conn->dev : NULL;
}
+static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+ bdaddr_t bdaddr;
+ baswap(&bdaddr, &dev->dst);
+ return sprintf(buf, "%s\n", batostr(&bdaddr));
+}
+
+static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
+{
+ struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
+ return sprintf(buf, "%d\n", dev->channel);
+}
+
+static DEVICE_ATTR(address, S_IRUGO, show_address, NULL);
+static DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
+
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev;
@@ -281,6 +298,14 @@ out:
return err;
}
+ dev_set_drvdata(dev->tty_dev, dev);
+
+ if (device_create_file(dev->tty_dev, &dev_attr_address) < 0)
+ BT_ERR("Failed to create address attribute");
+
+ if (device_create_file(dev->tty_dev, &dev_attr_channel) < 0)
+ BT_ERR("Failed to create channel attribute");
+
return dev->id;
}
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 65b6fb1c415..82d0dfdfa7e 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -189,7 +189,7 @@ static int sco_connect(struct sock *sk)
struct sco_conn *conn;
struct hci_conn *hcon;
struct hci_dev *hdev;
- int err = 0;
+ int err, type;
BT_DBG("%s -> %s", batostr(src), batostr(dst));
@@ -200,7 +200,9 @@ static int sco_connect(struct sock *sk)
err = -ENOMEM;
- hcon = hci_connect(hdev, SCO_LINK, dst);
+ type = lmp_esco_capable(hdev) ? ESCO_LINK : SCO_LINK;
+
+ hcon = hci_connect(hdev, type, dst);
if (!hcon)
goto done;
@@ -224,6 +226,7 @@ static int sco_connect(struct sock *sk)
sk->sk_state = BT_CONNECT;
sco_sock_set_timer(sk, sk->sk_sndtimeo);
}
+
done:
hci_dev_unlock_bh(hdev);
hci_dev_put(hdev);
@@ -846,7 +849,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
{
BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
- if (hcon->type != SCO_LINK)
+ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
return 0;
if (!status) {
@@ -865,10 +868,11 @@ static int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
{
BT_DBG("hcon %p reason %d", hcon, reason);
- if (hcon->type != SCO_LINK)
+ if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK)
return 0;
sco_conn_del(hcon, bt_err(reason));
+
return 0;
}
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index d5a09eaef91..817169e718c 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -871,7 +871,7 @@ static int translate_table(char *name, struct ebt_table_info *newinfo)
return -EINVAL;
}
- /* we now know the following (along with E=mc):
+ /* we now know the following (along with E=mc²):
- the nr of entries in each chain is right
- the size of the allocated space is right
- all valid hooks have a corresponding chain
diff --git a/net/core/dev.c b/net/core/dev.c
index 38b03da5c1c..872658927e4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1553,7 +1553,7 @@ gso:
return rc;
}
if (unlikely((netif_queue_stopped(dev) ||
- netif_subqueue_stopped(dev, skb->queue_mapping)) &&
+ netif_subqueue_stopped(dev, skb)) &&
skb->next))
return NETDEV_TX_BUSY;
} while (skb->next);
@@ -1661,7 +1661,7 @@ gso:
q = dev->qdisc;
if (q->enqueue) {
/* reset queue_mapping to zero */
- skb->queue_mapping = 0;
+ skb_set_queue_mapping(skb, 0);
rc = q->enqueue(skb, q);
qdisc_run(dev);
spin_unlock(&dev->queue_lock);
@@ -1692,7 +1692,7 @@ gso:
HARD_TX_LOCK(dev, cpu);
if (!netif_queue_stopped(dev) &&
- !netif_subqueue_stopped(dev, skb->queue_mapping)) {
+ !netif_subqueue_stopped(dev, skb)) {
rc = 0;
if (!dev_hard_start_xmit(skb, dev)) {
HARD_TX_UNLOCK(dev);
diff --git a/net/core/filter.c b/net/core/filter.c
index 1f0068eae50..e0a06942c02 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -447,7 +447,8 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk)
rcu_assign_pointer(sk->sk_filter, fp);
rcu_read_unlock_bh();
- sk_filter_delayed_uncharge(sk, old_fp);
+ if (old_fp)
+ sk_filter_delayed_uncharge(sk, old_fp);
return 0;
}
diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 590a767b029..daadbcc4e8d 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -15,7 +15,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 67ba9914e52..05979e35696 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1438,6 +1438,9 @@ int neigh_table_clear(struct neigh_table *tbl)
free_percpu(tbl->stats);
tbl->stats = NULL;
+ kmem_cache_destroy(tbl->kmem_cachep);
+ tbl->kmem_cachep = NULL;
+
return 0;
}
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 95daba62496..bf8d18f1b01 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -67,7 +67,7 @@ static void queue_process(struct work_struct *work)
local_irq_save(flags);
netif_tx_lock(dev);
if ((netif_queue_stopped(dev) ||
- netif_subqueue_stopped(dev, skb->queue_mapping)) ||
+ netif_subqueue_stopped(dev, skb)) ||
dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb);
netif_tx_unlock(dev);
@@ -269,7 +269,7 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
tries > 0; --tries) {
if (netif_tx_trylock(dev)) {
if (!netif_queue_stopped(dev) &&
- !netif_subqueue_stopped(dev, skb->queue_mapping))
+ !netif_subqueue_stopped(dev, skb))
status = dev->hard_start_xmit(skb, dev);
netif_tx_unlock(dev);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8cae60c5338..de33f36947e 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -6,7 +6,7 @@
*
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
* Ben Greear <greearb@candelatech.com>
- * Jens Ls <jens.laas@data.slu.se>
+ * Jens Låås <jens.laas@data.slu.se>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -161,7 +161,7 @@
#endif
#include <asm/byteorder.h>
#include <linux/rcupdate.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
@@ -2603,8 +2603,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
skb->network_header = skb->tail;
skb->transport_header = skb->network_header + sizeof(struct iphdr);
skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
- skb->queue_mapping = pkt_dev->cur_queue_map;
-
+ skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
iph = ip_hdr(skb);
udph = udp_hdr(skb);
@@ -2941,8 +2940,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
skb->network_header = skb->tail;
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
- skb->queue_mapping = pkt_dev->cur_queue_map;
-
+ skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
iph = ipv6_hdr(skb);
udph = udp_hdr(skb);
@@ -3385,7 +3383,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
if ((netif_queue_stopped(odev) ||
(pkt_dev->skb &&
- netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping))) ||
+ netif_subqueue_stopped(odev, pkt_dev->skb))) ||
need_resched()) {
idle_start = getCurUs();
@@ -3402,7 +3400,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
pkt_dev->idle_acc += getCurUs() - idle_start;
if (netif_queue_stopped(odev) ||
- netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+ netif_subqueue_stopped(odev, pkt_dev->skb)) {
pkt_dev->next_tx_us = getCurUs(); /* TODO */
pkt_dev->next_tx_ns = 0;
goto out; /* Try the next interface */
@@ -3431,7 +3429,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
netif_tx_lock_bh(odev);
if (!netif_queue_stopped(odev) &&
- !netif_subqueue_stopped(odev, pkt_dev->skb->queue_mapping)) {
+ !netif_subqueue_stopped(odev, pkt_dev->skb)) {
atomic_inc(&(pkt_dev->skb->users));
retry_now:
@@ -3514,7 +3512,7 @@ static int pktgen_thread_worker(void *arg)
init_waitqueue_head(&t->queue);
- pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid);
+ pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current));
set_current_state(TASK_INTERRUPTIBLE);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 1072d16696c..4a2640d3826 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -744,10 +744,10 @@ static struct net *get_net_ns_by_pid(pid_t pid)
rcu_read_lock();
tsk = find_task_by_pid(pid);
if (tsk) {
- task_lock(tsk);
- if (tsk->nsproxy)
- net = get_net(tsk->nsproxy->net_ns);
- task_unlock(tsk);
+ struct nsproxy *nsproxy;
+ nsproxy = task_nsproxy(tsk);
+ if (nsproxy)
+ net = get_net(nsproxy->net_ns);
}
rcu_read_unlock();
return net;
diff --git a/net/core/scm.c b/net/core/scm.c
index 530bee8d9ed..100ba6d9d47 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -24,6 +24,8 @@
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/security.h>
+#include <linux/pid.h>
+#include <linux/nsproxy.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -42,7 +44,7 @@
static __inline__ int scm_check_creds(struct ucred *creds)
{
- if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) &&
+ if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
((creds->uid == current->uid || creds->uid == current->euid ||
creds->uid == current->suid) || capable(CAP_SETUID)) &&
((creds->gid == current->gid || creds->gid == current->egid ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 70d9b5da96a..4e2c84fcf27 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2045,7 +2045,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
if (copy > 0) {
if (copy > len)
copy = len;
- sg[elt].page = virt_to_page(skb->data + offset);
+ sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
sg[elt].length = copy;
elt++;
@@ -2065,7 +2065,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
if (copy > len)
copy = len;
- sg[elt].page = frag->page;
+ sg_set_page(&sg[elt], frag->page);
sg[elt].offset = frag->page_offset+offset-start;
sg[elt].length = copy;
elt++;
diff --git a/net/core/sock.c b/net/core/sock.c
index d292b4113d6..febbcbcf802 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -232,7 +232,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
warned++;
printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) "
"tries to set negative timeout\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
return 0;
}
*timeo_p = MAX_SCHEDULE_TIMEOUT;
diff --git a/net/dccp/diag.c b/net/dccp/diag.c
index 0f3745585a9..d8a3509b26f 100644
--- a/net/dccp/diag.c
+++ b/net/dccp/diag.c
@@ -68,3 +68,4 @@ module_exit(dccp_diag_fini);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
MODULE_DESCRIPTION("DCCP inet_diag handler");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, DCCPDIAG_GETSOCK);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 44f6e17e105..222549ab274 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -1037,8 +1037,8 @@ module_exit(dccp_v4_exit);
* values directly, Also cover the case where the protocol is not specified,
* i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
*/
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index cac53548c2d..bbadd6681b8 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -1219,8 +1219,8 @@ module_exit(dccp_v6_exit);
* values directly, Also cover the case where the protocol is not specified,
* i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
*/
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-33-type-6");
-MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-0-type-6");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 72e6ab66834..c796661a021 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -390,9 +390,7 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[3] = crc >> 24;
crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- sg.page = virt_to_page(pos);
- sg.offset = offset_in_page(pos);
- sg.length = len + 4;
+ sg_init_one(&sg, pos, len + 4);
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
}
@@ -485,9 +483,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
plen = skb->len - hdr_len - 12;
crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- sg.page = virt_to_page(pos);
- sg.offset = offset_in_page(pos);
- sg.length = plen + 4;
+ sg_init_one(&sg, pos, plen + 4);
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
if (net_ratelimit()) {
printk(KERN_DEBUG ": TKIP: failed to decrypt "
@@ -539,11 +535,12 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
return -1;
}
- sg[0].page = virt_to_page(hdr);
+ sg_init_table(sg, 2);
+ sg_set_page(&sg[0], virt_to_page(hdr));
sg[0].offset = offset_in_page(hdr);
sg[0].length = 16;
- sg[1].page = virt_to_page(data);
+ sg_set_page(&sg[1], virt_to_page(data));
sg[1].offset = offset_in_page(data);
sg[1].length = data_len;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 8d182459344..0af6103d715 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -170,9 +170,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
icv[3] = crc >> 24;
crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- sg.page = virt_to_page(pos);
- sg.offset = offset_in_page(pos);
- sg.length = len + 4;
+ sg_init_one(&sg, pos, len + 4);
return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
}
@@ -212,9 +210,7 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
plen = skb->len - hdr_len - 8;
crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- sg.page = virt_to_page(pos);
- sg.offset = offset_in_page(pos);
- sg.length = plen + 4;
+ sg_init_one(&sg, pos, plen + 4);
if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
return -7;
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 9b58dd67acb..d309e8f1999 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -409,7 +409,7 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
(*crypt)->priv);
sec.flags |= (1 << key);
/* This ensures a key will be activated if no key is
- * explicitely set */
+ * explicitly set */
if (key == sec.active_key)
sec.flags |= SEC_ACTIVE_KEY;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index d894f616c3d..9f9fd2c6f6e 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -560,7 +560,7 @@ config TCP_CONG_ILLINOIS
depends on EXPERIMENTAL
default n
---help---
- TCP-Illinois is a sender-side modificatio of TCP Reno for
+ TCP-Illinois is a sender-side modification of TCP Reno for
high speed long delay links. It uses round-trip-time to
adjust the alpha and beta parameters to achieve a higher average
throughput and maintain fairness.
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 81a8285d6d6..8d8c2915e06 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -54,7 +54,7 @@
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 3cef12835c4..8fb6ca23700 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -93,7 +93,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo,
int remaining, rover, low, high;
inet_get_local_port_range(&low, &high);
- remaining = high - low;
+ remaining = (high - low) + 1;
rover = net_random() % remaining + low;
do {
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 7eb83ebed2e..dc429b6b0ba 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -815,6 +815,12 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
nlmsg_len(nlh) < hdrlen)
return -EINVAL;
+#ifdef CONFIG_KMOD
+ if (inet_diag_table[nlh->nlmsg_type] == NULL)
+ request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
+ NETLINK_INET_DIAG, nlh->nlmsg_type);
+#endif
+
if (inet_diag_table[nlh->nlmsg_type] == NULL)
return -ENOENT;
@@ -914,3 +920,4 @@ static void __exit inet_diag_exit(void)
module_init(inet_diag_init);
module_exit(inet_diag_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_INET_DIAG);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index fac6398e436..16eecc7046a 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -286,7 +286,7 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row,
struct inet_timewait_sock *tw = NULL;
inet_get_local_port_range(&low, &high);
- remaining = high - low;
+ remaining = (high - low) + 1;
local_bh_disable();
for (i = 1; i <= remaining; i++) {
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 1960747f354..c99f2a33fb9 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -794,7 +794,7 @@ static int sync_thread(void *startup)
add_wait_queue(&sync_wait, &wait);
- set_sync_pid(state, current->pid);
+ set_sync_pid(state, task_pid_nr(current));
complete(tinfo->startup);
/*
@@ -877,7 +877,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
if (!tinfo)
return -ENOMEM;
- IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+ IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n",
sizeof(struct ip_vs_sync_conn));
@@ -917,7 +917,7 @@ int stop_sync_thread(int state)
(state == IP_VS_STATE_BACKUP && !sync_backup_pid))
return -ESRCH;
- IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
+ IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current));
IP_VS_INFO("stopping sync thread %d ...\n",
(state == IP_VS_STATE_MASTER) ?
sync_master_pid : sync_backup_pid);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c78acc1a7f1..ffddd2b4535 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -122,7 +122,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
if (write && ret == 0) {
- if (range[1] <= range[0])
+ if (range[1] < range[0])
ret = -EINVAL;
else
set_local_port_range(range);
@@ -150,7 +150,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
if (ret == 0 && newval && newlen) {
- if (range[1] <= range[0])
+ if (range[1] < range[0])
ret = -EINVAL;
else
set_local_port_range(range);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4f322003835..2e6ad6dbba6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1334,7 +1334,7 @@ do_prequeue:
if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) {
if (net_ratelimit())
printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
peek_seq = tp->copied_seq;
}
continue;
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 3904d2158a9..2fbcc7d1b1a 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -56,3 +56,4 @@ static void __exit tcp_diag_exit(void)
module_init(tcp_diag_init);
module_exit(tcp_diag_exit);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_INET_DIAG, TCPDIAG_GETSOCK);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index cb9fc58efb2..35d2b0e9e10 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -147,13 +147,14 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum,
write_lock_bh(&udp_hash_lock);
if (!snum) {
- int i, low, high;
+ int i, low, high, remaining;
unsigned rover, best, best_size_so_far;
inet_get_local_port_range(&low, &high);
+ remaining = (high - low) + 1;
best_size_so_far = UINT_MAX;
- best = rover = net_random() % (high - low) + low;
+ best = rover = net_random() % remaining + low;
/* 1st pass: look for empty (or shortest) hash chain */
for (i = 0; i < UDP_HTABLE_SIZE; i++) {
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 67cd06613a2..66a9139d46e 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -483,6 +483,7 @@ static int ah6_init_state(struct xfrm_state *x)
break;
case XFRM_MODE_TUNNEL:
x->props.header_len += sizeof(struct ipv6hdr);
+ break;
default:
goto error;
}
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index b0715432e45..72a659806ca 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -360,6 +360,7 @@ static int esp6_init_state(struct xfrm_state *x)
break;
case XFRM_MODE_TUNNEL:
x->props.header_len += sizeof(struct ipv6hdr);
+ break;
default:
goto error;
}
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 1c2c2765543..d6f1026f194 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -261,7 +261,7 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
struct inet_timewait_sock *tw = NULL;
inet_get_local_port_range(&low, &high);
- remaining = high - low;
+ remaining = (high - low) + 1;
local_bh_disable();
for (i = 1; i <= remaining; i++) {
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index af0cea721d2..80c33f408e3 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -202,7 +202,7 @@ void irlmp_expire_discoveries(hashbin_t *log, __u32 saddr, int force)
/* Drop the spinlock before calling the higher layers, as
* we can't guarantee they won't call us back and create a
* deadlock. We will work on our own private data, so we
- * don't care to be interupted. - Jean II */
+ * don't care to be interrupted. - Jean II */
spin_unlock_irqrestore(&log->hb_spinlock, flags);
if(buffer == NULL)
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index ee3889fa49a..dc5e34a0162 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/iriap_event.c b/net/irda/iriap_event.c
index 99b18dc7a0b..8fb9d7277ca 100644
--- a/net/irda/iriap_event.c
+++ b/net/irda/iriap_event.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index cf302457097..cbcf04380f3 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c
index 87039c2fb6a..fff52d57a20 100644
--- a/net/irda/irlan/irlan_client.c
+++ b/net/irda/irlan/irlan_client.c
@@ -20,7 +20,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_client_event.c b/net/irda/irlan/irlan_client_event.c
index 843ab6fbb39..6afcee59e90 100644
--- a/net/irda/irlan/irlan_client_event.c
+++ b/net/irda/irlan/irlan_client_event.c
@@ -17,7 +17,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index f5778ef3ccc..a4b56e25a91 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -17,7 +17,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c
index 340f04a36b0..7f9c8542e5f 100644
--- a/net/irda/irlan/irlan_eth.c
+++ b/net/irda/irlan/irlan_eth.c
@@ -19,7 +19,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c
index 623e0fd16c1..a9750a80138 100644
--- a/net/irda/irlan/irlan_event.c
+++ b/net/irda/irlan/irlan_event.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_filter.c b/net/irda/irlan/irlan_filter.c
index e6346b88f93..4384be9a688 100644
--- a/net/irda/irlan/irlan_filter.c
+++ b/net/irda/irlan/irlan_filter.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c
index aac66434e47..13db942812e 100644
--- a/net/irda/irlan/irlan_provider.c
+++ b/net/irda/irlan/irlan_provider.c
@@ -20,7 +20,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlan/irlan_provider_event.c b/net/irda/irlan/irlan_provider_event.c
index ef401bd6ea0..10ece5a4752 100644
--- a/net/irda/irlan/irlan_provider_event.c
+++ b/net/irda/irlan/irlan_provider_event.c
@@ -16,7 +16,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlap_event.c b/net/irda/irlap_event.c
index a8b8873aa26..4c33bf5c835 100644
--- a/net/irda/irlap_event.c
+++ b/net/irda/irlap_event.c
@@ -19,7 +19,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c
index 77ac27e8116..4f3764546b2 100644
--- a/net/irda/irlap_frame.c
+++ b/net/irda/irlap_frame.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index 7db92ced2c0..cedff8068fb 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlmp_event.c b/net/irda/irlmp_event.c
index 65ffa981510..1bba87e7860 100644
--- a/net/irda/irlmp_event.c
+++ b/net/irda/irlmp_event.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c
index 559302d3fe6..0a79d9aeb08 100644
--- a/net/irda/irlmp_frame.c
+++ b/net/irda/irlmp_frame.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irmod.c b/net/irda/irmod.c
index 8ba703da279..01554b996b9 100644
--- a/net/irda/irmod.c
+++ b/net/irda/irmod.c
@@ -17,7 +17,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
index d058b467f9e..40c28efaed9 100644
--- a/net/irda/irqueue.c
+++ b/net/irda/irqueue.c
@@ -28,7 +28,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irsysctl.c b/net/irda/irsysctl.c
index 525343a1c52..565cbf0421c 100644
--- a/net/irda/irsysctl.c
+++ b/net/irda/irsysctl.c
@@ -17,7 +17,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 1311976c9df..97db158c927 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/timer.c b/net/irda/timer.c
index d3a6ee8cc4a..d730099080a 100644
--- a/net/irda/timer.c
+++ b/net/irda/timer.c
@@ -18,7 +18,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/irda/wrapper.c b/net/irda/wrapper.c
index a7a7f191f1a..e71286768a4 100644
--- a/net/irda/wrapper.c
+++ b/net/irda/wrapper.c
@@ -20,7 +20,7 @@
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * Neither Dag Brattli nor University of Troms admit liability nor
+ * Neither Dag Brattli nor University of Tromsø admit liability nor
* provide warranty for any of this software. This material is
* provided "AS-IS" and at no charge.
*
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 983058d432d..a2f5a6ea389 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -389,7 +389,7 @@ static void iucv_block_cpu(void *data)
* iucv_declare_cpu
* @data: unused
*
- * Declare a interupt buffer on this cpu.
+ * Declare a interrupt buffer on this cpu.
*/
static void iucv_declare_cpu(void *data)
{
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 49eacba824d..46cf962f7f8 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -762,7 +762,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
if (net_ratelimit())
printk(KERN_DEBUG "LLC(%s:%d): Application "
"bug, race in MSG_PEEK.\n",
- current->comm, current->pid);
+ current->comm, task_pid_nr(current));
peek_seq = llc->copied_seq;
}
continue;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d34a9deca67..4b4ed2a5803 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -37,8 +37,6 @@
struct ieee80211_local;
-#define BIT(x) (1 << (x))
-
#define IEEE80211_ALIGN32_PAD(a) ((4 - ((a) & 3)) & 3)
/* Maximum number of broadcast/multicast frames to buffer when some of the
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index db81aef6177..f7ffeec3913 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -108,14 +108,11 @@ struct ieee802_11_elems {
u8 wmm_param_len;
};
-enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 };
-
-static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
- struct ieee802_11_elems *elems)
+static void ieee802_11_parse_elems(u8 *start, size_t len,
+ struct ieee802_11_elems *elems)
{
size_t left = len;
u8 *pos = start;
- int unknown = 0;
memset(elems, 0, sizeof(*elems));
@@ -126,15 +123,8 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
elen = *pos++;
left -= 2;
- if (elen > left) {
-#if 0
- if (net_ratelimit())
- printk(KERN_DEBUG "IEEE 802.11 element parse "
- "failed (id=%d elen=%d left=%d)\n",
- id, elen, left);
-#endif
- return ParseFailed;
- }
+ if (elen > left)
+ return;
switch (id) {
case WLAN_EID_SSID:
@@ -201,28 +191,15 @@ static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
elems->ext_supp_rates_len = elen;
break;
default:
-#if 0
- printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
- "unknown element (id=%d elen=%d)\n",
- id, elen);
-#endif
- unknown++;
break;
}
left -= elen;
pos += elen;
}
-
- /* Do not trigger error if left == 1 as Apple Airport base stations
- * send AssocResps that are one spurious byte too long. */
-
- return unknown ? ParseUnknown : ParseOK;
}
-
-
static int ecw2cw(int ecw)
{
int cw = 1;
@@ -931,12 +908,7 @@ static void ieee80211_auth_challenge(struct net_device *dev,
printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
pos = mgmt->u.auth.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
- == ParseFailed) {
- printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
- dev->name);
- return;
- }
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
if (!elems.challenge) {
printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
"frame\n", dev->name);
@@ -1230,12 +1202,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
aid &= ~(BIT(15) | BIT(14));
pos = mgmt->u.assoc_resp.variable;
- if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
- == ParseFailed) {
- printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
- dev->name);
- return;
- }
+ ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
if (!elems.supp_rates) {
printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
@@ -1459,7 +1426,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee802_11_elems elems;
size_t baselen;
- int channel, invalid = 0, clen;
+ int channel, clen;
struct ieee80211_sta_bss *bss;
struct sta_info *sta;
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1505,9 +1472,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
#endif /* CONFIG_MAC80211_IBSS_DEBUG */
}
- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
- &elems) == ParseFailed)
- invalid = 1;
+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
@@ -1724,9 +1689,7 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
if (baselen > len)
return;
- if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
- &elems) == ParseFailed)
- return;
+ ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
if (elems.erp_info && elems.erp_info_len >= 1)
ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 6675261e958..cc806d640f7 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -138,9 +138,7 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
*icv = cpu_to_le32(~crc32_le(~0, data, data_len));
crypto_blkcipher_setkey(tfm, rc4key, klen);
- sg.page = virt_to_page(data);
- sg.offset = offset_in_page(data);
- sg.length = data_len + WEP_ICV_LEN;
+ sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
}
@@ -204,9 +202,7 @@ int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
__le32 crc;
crypto_blkcipher_setkey(tfm, rc4key, klen);
- sg.page = virt_to_page(data);
- sg.offset = offset_in_page(data);
- sg.length = data_len + WEP_ICV_LEN;
+ sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
crc = cpu_to_le32(~crc32_le(~0, data, data_len));
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 8cc324b159e..856793e8db7 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -23,7 +23,7 @@
#include <linux/ip.h>
#include <net/checksum.h>
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
MODULE_DESCRIPTION("IP tables CONNMARK matching module");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_CONNMARK");
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index af79423bc8e..9ec50139b9a 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -2,13 +2,13 @@
* GPL (C) 2002 Martin Devera (devik@cdi.cz).
*/
#include <linux/module.h>
+#include <linux/bitops.h>
#include <linux/skbuff.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_connbytes.h>
#include <net/netfilter/nf_conntrack.h>
#include <asm/div64.h>
-#include <asm/bitops.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 1071fc54d6d..9f67920af41 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -25,7 +25,7 @@
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_connmark.h>
-MODULE_AUTHOR("Henrik Nordstrom <hno@marasytems.com>");
+MODULE_AUTHOR("Henrik Nordstrom <hno@marasystems.com>");
MODULE_DESCRIPTION("IP tables connmark match module");
MODULE_LICENSE("GPL");
MODULE_ALIAS("ipt_connmark");
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index 4fcca797150..f263a77e57b 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -1,5 +1,5 @@
-/* (C) 1999 Jrme de Vivie <devivie@info.enserb.u-bordeaux.fr>
- * (C) 1999 Herv Eychenne <eychenne@info.enserb.u-bordeaux.fr>
+/* (C) 1999 Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
+ * (C) 1999 Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index e11000a8e95..d0936506b73 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1623,11 +1623,6 @@ static struct vm_operations_struct packet_mmap_ops = {
.close =packet_mm_close,
};
-static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order)
-{
- return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1);
-}
-
static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len)
{
int i;
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index eaabf087c59..d1e9d68f8ba 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -146,18 +146,18 @@ static void rfkill_disconnect(struct input_handle *handle)
static const struct input_device_id rfkill_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
- .evbit = { BIT(EV_KEY) },
- .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) },
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
- .evbit = { BIT(EV_KEY) },
- .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) },
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
},
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
- .evbit = { BIT(EV_KEY) },
- .keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) },
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
},
{ }
};
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 92435a882fa..9c15c4888d1 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -2,9 +2,7 @@
# Traffic control configuration.
#
-menu "QoS and/or fair queueing"
-
-config NET_SCHED
+menuconfig NET_SCHED
bool "QoS and/or fair queueing"
select NET_SCH_FIFO
---help---
@@ -41,9 +39,6 @@ config NET_SCHED
The available schedulers are listed in the following questions; you
can say Y to as many as you like. If unsure, say N now.
-config NET_SCH_FIFO
- bool
-
if NET_SCHED
comment "Queueing/Scheduling"
@@ -500,4 +495,5 @@ config NET_CLS_IND
endif # NET_SCHED
-endmenu
+config NET_SCH_FIFO
+ bool
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index e9989610712..ceda8890ab0 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -55,7 +55,7 @@
* ppp0..9.
*
* NOTE: Certain meta values depend on other subsystems and are
- * only available if that subsytem is enabled in the kernel.
+ * only available if that subsystem is enabled in the kernel.
*/
#include <linux/module.h>
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index e01d57692c9..fa1a6f45dc4 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -556,6 +556,7 @@ void dev_deactivate(struct net_device *dev)
{
struct Qdisc *qdisc;
struct sk_buff *skb;
+ int running;
spin_lock_bh(&dev->queue_lock);
qdisc = dev->qdisc;
@@ -571,12 +572,31 @@ void dev_deactivate(struct net_device *dev)
dev_watchdog_down(dev);
- /* Wait for outstanding dev_queue_xmit calls. */
+ /* Wait for outstanding qdisc-less dev_queue_xmit calls. */
synchronize_rcu();
/* Wait for outstanding qdisc_run calls. */
- while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
- yield();
+ do {
+ while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state))
+ yield();
+
+ /*
+ * Double-check inside queue lock to ensure that all effects
+ * of the queue run are visible when we return.
+ */
+ spin_lock_bh(&dev->queue_lock);
+ running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state);
+ spin_unlock_bh(&dev->queue_lock);
+
+ /*
+ * The running flag should never be set at this point because
+ * we've already set dev->qdisc to noop_qdisc *inside* the same
+ * pair of spin locks. That is, if any qdisc_run starts after
+ * our initial test it should see the noop_qdisc and then
+ * clear the RUNNING bit before dropping the queue lock. So
+ * if it is set here then we've found a bug.
+ */
+ } while (WARN_ON_ONCE(running));
}
void dev_init_scheduler(struct net_device *dev)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index be57cf317a7..421281d9dd1 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -266,7 +266,7 @@ static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
int busy;
int nores;
int len = skb->len;
- int subq = skb->queue_mapping;
+ int subq = skb_get_queue_mapping(skb);
struct sk_buff *skb_res = NULL;
start = master->slaves;
@@ -284,7 +284,7 @@ restart:
if (slave->qdisc_sleeping != q)
continue;
if (netif_queue_stopped(slave) ||
- netif_subqueue_stopped(slave, subq) ||
+ __netif_subqueue_stopped(slave, subq) ||
!netif_running(slave)) {
busy = 1;
continue;
@@ -294,7 +294,7 @@ restart:
case 0:
if (netif_tx_trylock(slave)) {
if (!netif_queue_stopped(slave) &&
- !netif_subqueue_stopped(slave, subq) &&
+ !__netif_subqueue_stopped(slave, subq) &&
slave->hard_start_xmit(skb, slave) == 0) {
netif_tx_unlock(slave);
master->slaves = NEXT_SLAVE(q);
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 78181072471..cbd64b216cc 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -726,7 +726,8 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
/* set up scatter list */
end = skb_tail_pointer(skb);
- sg.page = virt_to_page(auth);
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, virt_to_page(auth));
sg.offset = (unsigned long)(auth) % PAGE_SIZE;
sg.length = end - (unsigned char *)auth;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f983a369d4e..d5a9785a158 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1513,7 +1513,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
struct hash_desc desc;
/* Sign the message. */
- sg.page = virt_to_page(&cookie->c);
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, virt_to_page(&cookie->c));
sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
sg.length = bodysize;
keylen = SCTP_SECRET_SIZE;
@@ -1585,7 +1586,8 @@ struct sctp_association *sctp_unpack_cookie(
/* Check the signature. */
keylen = SCTP_SECRET_SIZE;
- sg.page = virt_to_page(bear_cookie);
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, virt_to_page(bear_cookie));
sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
sg.length = bodysize;
key = (char *)ep->secret_key[ep->current_key];
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index bfb6a29633d..32be431affc 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -197,9 +197,9 @@ encryptor(struct scatterlist *sg, void *data)
int i = (page_pos + outbuf->page_base) >> PAGE_CACHE_SHIFT;
in_page = desc->pages[i];
} else {
- in_page = sg->page;
+ in_page = sg_page(sg);
}
- desc->infrags[desc->fragno].page = in_page;
+ sg_set_page(&desc->infrags[desc->fragno], in_page);
desc->fragno++;
desc->fraglen += sg->length;
desc->pos += sg->length;
@@ -215,11 +215,11 @@ encryptor(struct scatterlist *sg, void *data)
if (ret)
return ret;
if (fraglen) {
- desc->outfrags[0].page = sg->page;
+ sg_set_page(&desc->outfrags[0], sg_page(sg));
desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
desc->outfrags[0].length = fraglen;
desc->infrags[0] = desc->outfrags[0];
- desc->infrags[0].page = in_page;
+ sg_set_page(&desc->infrags[0], in_page);
desc->fragno = 1;
desc->fraglen = fraglen;
} else {
@@ -287,7 +287,7 @@ decryptor(struct scatterlist *sg, void *data)
if (ret)
return ret;
if (fraglen) {
- desc->frags[0].page = sg->page;
+ sg_set_page(&desc->frags[0], sg_page(sg));
desc->frags[0].offset = sg->offset + sg->length - fraglen;
desc->frags[0].length = fraglen;
desc->fragno = 1;
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index 3c773c53e12..c98873f39ae 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -847,7 +847,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
task->tk_start = jiffies;
dprintk("RPC: new task initialized, procpid %u\n",
- current->pid);
+ task_pid_nr(current));
}
static struct rpc_task *
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 6a59180e166..3d1f7cdf9dd 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -1059,7 +1059,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
do {
if (thislen > page_len)
thislen = page_len;
- sg->page = buf->pages[i];
+ sg_set_page(sg, buf->pages[i]);
sg->offset = page_offset;
sg->length = thislen;
ret = actor(sg, data);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 6996cba5aa9..9163ec526c2 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -483,7 +483,7 @@ static int unix_listen(struct socket *sock, int backlog)
sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN;
/* set credentials so connect can copy them */
- sk->sk_peercred.pid = current->tgid;
+ sk->sk_peercred.pid = task_tgid_vnr(current);
sk->sk_peercred.uid = current->euid;
sk->sk_peercred.gid = current->egid;
err = 0;
@@ -1133,7 +1133,7 @@ restart:
unix_peer(newsk) = sk;
newsk->sk_state = TCP_ESTABLISHED;
newsk->sk_type = sk->sk_type;
- newsk->sk_peercred.pid = current->tgid;
+ newsk->sk_peercred.pid = task_tgid_vnr(current);
newsk->sk_peercred.uid = current->euid;
newsk->sk_peercred.gid = current->egid;
newu = unix_sk(newsk);
@@ -1194,7 +1194,7 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb)
sock_hold(skb);
unix_peer(ska)=skb;
unix_peer(skb)=ska;
- ska->sk_peercred.pid = skb->sk_peercred.pid = current->tgid;
+ ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current);
ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid;
ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid;
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5ced62c19c6..fb2220a719b 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -552,7 +552,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
if (copy > len)
copy = len;
- sg.page = virt_to_page(skb->data + offset);
+ sg_set_page(&sg, virt_to_page(skb->data + offset));
sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
sg.length = copy;
@@ -577,7 +577,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
if (copy > len)
copy = len;
- sg.page = frag->page;
+ sg_set_page(&sg, frag->page);
sg.offset = frag->page_offset + offset-start;
sg.length = copy;
diff --git a/samples/Kconfig b/samples/Kconfig
new file mode 100644
index 00000000000..57bb2236952
--- /dev/null
+++ b/samples/Kconfig
@@ -0,0 +1,16 @@
+# samples/Kconfig
+
+menuconfig SAMPLES
+ bool "Sample kernel code"
+ help
+ You can build and test sample kernel code here.
+
+if SAMPLES
+
+config SAMPLE_MARKERS
+ tristate "Build markers examples -- loadable modules only"
+ depends on MARKERS && m
+ help
+ This build markers example modules.
+
+endif # SAMPLES
diff --git a/samples/Makefile b/samples/Makefile
new file mode 100644
index 00000000000..5a4f0b6bcbe
--- /dev/null
+++ b/samples/Makefile
@@ -0,0 +1,3 @@
+# Makefile for Linux samples code
+
+obj-$(CONFIG_SAMPLES) += markers/
diff --git a/samples/markers/Makefile b/samples/markers/Makefile
new file mode 100644
index 00000000000..6d7231265f0
--- /dev/null
+++ b/samples/markers/Makefile
@@ -0,0 +1,4 @@
+# builds the kprobes example kernel modules;
+# then to use one (as root): insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o
diff --git a/samples/markers/marker-example.c b/samples/markers/marker-example.c
new file mode 100644
index 00000000000..e787c6d16dd
--- /dev/null
+++ b/samples/markers/marker-example.c
@@ -0,0 +1,54 @@
+/* marker-example.c
+ *
+ * Executes a marker when /proc/marker-example is opened.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+
+struct proc_dir_entry *pentry_example;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+ int i;
+
+ trace_mark(subsystem_event, "%d %s", 123, "example string");
+ for (i = 0; i < 10; i++)
+ trace_mark(subsystem_eventb, MARK_NOARGS);
+ return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+ .open = my_open,
+};
+
+static int example_init(void)
+{
+ printk(KERN_ALERT "example init\n");
+ pentry_example = create_proc_entry("marker-example", 0444, NULL);
+ if (pentry_example)
+ pentry_example->proc_fops = &mark_ops;
+ else
+ return -EPERM;
+ return 0;
+}
+
+static void example_exit(void)
+{
+ printk(KERN_ALERT "example exit\n");
+ remove_proc_entry("marker-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Marker example");
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
new file mode 100644
index 00000000000..238b2e384fc
--- /dev/null
+++ b/samples/markers/probe-example.c
@@ -0,0 +1,98 @@
+/* probe-example.c
+ *
+ * Connects two functions to marker call sites.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/marker.h>
+#include <asm/atomic.h>
+
+struct probe_data {
+ const char *name;
+ const char *format;
+ marker_probe_func *probe_func;
+};
+
+void probe_subsystem_event(const struct marker *mdata, void *private,
+ const char *format, ...)
+{
+ va_list ap;
+ /* Declare args */
+ unsigned int value;
+ const char *mystr;
+
+ /* Assign args */
+ va_start(ap, format);
+ value = va_arg(ap, typeof(value));
+ mystr = va_arg(ap, typeof(mystr));
+
+ /* Call printk */
+ printk(KERN_DEBUG "Value %u, string %s\n", value, mystr);
+
+ /* or count, check rights, serialize data in a buffer */
+
+ va_end(ap);
+}
+
+atomic_t eventb_count = ATOMIC_INIT(0);
+
+void probe_subsystem_eventb(const struct marker *mdata, void *private,
+ const char *format, ...)
+{
+ /* Increment counter */
+ atomic_inc(&eventb_count);
+}
+
+static struct probe_data probe_array[] =
+{
+ { .name = "subsystem_event",
+ .format = "%d %s",
+ .probe_func = probe_subsystem_event },
+ { .name = "subsystem_eventb",
+ .format = MARK_NOARGS,
+ .probe_func = probe_subsystem_eventb },
+};
+
+static int __init probe_init(void)
+{
+ int result;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probe_array); i++) {
+ result = marker_probe_register(probe_array[i].name,
+ probe_array[i].format,
+ probe_array[i].probe_func, &probe_array[i]);
+ if (result)
+ printk(KERN_INFO "Unable to register probe %s\n",
+ probe_array[i].name);
+ result = marker_arm(probe_array[i].name);
+ if (result)
+ printk(KERN_INFO "Unable to arm probe %s\n",
+ probe_array[i].name);
+ }
+ return 0;
+}
+
+static void __exit probe_fini(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(probe_array); i++)
+ marker_probe_unregister(probe_array[i].name);
+ printk(KERN_INFO "Number of event b : %u\n",
+ atomic_read(&eventb_count));
+}
+
+module_init(probe_init);
+module_exit(probe_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("SUBSYSTEM Probe");
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index de7bb284c61..b96ea8d6a5e 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -56,6 +56,17 @@ endef
# gcc support functions
# See documentation in Documentation/kbuild/makefiles.txt
+# cc-cross-prefix
+# Usage: CROSS_COMPILE := $(call cc-cross-prefix, m68k-linux-gnu- m68k-linux-)
+# Return first prefix where a prefix$(CC) is found in PATH.
+# If no $(CC) found in PATH with listed prefixes return nothing
+cc-cross-prefix = \
+ $(word 1, $(foreach c,$(1), \
+ $(shell set -e; \
+ if (which $(strip $(c))$(CC)) > /dev/null 2>&1 ; then \
+ echo $(c); \
+ fi)))
+
# output directory for tests below
TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/)
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index e5c6ac7bde9..0e4bd5459df 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -66,12 +66,15 @@ FILELINE * entity_system;
#define FUNCTION "-function"
#define NOFUNCTION "-nofunction"
+char *srctree;
+
void usage (void)
{
fprintf(stderr, "Usage: docproc {doc|depend} file\n");
fprintf(stderr, "Input is read from file.tmpl. Output is sent to stdout\n");
fprintf(stderr, "doc: frontend when generating kernel documentation\n");
fprintf(stderr, "depend: generate list of files referenced within file\n");
+ fprintf(stderr, "Environment variable SRCTREE: absolute path to kernel source tree.\n");
}
/*
@@ -90,7 +93,7 @@ void exec_kernel_doc(char **svec)
exit(1);
case 0:
memset(real_filename, 0, sizeof(real_filename));
- strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+ strncat(real_filename, srctree, PATH_MAX);
strncat(real_filename, KERNELDOCPATH KERNELDOC,
PATH_MAX - strlen(real_filename));
execvp(real_filename, svec);
@@ -171,7 +174,7 @@ void find_export_symbols(char * filename)
if (filename_exist(filename) == NULL) {
char real_filename[PATH_MAX + 1];
memset(real_filename, 0, sizeof(real_filename));
- strncat(real_filename, getenv("SRCTREE"), PATH_MAX);
+ strncat(real_filename, srctree, PATH_MAX);
strncat(real_filename, filename,
PATH_MAX - strlen(real_filename));
sym = add_new_file(filename);
@@ -338,6 +341,10 @@ void parse_file(FILE *infile)
int main(int argc, char *argv[])
{
FILE * infile;
+
+ srctree = getenv("SRCTREE");
+ if (!srctree)
+ srctree = getcwd(NULL, 0);
if (argc != 3) {
usage();
exit(1);
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl
index b458e2acb4a..d716b76098b 100755
--- a/scripts/checkstack.pl
+++ b/scripts/checkstack.pl
@@ -13,9 +13,10 @@
# Random bits by Matt Mackall <mpm@selenic.com>
# M68k port by Geert Uytterhoeven and Andreas Schwab
# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
+# PARISC port by Kyle McMartin <kyle@parisc-linux.org>
#
# Usage:
-# objdump -d vmlinux | stackcheck.pl [arch]
+# objdump -d vmlinux | scripts/checkstack.pl [arch]
#
# TODO : Port to all architectures (one regex per arch)
@@ -61,6 +62,8 @@ my (@stack, $re, $x, $xs);
} elsif ($arch eq 'mips') {
#88003254: 27bdffe0 addiu sp,sp,-32
$re = qr/.*addiu.*sp,sp,-(([0-9]{2}|[3-9])[0-9]{2})/o;
+ } elsif ($arch eq 'parisc' || $arch eq 'parisc64') {
+ $re = qr/.*ldo ($x{1,8})\(sp\),sp/o;
} elsif ($arch eq 'ppc') {
#c00029f4: 94 21 ff 30 stwu r1,-208(r1)
$re = qr/.*stwu.*r1,-($x{1,8})\(r1\)/o;
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index bb08069b04a..83c5e76414c 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -84,7 +84,7 @@ help:
# lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
-# Use reursively expanded variables so we do not call gcc unless
+# Use recursively expanded variables so we do not call gcc unless
# we really need to do so. (Do not call gcc as part of make mrproper)
HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags)
HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC))
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 7bfa181d6ed..f9d0d91a3fe 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -235,23 +235,16 @@ void menu_finalize(struct menu *parent)
sym = parent->sym;
if (parent->list) {
if (sym && sym_is_choice(sym)) {
- /* find out choice type */
- enum symbol_type type = S_UNKNOWN;
-
+ /* find the first choice value and find out choice type */
for (menu = parent->list; menu; menu = menu->next) {
- if (menu->sym && menu->sym->type != S_UNKNOWN) {
- if (type == S_UNKNOWN)
- type = menu->sym->type;
- if (type != S_BOOLEAN)
- break;
- if (menu->sym->type == S_TRISTATE) {
- type = S_TRISTATE;
- break;
- }
+ if (menu->sym) {
+ current_entry = parent;
+ menu_set_type(menu->sym->type);
+ current_entry = menu;
+ menu_set_type(sym->type);
+ break;
}
}
- current_entry = parent;
- menu_set_type(type);
parentdep = expr_alloc_symbol(sym);
} else if (parent->prompt)
parentdep = parent->prompt->visible.expr;
@@ -260,16 +253,7 @@ void menu_finalize(struct menu *parent)
for (menu = parent->list; menu; menu = menu->next) {
basedep = expr_transform(menu->dep);
- dep = parentdep;
- if (sym && sym_is_choice(sym) && menu->sym) {
- enum symbol_type type = menu->sym->type;
-
- if (type == S_UNKNOWN)
- type = sym->type;
- if (type != S_TRISTATE)
- dep = expr_alloc_comp(E_EQUAL, sym, &symbol_yes);
- }
- basedep = expr_alloc_and(expr_copy(dep), basedep);
+ basedep = expr_alloc_and(expr_copy(parentdep), basedep);
basedep = expr_eliminate_dups(basedep);
menu->dep = basedep;
if (menu->sym)
@@ -342,8 +326,7 @@ void menu_finalize(struct menu *parent)
"values not supported");
}
current_entry = menu;
- if (menu->sym->type == S_UNKNOWN)
- menu_set_type(sym->type);
+ menu_set_type(sym->type);
menu_add_symbol(P_CHOICE, sym, NULL);
prop = sym_get_choice_prop(sym);
for (ep = &prop->expr; *ep; ep = &(*ep)->left.expr)
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index e4eeb59a8c2..b9bb32dfd62 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1274,8 +1274,12 @@ ConfigMainWindow::ConfigMainWindow(void)
QMenuBar* menu;
bool ok;
int x, y, width, height;
+ char title[256];
QWidget *d = configApp->desktop();
+ snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
+ getenv("KERNELVERSION"));
+ setCaption(title);
width = configSettings->readNumEntry("/window width", d->width() - 64);
height = configSettings->readNumEntry("/window height", d->height() - 64);
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2ef9a193fca..93ac52adb49 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -268,6 +268,9 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod,
"was in %s%s\n", mod->name, name,
s->module->name,
is_vmlinux(s->module->name) ?"":".ko");
+ } else {
+ /* In case Modules.symvers was out of date */
+ s->module = mod;
}
}
s->preloaded = 0;
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 6edb29f2b4a..0f657b5f3bc 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -83,6 +83,7 @@ Maintainer: $name
Standards-Version: 3.6.1
Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
Architecture: any
Description: User Mode Linux kernel, version $version
User-mode Linux is a port of the Linux kernel to its own system call
@@ -104,6 +105,7 @@ Maintainer: $name
Standards-Version: 3.6.1
Package: $packagename
+Provides: kernel-image-$version, linux-image-$version
Architecture: any
Description: Linux kernel, version $version
This package contains the Linux kernel, modules and corresponding other
diff --git a/security/commoncap.c b/security/commoncap.c
index 48ca5b09276..bf67871173e 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -23,6 +23,7 @@
#include <linux/xattr.h>
#include <linux/hugetlb.h>
#include <linux/mount.h>
+#include <linux/sched.h>
#ifdef CONFIG_SECURITY_FILE_CAPABILITIES
/*
@@ -189,7 +190,8 @@ int cap_inode_killpriv(struct dentry *dentry)
return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
}
-static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
+static inline int cap_from_disk(struct vfs_cap_data *caps,
+ struct linux_binprm *bprm,
int size)
{
__u32 magic_etc;
@@ -197,7 +199,7 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
if (size != XATTR_CAPS_SZ)
return -EINVAL;
- magic_etc = le32_to_cpu(caps[0]);
+ magic_etc = le32_to_cpu(caps->magic_etc);
switch ((magic_etc & VFS_CAP_REVISION_MASK)) {
case VFS_CAP_REVISION:
@@ -205,8 +207,8 @@ static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
bprm->cap_effective = true;
else
bprm->cap_effective = false;
- bprm->cap_permitted = to_cap_t( le32_to_cpu(caps[1]) );
- bprm->cap_inheritable = to_cap_t( le32_to_cpu(caps[2]) );
+ bprm->cap_permitted = to_cap_t(le32_to_cpu(caps->permitted));
+ bprm->cap_inheritable = to_cap_t(le32_to_cpu(caps->inheritable));
return 0;
default:
return -EINVAL;
@@ -218,7 +220,7 @@ static int get_file_caps(struct linux_binprm *bprm)
{
struct dentry *dentry;
int rc = 0;
- __le32 v1caps[XATTR_CAPS_SZ];
+ struct vfs_cap_data incaps;
struct inode *inode;
if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
@@ -231,8 +233,14 @@ static int get_file_caps(struct linux_binprm *bprm)
if (!inode->i_op || !inode->i_op->getxattr)
goto out;
- rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps,
- XATTR_CAPS_SZ);
+ rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, NULL, 0);
+ if (rc > 0) {
+ if (rc == XATTR_CAPS_SZ)
+ rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS,
+ &incaps, XATTR_CAPS_SZ);
+ else
+ rc = -EINVAL;
+ }
if (rc == -ENODATA || rc == -EOPNOTSUPP) {
/* no data, that's ok */
rc = 0;
@@ -241,7 +249,7 @@ static int get_file_caps(struct linux_binprm *bprm)
if (rc < 0)
goto out;
- rc = cap_from_disk(v1caps, bprm, rc);
+ rc = cap_from_disk(&incaps, bprm, rc);
if (rc)
printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
__FUNCTION__, rc, bprm->filename);
@@ -334,7 +342,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe)
/* For init, we want to retain the capabilities set
* in the init_task struct. Thus we skip the usual
* capability rules */
- if (!is_init(current)) {
+ if (!is_global_init(current)) {
current->cap_permitted = new_permitted;
current->cap_effective = bprm->cap_effective ?
new_permitted : 0;
diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c
index d7c4fb86b9e..17b3e6f13ca 100644
--- a/sound/core/seq/seq_midi_emul.c
+++ b/sound/core/seq/seq_midi_emul.c
@@ -71,7 +71,7 @@ static void reset_all_channels(struct snd_midi_channel_set *chset);
* such as GM, GS and XG.
* There modes that this module will run in are:
* Generic MIDI - no interpretation at all, it will just save current values
- * of controlers etc.
+ * of controllers etc.
* GM - You can use all gm_ prefixed elements of chan. Controls, RPN, NRPN,
* SysEx will be interpreded as defined in General Midi.
* GS - You can use all gs_ prefixed elements of chan. Codes for GS will be
@@ -176,7 +176,7 @@ snd_midi_process_event(struct snd_midi_op *ops,
ev->data.control.value);
break;
case SNDRV_SEQ_EVENT_NONREGPARAM:
- /* Break it back into its controler values */
+ /* Break it back into its controller values */
chan->param_type = SNDRV_MIDI_PARAM_TYPE_NONREGISTERED;
chan->control[MIDI_CTL_MSB_DATA_ENTRY]
= (ev->data.control.value >> 7) & 0x7f;
@@ -189,7 +189,7 @@ snd_midi_process_event(struct snd_midi_op *ops,
nrpn(ops, drv, chan, chanset);
break;
case SNDRV_SEQ_EVENT_REGPARAM:
- /* Break it back into its controler values */
+ /* Break it back into its controller values */
chan->param_type = SNDRV_MIDI_PARAM_TYPE_REGISTERED;
chan->control[MIDI_CTL_MSB_DATA_ENTRY]
= (ev->data.control.value >> 7) & 0x7f;
@@ -267,7 +267,7 @@ note_off(struct snd_midi_op *ops, void *drv, struct snd_midi_channel *chan,
}
/*
- * Do all driver independent operations for this controler and pass
+ * Do all driver independent operations for this controller and pass
* events that need to take place immediately to the driver.
*/
static void
diff --git a/sound/drivers/opl3/opl3_midi.c b/sound/drivers/opl3/opl3_midi.c
index 1b6f227af37..3557b6e20eb 100644
--- a/sound/drivers/opl3/opl3_midi.c
+++ b/sound/drivers/opl3/opl3_midi.c
@@ -808,7 +808,7 @@ static void snd_opl3_pitch_ctrl(struct snd_opl3 *opl3, struct snd_midi_channel *
}
/*
- * Deal with a controler type event. This includes all types of
+ * Deal with a controller type event. This includes all types of
* control events, not just the midi controllers
*/
void snd_opl3_control(void *p, int type, struct snd_midi_channel *chan)
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index fe31bb5cffb..37c47fb95ac 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -189,7 +189,6 @@ void snd_tea575x_init(struct snd_tea575x *tea)
tea->vd.owner = tea->card->module;
strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
tea->vd.type = VID_TYPE_TUNER;
- tea->vd.hardware = VID_HARDWARE_RTRACK; /* FIXME: assign new number */
tea->vd.release = snd_tea575x_release;
video_set_drvdata(&tea->vd, tea);
tea->vd.fops = &tea->fops;
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 4a7367a8ff9..c1af28fd4a1 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -623,7 +623,7 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
(snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
(snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
- /* Set DMA controler */
+ /* Set DMA controller */
snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_READ | DMA_AUTOINIT);
return 0;
@@ -689,7 +689,7 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
(snd_pcm_format_width(runtime->format) == 16 ? 0x04 : 0x00) |
(snd_pcm_format_unsigned(runtime->format) ? 0x00 : 0x20));
- /* Set DMA controler */
+ /* Set DMA controller */
snd_dma_program(chip->dma1, runtime->dma_addr, size, DMA_MODE_WRITE | DMA_AUTOINIT);
return 0;
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 8a61a119186..24460a558bf 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -498,8 +498,8 @@ snd_au1000_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
int i;
spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++)
if (!(au1000->ac97_ioport->status & AC97C_CP))
break;
@@ -535,8 +535,8 @@ snd_au1000_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short
int i;
spin_lock(&au1000->ac97_lock);
-/* would rather use the interupt than this polling but it works and I can't
-get the interupt driven case to work efficiently */
+/* would rather use the interrupt than this polling but it works and I can't
+get the interrupt driven case to work efficiently */
for (i = 0; i < 0x5000; i++)
if (!(au1000->ac97_ioport->status & AC97C_CP))
break;
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index f70286a7364..26819e2f576 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -191,7 +191,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
/* Init audio core.
* This must be done before we do request_irq otherwise we can get spurious
- * interupts that we do not handle properly and make a mess of things */
+ * interrupts that we do not handle properly and make a mess of things */
if ((err = vortex_core_init(chip)) != 0) {
printk(KERN_ERR "hw core init failed\n");
goto core_out;
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index a1aa89f2faf..566b5ab9d4e 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -236,8 +236,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip)
input_dev->id.product = 0x0001;
input_dev->id.version = 0x0100;
- input_dev->evbit[0] = BIT(EV_SND);
- input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+ input_dev->evbit[0] = BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
input_dev->event = snd_pmac_beep_event;
input_dev->dev.parent = &chip->pdev->dev;
input_set_drvdata(input_dev, chip);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 91651bdfa76..e6a67b58f29 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -264,7 +264,7 @@ out:
}
/*
- * Power down the audio subsytem pmdown_time msecs after close is called.
+ * Power down the audio subsystem pmdown_time msecs after close is called.
* This is to ensure there are no pops or clicks in between any music tracks
* due to DAPM power cycling.
*/
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index b3193e687db..29a546fecac 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -24,7 +24,7 @@
* o Automatic Mic Bias support
* o Jack insertion power event initiation - e.g. hp insertion will enable
* sinks, dacs, etc
- * o Delayed powerdown of audio susbsytem to reduce pops between a quick
+ * o Delayed powerdown of audio susbsystem to reduce pops between a quick
* device reopen.
*
* Todo:
diff --git a/sound/synth/emux/emux_synth.c b/sound/synth/emux/emux_synth.c
index 3733118d39b..478369bb38c 100644
--- a/sound/synth/emux/emux_synth.c
+++ b/sound/synth/emux/emux_synth.c
@@ -317,7 +317,7 @@ snd_emux_update_port(struct snd_emux_port *port, int update)
/*
- * Deal with a controler type event. This includes all types of
+ * Deal with a controller type event. This includes all types of
* control events, not just the midi controllers
*/
void
diff --git a/sound/usb/caiaq/caiaq-input.c b/sound/usb/caiaq/caiaq-input.c
index a1de0c60895..cd536ca20e5 100644
--- a/sound/usb/caiaq/caiaq-input.c
+++ b/sound/usb/caiaq/caiaq-input.c
@@ -200,8 +200,9 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
switch (dev->chip.usb_id) {
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
- input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_Z);
input->keycode = keycode_rk2;
input->keycodesize = sizeof(char);
input->keycodemax = ARRAY_SIZE(keycode_rk2);
@@ -228,8 +229,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
break;
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
- input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input->absbit[0] = BIT(ABS_X);
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->absbit[0] = BIT_MASK(ABS_X);
input->keycode = keycode_ak1;
input->keycodesize = sizeof(char);
input->keycodemax = ARRAY_SIZE(keycode_ak1);